YARA-1177

This commit is contained in:
2026-07-31 19:45:33 +03:30
parent e742d43201
commit 77cf420c33
9 changed files with 1100 additions and 303 deletions

View File

@@ -8,69 +8,20 @@ import {
IsOptional,
IsInt,
} from "class-validator";
import {
ClaimVehicleTypeV2,
OuterPartSideV2,
} from "src/static/outer-car-parts-catalog";
import { ClaimVehicleTypeV2 } 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
* V2 DTO for selecting damaged outer car parts.
* Submit `selectedPartIds` with IDs from the `GET outer-parts-catalog` response.
*/
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],
@ApiPropertyOptional({
description:
"Selected outer part IDs from the Fanavaran car-components catalog. " +
"IDs must match values returned by GET outer-parts-catalog.",
example: [9, 10, 30],
type: [Number],
required: false,
})
@IsOptional()
@IsArray({ message: "selectedPartIds must be an array" })
@@ -79,12 +30,13 @@ export class SelectOuterPartsV2Dto {
@IsInt({ each: true, message: "Each selected part ID must be an integer" })
selectedPartIds?: number[];
@ApiProperty({
description: "Vehicle type for validating available outer parts",
@ApiPropertyOptional({
description:
"Vehicle type (sedan, suv, hatchback, pickup, van). Optional — stored for context only; " +
"all vehicle types share the same Fanavaran parts catalog.",
enum: ClaimVehicleTypeV2,
required: true,
})
@IsNotEmpty()
@IsOptional()
@IsEnum(ClaimVehicleTypeV2)
carType?: ClaimVehicleTypeV2;
}
@@ -156,53 +108,21 @@ export class SetClaimVehicleTypeV2Dto {
}
/**
* 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`.
* Shape returned by `GET .../outer-parts-catalog`.
* Sourced live from the Fanavaran `car/base-info/car-components` lookup so that
* the list always matches what Fanavaran accepts in `DmgSections[].DmgSectionId`.
*/
export class OuterPartCatalogItemDto {
@ApiProperty({
description: "Static catalog id (unique across all car types)",
example: 102,
description:
"Fanavaran DmgSectionId — use this value when submitting selectedPartIds",
example: 30,
})
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: "چرخ عقب (چپ)",
description: "Display label in Farsi (Caption from Fanavaran)",
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;
}