forked from Yara724/api
209 lines
5.3 KiB
TypeScript
209 lines
5.3 KiB
TypeScript
import { ApiProperty, ApiPropertyOptional } from "@nestjs/swagger";
|
|
import {
|
|
IsArray,
|
|
IsEnum,
|
|
IsNotEmpty,
|
|
ArrayMinSize,
|
|
ArrayUnique,
|
|
IsOptional,
|
|
IsInt,
|
|
} from "class-validator";
|
|
import {
|
|
ClaimVehicleTypeV2,
|
|
OuterPartSideV2,
|
|
} from "src/static/outer-car-parts-catalog";
|
|
import { DamageSelectedPartV2BodyDto } from "./damage-selected-part-v2.dto";
|
|
|
|
/**
|
|
* Enum for valid outer car parts that can be damaged
|
|
* Follows the naming convention from workflow step definition
|
|
*/
|
|
export enum OuterCarPart {
|
|
// Hood
|
|
HOOD = "hood",
|
|
|
|
// Doors
|
|
FRONT_RIGHT_DOOR = "front_right_door",
|
|
FRONT_LEFT_DOOR = "front_left_door",
|
|
REAR_RIGHT_DOOR = "rear_right_door",
|
|
REAR_LEFT_DOOR = "rear_left_door",
|
|
|
|
// Bumpers
|
|
FRONT_BUMPER = "front_bumper",
|
|
REAR_BUMPER = "rear_bumper",
|
|
|
|
// Fenders
|
|
FRONT_RIGHT_FENDER = "front_right_fender",
|
|
FRONT_LEFT_FENDER = "front_left_fender",
|
|
REAR_RIGHT_FENDER = "rear_right_fender",
|
|
REAR_LEFT_FENDER = "rear_left_fender",
|
|
|
|
// Trunk & Roof
|
|
TRUNK = "trunk",
|
|
ROOF = "roof",
|
|
}
|
|
|
|
/**
|
|
* V2 DTO for selecting damaged outer car parts
|
|
* Much cleaner than the nested boolean structure
|
|
*/
|
|
export class SelectOuterPartsV2Dto {
|
|
@ApiProperty({
|
|
description: "Array of selected damaged outer car parts",
|
|
example: ["hood", "front_right_door", "rear_bumper", "roof"],
|
|
enum: OuterCarPart,
|
|
isArray: true,
|
|
minItems: 1,
|
|
maxItems: 13,
|
|
})
|
|
@IsOptional()
|
|
@IsArray({ message: "selectedParts must be an array" })
|
|
@ArrayMinSize(1, { message: "At least one damaged part must be selected" })
|
|
@ArrayUnique({ message: "Duplicate parts are not allowed" })
|
|
@IsEnum(OuterCarPart, {
|
|
each: true,
|
|
message: "Invalid part name. Must be one of the valid outer car parts",
|
|
})
|
|
selectedParts?: OuterCarPart[];
|
|
|
|
@ApiProperty({
|
|
description: "Selected outer part IDs from catalog",
|
|
example: [9, 10, 4],
|
|
type: [Number],
|
|
required: false,
|
|
})
|
|
@IsOptional()
|
|
@IsArray({ message: "selectedPartIds must be an array" })
|
|
@ArrayMinSize(1, { message: "At least one part ID must be selected" })
|
|
@ArrayUnique({ message: "Duplicate part IDs are not allowed" })
|
|
@IsInt({ each: true, message: "Each selected part ID must be an integer" })
|
|
selectedPartIds?: number[];
|
|
|
|
@ApiProperty({
|
|
description: "Vehicle type for validating available outer parts",
|
|
enum: ClaimVehicleTypeV2,
|
|
required: true,
|
|
})
|
|
@IsNotEmpty()
|
|
@IsEnum(ClaimVehicleTypeV2)
|
|
carType?: ClaimVehicleTypeV2;
|
|
}
|
|
|
|
/**
|
|
* Response DTO for select outer parts V2
|
|
*/
|
|
export class SelectOuterPartsV2ResponseDto {
|
|
@ApiProperty({
|
|
description: "Claim request ID",
|
|
example: "507f1f77bcf86cd799439011",
|
|
})
|
|
claimRequestId: string;
|
|
|
|
@ApiProperty({
|
|
description: "Public ID shared across blame and claim",
|
|
example: "A14235",
|
|
})
|
|
publicId: string;
|
|
|
|
@ApiProperty({
|
|
description:
|
|
"Ordered selected parts: id, side-agnostic name, side, label_fa (and optional catalogKey)",
|
|
type: [DamageSelectedPartV2BodyDto],
|
|
})
|
|
selectedParts: DamageSelectedPartV2BodyDto[];
|
|
|
|
@ApiProperty({
|
|
description: "Selected part IDs",
|
|
example: [9, 7, 11],
|
|
type: [Number],
|
|
})
|
|
selectedPartIds: number[];
|
|
|
|
@ApiProperty({
|
|
description: "Current workflow step",
|
|
example: "SELECT_OUTER_PARTS",
|
|
})
|
|
currentStep: string;
|
|
|
|
@ApiProperty({
|
|
description: "Next possible workflow step",
|
|
example: "SELECT_OTHER_PARTS",
|
|
})
|
|
nextStep: string;
|
|
|
|
@ApiProperty({
|
|
description: "Success message",
|
|
example:
|
|
"Outer parts selected successfully. Please proceed to select other parts.",
|
|
})
|
|
message: string;
|
|
|
|
@ApiPropertyOptional({
|
|
description:
|
|
"Best-effort Fanavaran damage-case submit result. Selecting parts still succeeds when this contains a warning.",
|
|
})
|
|
fanavaranDamageCase?: unknown;
|
|
}
|
|
|
|
export class SetClaimVehicleTypeV2Dto {
|
|
@ApiProperty({
|
|
description: "Vehicle type selected by user",
|
|
enum: ClaimVehicleTypeV2,
|
|
})
|
|
@IsNotEmpty()
|
|
@IsEnum(ClaimVehicleTypeV2)
|
|
carType: ClaimVehicleTypeV2;
|
|
}
|
|
|
|
/**
|
|
* Shape returned by `GET .../outer-parts-catalog` (both user and expert
|
|
* controllers). It mirrors how items are persisted under
|
|
* `damage.selectedParts` (see `DamageSelectedPartV2BodyDto`) so the front-end
|
|
* can match catalog rows to stored selections without any field renaming:
|
|
* `name` is side-agnostic, `label_fa` is disambiguated with the side in
|
|
* parentheses, and the original full catalog key (`left_backfender`) is
|
|
* exposed as `catalogKey`.
|
|
*/
|
|
export class OuterPartCatalogItemDto {
|
|
@ApiProperty({
|
|
description: "Static catalog id (unique across all car types)",
|
|
example: 102,
|
|
})
|
|
id: number;
|
|
|
|
@ApiProperty({
|
|
description: "Side-agnostic part name (matches stored part `name`)",
|
|
example: "backWheel",
|
|
})
|
|
name: string;
|
|
|
|
@ApiProperty({
|
|
description: "Vehicle side / region",
|
|
enum: OuterPartSideV2,
|
|
example: "left",
|
|
})
|
|
side: string;
|
|
|
|
@ApiProperty({
|
|
description:
|
|
"Display label in Farsi, with side disambiguator in parentheses when needed",
|
|
example: "چرخ عقب (چپ)",
|
|
})
|
|
label_fa: string;
|
|
|
|
@ApiProperty({
|
|
description: "Original full catalog key (matches stored `catalogKey`)",
|
|
example: "left_backWheel",
|
|
required: false,
|
|
})
|
|
catalogKey?: string;
|
|
|
|
@ApiProperty({
|
|
description: "Vehicle type this catalog row belongs to",
|
|
enum: ClaimVehicleTypeV2,
|
|
required: false,
|
|
example: "suv",
|
|
})
|
|
carType?: ClaimVehicleTypeV2;
|
|
}
|