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();