Files
travelplanning/main.ts
T
2026-06-13 16:06:24 +07:00

100 lines
2.7 KiB
TypeScript

import { NestFactory } from '@nestjs/core';
import { Module, Controller, Get, Post, Body, Param, ParseIntPipe, NotFoundException, BadRequestException } from '@nestjs/common';
import { PrismaService } from './prisma.service';
import 'dotenv/config';
import * as bcrypt from 'bcrypt';
@Controller()
class AppController {
@Get()
getHello(): string {
return 'Travel Planning API is running!';
}
}
@Controller('v1/auth')
class AuthController {
constructor(private prisma: PrismaService) {}
@Post('signup')
async signup(@Body() body: any) {
const { email, password, name } = body;
// 1. Kiểm tra email tồn tại
const existingUser = await this.prisma.user.findUnique({ where: { email } });
if (existingUser) throw new BadRequestException('Email đã được sử dụng');
// 2. Logic "First User is Admin"
const userCount = await this.prisma.user.count();
const shouldBeAdmin = userCount === 0;
// 3. Hash mật khẩu
const passwordHash = await bcrypt.hash(password, 10);
return this.prisma.user.create({
data: { email, passwordHash, name, isAdmin: shouldBeAdmin },
select: { id: true, email: true, name: true, isAdmin: true }
});
}
}
@Controller('v1/tours')
class TourController {
constructor(private prisma: PrismaService) {}
@Get('explore')
async getPublicTours() {
// Lấy các tour có ít nhất 1 ảnh và thông tin vị trí từ chặng đầu tiên
return this.prisma.tour.findMany({
take: 20,
include: {
photos: { take: 1 },
legs: {
take: 1,
include: {
places: { take: 1 }
}
}
}
});
}
@Get(':id')
async getTourDetails(@Param('id', ParseIntPipe) id: number) {
const tour = await this.prisma.tour.findUnique({
where: { id },
include: {
members: true,
photos: true,
legs: {
orderBy: { sequenceNumber: 'asc' },
include: {
places: { orderBy: { sequenceInLeg: 'asc' } },
expenses: true,
},
},
},
});
if (!tour) throw new NotFoundException(`Không tìm thấy Tour với ID ${id}`);
return tour;
}
}
@Module({
controllers: [AppController, AuthController, TourController],
providers: [PrismaService],
exports: [PrismaService]
})
class AppModule {}
async function bootstrap() {
const app = await NestFactory.create(AppModule);
app.enableCors(); // Cho phép Frontend gọi API
app.setGlobalPrefix('api'); // Tất cả API sẽ bắt đầu bằng /api/...
const port = process.env.PORT || 3001;
await app.listen(port);
console.log(`🚀 Server is running on: http://localhost:${port}`);
}
bootstrap();