Files
yara724api/src/claim-request-management/dto/claim-details-v2.dto.ts
Sepehr Yahyaee 7d1a50db7b fix: harden claim review and inquiry workflows
Preserve damage history and current vehicle price, restore depreciation mapping, normalize inquiry/report output, and support resumable expert review with paginated case retrieval.
2026-09-18 16:04:33 +03:30

288 lines
8.3 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger';
import { DamageSelectedPartV2BodyDto } from './damage-selected-part-v2.dto';
/** Suggested HTTP call for the owner UI (`pathTemplate`: replace placeholders). */
export class ClaimDetailsOwnerNextActionV2Dto {
@ApiProperty({ description: 'Stable UI key', example: 'FINAL_SIGN' })
key: string;
@ApiPropertyOptional({ description: 'HTTP verb', example: 'PUT' })
method?: string;
@ApiPropertyOptional({
description: 'Path under API root',
example: 'v2/claim-request-management/request/{claimRequestId}/owner-insurer-approval/sign',
})
pathTemplate?: string;
@ApiProperty({ description: 'What this endpoint does for the user' })
description: string;
}
/** Server-derived hints: which phase the claim is in and what to offer next (owners only). */
export class ClaimDetailsOwnerGuidanceV2Dto {
@ApiProperty({
description: 'Machine-readable phase',
enum: [
'COMPLETED',
'REJECTED',
'CANCELLED',
'EXPERT_RESEND',
'WAITING_DAMAGE_EXPERT',
'EXPERT_REVIEWING',
'USER_FLOW',
'UPLOAD_FACTORS',
'EXPERT_VALIDATING_FACTORS',
'SIGN_PRICED_LINES',
'INSURER_REVIEW_NEEDS_REVISION',
'FINAL_SIGN_OR_REJECT',
'INSURER_APPROVAL_FALLBACK',
],
})
phaseKey: string;
@ApiProperty({ description: 'Short headline for the current phase' })
headline: string;
@ApiPropertyOptional({ description: 'Longer UX copy' })
detail?: string;
@ApiProperty({ type: [ClaimDetailsOwnerNextActionV2Dto] })
nextActions: ClaimDetailsOwnerNextActionV2Dto[];
@ApiPropertyOptional({
description: 'Whether PUT objection is permitted (see server validation for exact rules)',
})
objectionAllowed?: boolean;
@ApiPropertyOptional({ description: 'How objection relates to priced vs factor-only lines' })
objectionHint?: string;
}
/** Active damage-expert resend request (owner must upload or acknowledge). */
export class ExpertResendDetailsV2Dto {
@ApiPropertyOptional()
resendDescription?: string;
@ApiPropertyOptional({ type: [String] })
resendDocuments?: string[];
@ApiPropertyOptional({
description:
"Damaged parts the expert asked to re-capture (same shape as damagedParts: id, name, side, label_fa, catalogKey, captured, url).",
type: [Object],
})
resendCarParts?: Array<{
id?: number | null;
name?: string;
side?: string;
label_fa?: string;
label_en?: string;
catalogKey?: string;
key?: string;
captured?: boolean;
url?: string;
path?: string;
fileName?: string;
}>;
@ApiPropertyOptional({ description: 'Set when the owner satisfied the resend request' })
fulfilledAt?: Date;
}
export class ClaimDetailsV2ResponseDto {
@ApiProperty({ description: 'Claim case ID' })
claimRequestId: string;
@ApiProperty({ description: 'Public ID' })
publicId: string;
@ApiProperty({ description: 'Request number' })
requestNo: string;
@ApiProperty({
description:
"ClaimCaseStatus; see also `ownerGuidance` for UX. New V2–V5 priced-only claims are COMPLETED after expert work; factor claims use INSURER_REVIEW_MIXED_FACTORS_PENDING | OWNER_REPAIR_FACTOR_UPLOAD_PENDING | EXPERT_VALIDATING_REPAIR_FACTORS. V5 then uses WAITING_FOR_FILE_MAKER_APPROVAL. Legacy WAITING_FOR_INSURER_APPROVAL or INSURER_REVIEW_AWAITING_OWNER_SIGN may still appear.",
example: "OWNER_REPAIR_FACTOR_UPLOAD_PENDING",
})
status: string;
@ApiProperty({ description: 'Claim damage status' })
claimStatus: string;
@ApiProperty({ description: 'Current workflow step' })
currentStep: string;
@ApiPropertyOptional({ description: 'Next workflow step' })
nextStep?: string;
@ApiPropertyOptional({ description: 'Blame request ID' })
blameRequestId?: string;
@ApiPropertyOptional({ description: 'Blame request number' })
blameRequestNo?: string;
@ApiPropertyOptional({
description: 'Blame file type: THIRD_PARTY or CAR_BODY',
example: 'THIRD_PARTY',
})
blameType?: string;
@ApiPropertyOptional({
description: 'How the blame file was initiated: IN_PERSON or LINK',
example: 'IN_PERSON',
})
creationMethod?: string;
@ApiPropertyOptional({
description: 'Claim owner (damaged party): ids for the user and their insurer client scope',
})
owner?: {
userId: string;
clientId?: string;
userClientKey?: string;
fullName?: string;
};
@ApiPropertyOptional({ description: 'Vehicle snapshot' })
vehicle?: {
carName?: string;
carModel?: string;
carType?: string;
plate?: any;
};
@ApiPropertyOptional({
description: 'Selected outer damaged parts (ordered objects with id, name, side, label_fa)',
type: [DamageSelectedPartV2BodyDto],
})
selectedParts?: DamageSelectedPartV2BodyDto[];
@ApiPropertyOptional({ description: 'Selected other damaged parts' })
otherParts?: string[];
@ApiPropertyOptional({ description: 'Bank info (masked)' })
money?: {
sheba?: string;
nationalCodeOfOwner?: string;
};
@ApiPropertyOptional({ description: 'Required documents status (link instead of id)' })
requiredDocuments?: Record<string, { uploaded: boolean; fileUrl?: string }>;
@ApiPropertyOptional({ description: 'Car angles captured' })
carAngles?: Record<string, { captured: boolean; url?: string }>;
@ApiPropertyOptional({
description:
'Per-part capture status and URLs (array index aligns with selectedParts; includes id, name, side, label_fa)',
type: 'array',
items: {
type: 'object',
properties: {
index: { type: 'number' },
id: { type: 'number', nullable: true },
name: { type: 'string' },
side: { type: 'string' },
label_fa: { type: 'string' },
captured: { type: 'boolean' },
url: { type: 'string' },
path: { type: 'string' },
fileName: { type: 'string' },
},
},
})
damagedParts?: Array<{
index: number;
id?: number | null;
name: string;
side: string;
label_fa: string;
captured: boolean;
url?: string;
path?: string;
fileName?: string;
}>;
@ApiPropertyOptional({
description:
'Append-only expert damaged-part revisions. Removed rows retain their original capture URL.',
type: 'array',
items: {
type: 'object',
properties: {
revisionId: { type: 'string' },
changedAt: { type: 'string', format: 'date-time' },
changedBy: { type: 'object' },
removedParts: { type: 'array', items: { type: 'object' } },
addedParts: { type: 'array', items: { type: 'object' } },
},
},
})
damagedPartsHistory?: Array<{
revisionId: string;
changedAt: Date | string;
changedBy: {
actorId: string;
actorName?: string;
actorType: string;
};
removedParts: Array<Record<string, unknown>>;
addedParts: Array<Record<string, unknown>>;
}>;
@ApiPropertyOptional({
description:
'Damage expert resend instructions and progress (when status is WAITING_FOR_USER_RESEND).',
})
expertResend?: ExpertResendDetailsV2Dto;
@ApiPropertyOptional({
description:
"Fanavaran claim reference. Returned only after the local claim reaches COMPLETED. Each of claimId, claimNo, dmgCaseId, and expertiseId is included when Fanavaran has supplied it.",
example: {
claimId: 987654,
claimNo: 123456,
dmgCaseId: 11,
expertiseId: 22,
},
})
fanavaran?: {
claimId?: number;
claimNo?: number;
dmgCaseId?: number;
expertiseId?: number;
};
@ApiPropertyOptional({
description: "Damage expert opinion(s): initial and final (after objection).",
type: Object,
})
evaluation?: {
damageExpertReply?: unknown;
damageExpertReplyFinal?: unknown;
};
@ApiPropertyOptional({
type: ClaimDetailsOwnerGuidanceV2Dto,
description:
'Owner-only: derived headline, suggested API routes, and whether objection is plausible. Omitted when the actor is FIELD_EXPERT.',
})
ownerGuidance?: ClaimDetailsOwnerGuidanceV2Dto;
@ApiPropertyOptional({ description: 'User satisfaction rating (if submitted)' })
userRating?: {
progressSpeed: number;
registrationEase: number;
overallEvaluation: number;
comment?: string;
createdAt?: Date;
};
@ApiProperty({ description: 'Created at' })
createdAt: string;
@ApiProperty({ description: 'Updated at' })
updatedAt: string;
}