main create
This commit is contained in:
@@ -0,0 +1,100 @@
|
||||
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();
|
||||
Reference in New Issue
Block a user