feat: add booking input validation
This commit is contained in:
34
apps/api/src/booking.dto.ts
Normal file
34
apps/api/src/booking.dto.ts
Normal 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[] =
|
||||
[];
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user