import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger'; import { Type } from 'class-transformer'; import { ArrayMaxSize, ArrayMinSize, IsArray, IsNotEmpty, IsNumber, IsObject, IsOptional, IsString, Max, Min, ValidateNested, } from 'class-validator'; /** * 清单条目(api-contract-v1 §5)。 * 阶段0 决策#1:一条前端 DesignItem = 一条后端 DesignList,items 固定 1 个元素; * 决策#3:productIcon 不入库,由客户端按 productId 推导。 */ export class DesignListEntryDto { @ApiProperty() @IsString() @IsNotEmpty() productId!: string; @ApiProperty() @IsString() @IsNotEmpty() productName!: string; @ApiProperty() @IsNumber() @Min(0) unitPrice!: number; @ApiProperty() @IsNumber() @Min(1) @Max(999) count!: number; /** 结构白名单与大小校验在 service 层做(设计数据契约 v1) */ @ApiPropertyOptional() @IsOptional() @IsObject() designData?: Record; } export class CreateDesignListDto { @ApiProperty({ description: '清单标题;前端传 productName(阶段0 决策#4)' }) @IsString() @IsNotEmpty() title!: string; @ApiProperty({ type: [DesignListEntryDto] }) @IsArray() @ArrayMinSize(1) @ArrayMaxSize(1) @ValidateNested({ each: true }) @Type(() => DesignListEntryDto) items!: DesignListEntryDto[]; }