From f39c50aeb0b59a3877bec9a3fe647eb2ba2155f2 Mon Sep 17 00:00:00 2001 From: SepehrYahyaee <7heycallmegray@gmail.com> Date: Wed, 15 Jul 2026 15:59:21 +0330 Subject: [PATCH] Fixed v4/v5 car capture flow --- .../claim-request-management.service.ts | 84 ++++++++++++------- .../file-reviewer-blame-v4.controller.ts | 22 ++--- .../file-reviewer-blame-v5.controller.ts | 30 +++---- 3 files changed, 82 insertions(+), 54 deletions(-) diff --git a/src/claim-request-management/claim-request-management.service.ts b/src/claim-request-management/claim-request-management.service.ts index c8ce4fa..24622e7 100644 --- a/src/claim-request-management/claim-request-management.service.ts +++ b/src/claim-request-management/claim-request-management.service.ts @@ -8335,36 +8335,17 @@ export class ClaimRequestManagementService { ) { captureStepCompletedOnThisUpload = true; - if (options?.v3InPersonFlow) { - // V4/V5: no further upload steps after capture docs — finalise now. - const finalStatus = options.requiresFileMakerApproval - ? ClaimCaseStatus.WAITING_FOR_FILE_MAKER_APPROVAL - : ClaimCaseStatus.WAITING_FOR_DAMAGE_EXPERT; - $set["status"] = finalStatus; - $set["claimStatus"] = ClaimStatus.PENDING; - $set["workflow.currentStep"] = ClaimWorkflowStep.USER_SUBMISSION_COMPLETE; - $set["workflow.nextStep"] = ClaimWorkflowStep.EXPERT_DAMAGE_ASSESSMENT; - - // Mark the linked blame as COMPLETED. - if (claimCase.blameRequestId) { - await this.blameRequestDbService.findByIdAndUpdate( - String(claimCase.blameRequestId), - { $set: { status: BlameCaseStatus.COMPLETED } }, - ); - } - } else { - $set["status"] = ClaimCaseStatus.UPLOADING_REQUIRED_DOCUMENTS; - $set["workflow.currentStep"] = - ClaimWorkflowStep.UPLOAD_REQUIRED_DOCUMENTS; - $set["workflow.nextStep"] = ClaimWorkflowStep.USER_SUBMISSION_COMPLETE; - } + // Advance to walk-around video step (UPLOADING_REQUIRED_DOCUMENTS / + // UPLOAD_REQUIRED_DOCUMENTS). For V4/V5 the claim is finalised in + // setVideoCaptureV3 (car-capture), which is the last FileReviewer + // action before handing off to the damage expert. + $set["status"] = ClaimCaseStatus.UPLOADING_REQUIRED_DOCUMENTS; + $set["workflow.currentStep"] = ClaimWorkflowStep.UPLOAD_REQUIRED_DOCUMENTS; + $set["workflow.nextStep"] = ClaimWorkflowStep.USER_SUBMISSION_COMPLETE; completedStepsEntries.push( ClaimWorkflowStep.CAPTURE_PART_DAMAGES, ); - completedStepsEntries.push( - ClaimWorkflowStep.USER_SUBMISSION_COMPLETE, - ); historyEntries.push({ type: "STEP_COMPLETED", actor: { @@ -8376,7 +8357,7 @@ export class ClaimRequestManagementService { metadata: { stepKey: ClaimWorkflowStep.CAPTURE_PART_DAMAGES, description: options?.v3InPersonFlow - ? "V4/V5 capture complete. Claim ready for review." + ? "V4/V5 capture docs complete. Upload walk-around video to finalise." : "Angles, damaged parts, and capture-phase vehicle evidence are complete.", }, }); @@ -8540,7 +8521,9 @@ export class ClaimRequestManagementService { const message = isCapturePhaseDocUpload ? captureStepCompletedOnThisUpload - ? "Capture-phase documents and all damage captures are complete. Please proceed to upload the remaining required documents." + ? options?.v3InPersonFlow + ? "Capture-phase documents and all damage captures are complete. Upload the walk-around video (car-capture) to finalise." + : "Capture-phase documents and all damage captures are complete. Please proceed to upload the remaining required documents." : remaining > 0 ? `Document saved. ${remaining} capture-phase document(s) still required (chassis, engine, metal plate).` : capturePhaseSequenceMessage( @@ -10584,7 +10567,7 @@ export class ClaimRequestManagementService { ClaimWorkflowStep.UPLOAD_REQUIRED_DOCUMENTS ) { throw new BadRequestException( - `Complete all part/angle captures first. Expected ${ClaimWorkflowStep.UPLOAD_REQUIRED_DOCUMENTS}, but current step is ${claimCase.workflow?.currentStep}`, + `Complete capture-phase documents (chassis/engine) first. Expected ${ClaimWorkflowStep.UPLOAD_REQUIRED_DOCUMENTS}, but current step is ${claimCase.workflow?.currentStep}`, ); } @@ -10607,12 +10590,53 @@ export class ClaimRequestManagementService { ); } - return this.setVideoCaptureV2( + // Store the walk-around video (shared V2 logic). + const result = await this.setVideoCaptureV2( claimRequestId, fileDetail, currentUserId, actor, ); + + // V4/V5 (in-person FileReviewer flow): car-capture is the last step. + // Both variants land at WAITING_FOR_DAMAGE_EXPERT here. + // For V5 (requiresFileMakerApproval=true), autoSubmitToFanavaranV2OnClaimCompleted + // intercepts COMPLETED → WAITING_FOR_FILE_MAKER_APPROVAL after expert review. + await this.claimCaseDbService.findByIdAndUpdate(claimRequestId, { + $set: { + status: ClaimCaseStatus.WAITING_FOR_DAMAGE_EXPERT, + claimStatus: ClaimStatus.PENDING, + "workflow.currentStep": ClaimWorkflowStep.USER_SUBMISSION_COMPLETE, + "workflow.nextStep": ClaimWorkflowStep.EXPERT_DAMAGE_ASSESSMENT, + }, + $push: { + "workflow.completedSteps": ClaimWorkflowStep.USER_SUBMISSION_COMPLETE, + history: { + type: "STEP_COMPLETED", + actor: { + actorId: new Types.ObjectId(currentUserId), + actorName: claimCase.owner?.fullName || "User", + actorType: actor?.role === RoleEnum.FILE_REVIEWER ? "file_reviewer" : "user", + }, + timestamp: new Date(), + metadata: { + stepKey: ClaimWorkflowStep.USER_SUBMISSION_COMPLETE, + description: "V4/V5 walk-around video uploaded. Claim ready for damage expert review.", + v3InPersonFlow: true, + }, + }, + }, + }); + + // Mark the linked blame file as COMPLETED. + if (claimCase.blameRequestId) { + await this.blameRequestDbService.findByIdAndUpdate( + String(claimCase.blameRequestId), + { $set: { status: BlameCaseStatus.COMPLETED } }, + ); + } + + return result; } async capturePartV3( diff --git a/src/request-management/file-reviewer-blame-v4.controller.ts b/src/request-management/file-reviewer-blame-v4.controller.ts index 167d855..9eefc09 100644 --- a/src/request-management/file-reviewer-blame-v4.controller.ts +++ b/src/request-management/file-reviewer-blame-v4.controller.ts @@ -51,8 +51,7 @@ import { GetCaptureRequirementsV2ResponseDto } from "src/claim-request-managemen * * The FileReviewer picks up a sealed file (both signatures collected by the * FileMaker) and completes the damage-assessment portion: accident fields, - * documents, part selection, photo capture, walk-around video, and the final - * blame accident video that moves the file to WAITING_FOR_EXPERT. + * documents, part selection, photo capture, and walk-around video (final step). * * Sequence: * accident-fields @@ -61,9 +60,11 @@ import { GetCaptureRequirementsV2ResponseDto } from "src/claim-request-managemen * → select-outer-parts * → select-other-parts * → capture-part (damaged-part photos + four angles) - * → upload-document (chassis / engine / metal plate — capture phase) - * → car-capture (walk-around video) - * → upload-video (blame accident video — final, moves to WAITING_FOR_EXPERT) + * → upload-document (chassis / engine — capture phase) + * → car-capture (walk-around video — FINAL FileReviewer step) + * ↳ claim → WAITING_FOR_DAMAGE_EXPERT, blame → COMPLETED + * + * NOTE: upload-video is a no-op for V4 (blame is already COMPLETED by car-capture). */ @ApiTags("v4 FileReviewer — blame file review & capture") @Controller("v4/file-reviewer/blame-request-management") @@ -341,9 +342,10 @@ export class FileReviewerBlameV4Controller { }, }) @ApiOperation({ - summary: "Walk-around video", + summary: "Walk-around video (final FileReviewer step — V4)", description: - "Upload after capture-part is complete (parts, angles, capture-phase docs). Required before the final blame accident video.", + "Last FileReviewer action. Upload after capture-part is complete (parts, angles, chassis/engine docs). " + + "Finalises the claim → WAITING_FOR_DAMAGE_EXPERT and marks the blame as COMPLETED.", }) async carCapture( @Param("claimRequestId") claimRequestId: string, @@ -384,10 +386,10 @@ export class FileReviewerBlameV4Controller { @Post("upload-video/:requestId") @ApiParam({ name: "requestId" }) @ApiOperation({ - summary: "Blame accident video (FileReviewer final step — optional)", + summary: "Blame accident video (no-op for V4 — car-capture is the final step)", description: - "Last step of the V4 flow. Requires claim walk-around video and completed capture. " + - "File is optional — omit it to complete the blame without attaching a video.", + "Deprecated for V4. The blame is already COMPLETED by car-capture. " + + "Calling this endpoint returns an idempotent success response.", }) async uploadBlameVideo( @Param("requestId") requestId: string, diff --git a/src/request-management/file-reviewer-blame-v5.controller.ts b/src/request-management/file-reviewer-blame-v5.controller.ts index 225cc37..8fc401a 100644 --- a/src/request-management/file-reviewer-blame-v5.controller.ts +++ b/src/request-management/file-reviewer-blame-v5.controller.ts @@ -47,11 +47,9 @@ import { import { GetCaptureRequirementsV2ResponseDto } from "src/claim-request-management/dto/capture-requirements-v2.dto"; /** - * V5 FileReviewer flow — same as V4 except the final blame accident video moves - * the file to WAITING_FOR_FINANCIAL_EXPERT instead of WAITING_FOR_EXPERT. - * - * A FinancialExpert must then approve the file (→ WAITING_FOR_EXPERT) or - * reject it back (→ FINANCIAL_EXPERT_REJECTED) for the FileReviewer to correct. + * V5 FileReviewer flow — same as V4 except after the damage expert completes + * their review, the claim goes to WAITING_FOR_FILE_MAKER_APPROVAL instead of + * being submitted directly to fanavaran. * * Sequence: * accident-fields @@ -60,9 +58,12 @@ import { GetCaptureRequirementsV2ResponseDto } from "src/claim-request-managemen * → select-outer-parts * → select-other-parts * → capture-part (damaged-part photos + four angles) - * → upload-document (chassis / engine / metal plate — capture phase) - * → car-capture (walk-around video) - * → upload-video (blame accident video — final, moves to WAITING_FOR_FINANCIAL_EXPERT) + * → upload-document (chassis / engine — capture phase) + * → car-capture (walk-around video — FINAL FileReviewer step) + * ↳ claim → WAITING_FOR_DAMAGE_EXPERT, blame → COMPLETED + * ↳ after expert review: claim → WAITING_FOR_FILE_MAKER_APPROVAL + * + * NOTE: upload-video is a no-op for V5 (blame is already COMPLETED by car-capture). */ @ApiTags("v5 FileReviewer — blame file review & capture (with FinancialExpert approval)") @Controller("v5/file-reviewer/blame-request-management") @@ -340,9 +341,11 @@ export class FileReviewerBlameV5Controller { }, }) @ApiOperation({ - summary: "Walk-around video", + summary: "Walk-around video (final FileReviewer step — V5)", description: - "Upload after capture-part is complete (parts, angles, capture-phase docs). Required before the final blame accident video.", + "Last FileReviewer action. Upload after capture-part is complete (parts, angles, chassis/engine docs). " + + "Finalises the claim → WAITING_FOR_DAMAGE_EXPERT and marks the blame as COMPLETED. " + + "After the damage expert review completes the claim moves to WAITING_FOR_FILE_MAKER_APPROVAL.", }) async carCapture( @Param("claimRequestId") claimRequestId: string, @@ -360,7 +363,6 @@ export class FileReviewerBlameV5Controller { // ─── Final blame video ───────────────────────────────────────────────────────── // - // V5 difference: moves file to WAITING_FOR_FINANCIAL_EXPERT, not WAITING_FOR_EXPERT. @ApiBody({ schema: { @@ -385,10 +387,10 @@ export class FileReviewerBlameV5Controller { @Post("upload-video/:requestId") @ApiParam({ name: "requestId" }) @ApiOperation({ - summary: "Blame accident video (FileReviewer final step — V5, optional)", + summary: "Blame accident video (no-op for V5 — car-capture is the final step)", description: - "Last step of the V5 FileReviewer flow. Requires claim walk-around video and completed capture. " + - "File is optional — omit it to complete the blame without attaching a video.", + "Deprecated for V5. The blame is already COMPLETED by car-capture. " + + "Calling this endpoint returns an idempotent success response.", }) async uploadBlameVideo( @Param("requestId") requestId: string,