feat: add booking input validation

This commit is contained in:
2026-09-18 16:29:54 +08:00
parent 1e03d055aa
commit ae5f26baab
3 changed files with 47 additions and 5 deletions

View File

@@ -0,0 +1,34 @@
import { Type } from "class-transformer";
import {
IsArray,
IsIn,
IsInt,
IsISO8601,
IsOptional,
IsString,
Max,
Min,
ValidateNested,
} from "class-validator";
export class BookingItemDto {
@IsString() serviceId!: string;
@IsInt() @Min(1) @Max(50) quantity!: number;
}
export class CreateBookingDto {
@IsIn(["package", "private_chef"]) requestType!: "package" | "private_chef";
@IsString() customerName!: string;
@IsOptional() @IsString() phone?: string;
@IsOptional() @IsString() wechatId?: string;
@IsIn(["wechat", "phone", "none"]) contactPreference!: "wechat" | "phone" | "none";
@IsOptional() @IsIn(["pickup", "delivery"]) fulfillmentType?: "pickup" | "delivery";
@IsOptional() @IsString() serviceId?: string;
@IsOptional() @IsISO8601() requestedDate?: string;
@IsOptional() @IsString() requestedTime?: string;
@IsOptional() @IsString() deliveryAddress?: string;
@IsOptional() @IsString() note?: string;
@IsOptional() extraData?: Record<string, unknown>;
@IsArray() @ValidateNested({ each: true }) @Type(() => BookingItemDto) items: BookingItemDto[] =
[];
}

View File

@@ -1,9 +1,9 @@
import { BadRequestException, Injectable, NotFoundException } from "@nestjs/common";
import { BookingRequestType, Prisma } from "@prisma/client";
import { Prisma } from "@prisma/client";
import { PrismaService } from "./prisma.service.js";
export interface CreateBookingInput {
requestType: BookingRequestType;
requestType: "package" | "private_chef";
customerName: string;
phone?: string;
wechatId?: string;

View File

@@ -8,14 +8,16 @@ import {
Param,
Post,
Req,
ValidationPipe,
} from "@nestjs/common";
import { NestFactory } from "@nestjs/core";
import { Prisma } from "@prisma/client";
import { FastifyAdapter } from "@nestjs/platform-fastify";
import type { NestFastifyApplication } from "@nestjs/platform-fastify";
import { PrismaService } from "./prisma.service.js";
import { WechatAuthService } from "./wechat-auth.js";
import { BookingService } from "./booking.service.js";
import type { CreateBookingInput } from "./booking.service.js";
import { CreateBookingDto } from "./booking.dto.js";
import type { FastifyRequest } from "fastify";
import { createHmac } from "node:crypto";
@@ -115,13 +117,16 @@ export class CustomerBookingController {
) {}
@Post()
async create(@Req() request: FastifyRequest, @Body() body: CreateBookingInput): Promise<unknown> {
async create(@Req() request: FastifyRequest, @Body() body: CreateBookingDto): Promise<unknown> {
const identity = this.identity(request);
const customer = await this.prisma.customerUser.findUnique({
where: { brandId_openid: identity },
});
if (!customer) throw new BadRequestException("请先完成微信登录");
return this.bookings.create(identity.brandId, customer.id, body);
return this.bookings.create(identity.brandId, customer.id, {
...body,
extraData: body.extraData as Prisma.InputJsonObject,
});
}
@Get()
@@ -198,6 +203,9 @@ export class AppModule {}
export async function createApp(): Promise<NestFastifyApplication> {
const app = await NestFactory.create<NestFastifyApplication>(AppModule, new FastifyAdapter());
app.useGlobalPipes(
new ValidationPipe({ whitelist: true, forbidNonWhitelisted: true, transform: true }),
);
app.enableCors();
return app;
}