forked from Yara724/api
Fix V4 FileMaker workflow re-entry
This commit is contained in:
@@ -6228,8 +6228,9 @@ export class RequestManagementService {
|
||||
// the workflow is still at CREATED, advance past any intro step to the first
|
||||
// real data-entry step.
|
||||
//
|
||||
// THIRD_PARTY: skip FIRST_BLAME_CONFESSION (first party is always guilty) and
|
||||
// land on FIRST_VIDEO.
|
||||
// THIRD_PARTY: skip FIRST_BLAME_CONFESSION (first party is always guilty).
|
||||
// V4/V5 FileMaker files have no video step and land directly on the
|
||||
// initial inquiry form; other in-person flows land on FIRST_VIDEO.
|
||||
// CAR_BODY: no confession exists; advance from CREATED to CAR_BODY_ACCIDENT_TYPE
|
||||
// so the expert can fill the car-body form before video.
|
||||
if (
|
||||
@@ -6247,9 +6248,10 @@ export class RequestManagementService {
|
||||
const carBodyStepDoc = await this.getWorkflowStep({
|
||||
stepKey: WorkflowStep.CAR_BODY_ACCIDENT_TYPE,
|
||||
});
|
||||
const afterCarBody =
|
||||
(carBodyStepDoc?.nextPossibleSteps?.[0] as WorkflowStep) ??
|
||||
WorkflowStep.FIRST_VIDEO;
|
||||
const afterCarBody = (req as any).isMadeByFileMaker
|
||||
? WorkflowStep.FIRST_INITIAL_FORM
|
||||
: ((carBodyStepDoc?.nextPossibleSteps?.[0] as WorkflowStep) ??
|
||||
WorkflowStep.FIRST_VIDEO);
|
||||
|
||||
req.workflow.completedSteps = completed;
|
||||
req.workflow.currentStep = WorkflowStep.CAR_BODY_ACCIDENT_TYPE;
|
||||
@@ -6269,16 +6271,24 @@ export class RequestManagementService {
|
||||
// THIRD_PARTY: skip confession — first party is always guilty in IN_PERSON
|
||||
const step2 = await this.getWorkflowStep({ stepNumber: 2 }); // FIRST_BLAME_CONFESSION
|
||||
const step2Key = step2.stepKey as WorkflowStep;
|
||||
const step3 = await this.getWorkflowStep({ stepNumber: 3 }); // FIRST_VIDEO
|
||||
const step3Key = step3.stepKey as WorkflowStep;
|
||||
const nextAfterVideo =
|
||||
(step3.nextPossibleSteps?.[0] as WorkflowStep) ??
|
||||
WorkflowStep.FIRST_INITIAL_FORM;
|
||||
const isFileMakerFlow = !!(req as any).isMadeByFileMaker;
|
||||
let advancedTo: WorkflowStep;
|
||||
|
||||
if (isFileMakerFlow) {
|
||||
advancedTo = WorkflowStep.FIRST_INITIAL_FORM;
|
||||
req.workflow.currentStep = advancedTo;
|
||||
req.workflow.nextStep = WorkflowStep.FIRST_VOICE;
|
||||
} else {
|
||||
const step3 = await this.getWorkflowStep({ stepNumber: 3 }); // FIRST_VIDEO
|
||||
advancedTo = step3.stepKey as WorkflowStep;
|
||||
req.workflow.currentStep = advancedTo;
|
||||
req.workflow.nextStep =
|
||||
(step3.nextPossibleSteps?.[0] as WorkflowStep) ??
|
||||
WorkflowStep.FIRST_INITIAL_FORM;
|
||||
}
|
||||
|
||||
if (!completed.includes(step2Key)) completed.push(step2Key);
|
||||
req.workflow.completedSteps = completed;
|
||||
req.workflow.currentStep = step3Key;
|
||||
req.workflow.nextStep = nextAfterVideo;
|
||||
|
||||
// Auto-guilt: first party is always guilty in expert-initiated IN_PERSON
|
||||
const fIdx = this.getPartyIndex(req, PartyRole.FIRST);
|
||||
@@ -6303,7 +6313,7 @@ export class RequestManagementService {
|
||||
reason:
|
||||
"IN_PERSON expert-initiated: first party is always guilty; confession auto-resolved",
|
||||
stepKey: step2Key,
|
||||
advancedTo: step3Key,
|
||||
advancedTo,
|
||||
},
|
||||
} as any);
|
||||
}
|
||||
@@ -11750,8 +11760,13 @@ export class RequestManagementService {
|
||||
firstParty.carBodyFirstForm.object = body.object;
|
||||
|
||||
this.pushWorkflowSteps(req, [WorkflowStep.CAR_BODY_ACCIDENT_TYPE]);
|
||||
req.workflow.currentStep = WorkflowStep.CAR_BODY_ACCIDENT_TYPE;
|
||||
req.workflow.nextStep = WorkflowStep.FIRST_INITIAL_FORM;
|
||||
if ((req as any).isMadeByFileMaker) {
|
||||
req.workflow.currentStep = WorkflowStep.FIRST_INITIAL_FORM;
|
||||
req.workflow.nextStep = WorkflowStep.FIRST_VOICE;
|
||||
} else {
|
||||
req.workflow.currentStep = WorkflowStep.CAR_BODY_ACCIDENT_TYPE;
|
||||
req.workflow.nextStep = WorkflowStep.FIRST_INITIAL_FORM;
|
||||
}
|
||||
|
||||
if (!Array.isArray(req.history)) req.history = [];
|
||||
req.history.push({
|
||||
@@ -12712,6 +12727,51 @@ export class RequestManagementService {
|
||||
*/
|
||||
// ─── FileMaker file list / detail (V4 + V5) ────────────────────────────────
|
||||
|
||||
/**
|
||||
* Older V4/V5 records may have FIRST_VIDEO persisted by the shared in-person
|
||||
* OTP transition. FileMaker flows never exposed that step, so repair the API
|
||||
* projection until the first inquiry submission naturally persists the next
|
||||
* valid workflow state.
|
||||
*/
|
||||
private fileMakerWorkflowProjection(file: any): any {
|
||||
const rawWorkflow = file?.workflow ?? {};
|
||||
const workflow =
|
||||
typeof rawWorkflow.toObject === "function"
|
||||
? rawWorkflow.toObject({ versionKey: false })
|
||||
: { ...rawWorkflow };
|
||||
const completedSteps = Array.isArray(workflow.completedSteps)
|
||||
? workflow.completedSteps.filter(
|
||||
(step: WorkflowStep) => step !== WorkflowStep.FIRST_VIDEO,
|
||||
)
|
||||
: workflow.completedSteps;
|
||||
|
||||
if (
|
||||
workflow.currentStep === WorkflowStep.FIRST_VIDEO &&
|
||||
!(completedSteps ?? []).includes(WorkflowStep.FIRST_INITIAL_FORM)
|
||||
) {
|
||||
return {
|
||||
...workflow,
|
||||
currentStep: WorkflowStep.FIRST_INITIAL_FORM,
|
||||
nextStep: WorkflowStep.FIRST_VOICE,
|
||||
completedSteps,
|
||||
};
|
||||
}
|
||||
|
||||
if (
|
||||
file?.type === BlameRequestType.CAR_BODY &&
|
||||
workflow.currentStep === WorkflowStep.CAR_BODY_ACCIDENT_TYPE &&
|
||||
workflow.nextStep === WorkflowStep.FIRST_VIDEO
|
||||
) {
|
||||
return {
|
||||
...workflow,
|
||||
nextStep: WorkflowStep.FIRST_INITIAL_FORM,
|
||||
completedSteps,
|
||||
};
|
||||
}
|
||||
|
||||
return { ...workflow, completedSteps };
|
||||
}
|
||||
|
||||
async getMyFileMakerFiles(fileMaker: any): Promise<any[]> {
|
||||
if (fileMaker?.role !== RoleEnum.FILE_MAKER) {
|
||||
throw new ForbiddenException("Only FileMakers can use this endpoint.");
|
||||
@@ -12721,22 +12781,25 @@ export class RequestManagementService {
|
||||
isMadeByFileMaker: true,
|
||||
initiatedByFieldExpertId: makerId,
|
||||
});
|
||||
return (files || []).map((f: any) => ({
|
||||
_id: f._id,
|
||||
publicId: f.publicId,
|
||||
requestNo: f.requestNo,
|
||||
type: f.type,
|
||||
status: f.status,
|
||||
blameStatus: f.blameStatus,
|
||||
workflow: {
|
||||
currentStep: f.workflow?.currentStep,
|
||||
nextStep: f.workflow?.nextStep,
|
||||
completedSteps: f.workflow?.completedSteps,
|
||||
},
|
||||
requiresFileMakerApproval: f.requiresFileMakerApproval,
|
||||
createdAt: f.createdAt,
|
||||
updatedAt: f.updatedAt,
|
||||
}));
|
||||
return (files || []).map((f: any) => {
|
||||
const workflow = this.fileMakerWorkflowProjection(f);
|
||||
return {
|
||||
_id: f._id,
|
||||
publicId: f.publicId,
|
||||
requestNo: f.requestNo,
|
||||
type: f.type,
|
||||
status: f.status,
|
||||
blameStatus: f.blameStatus,
|
||||
workflow: {
|
||||
currentStep: workflow.currentStep,
|
||||
nextStep: workflow.nextStep,
|
||||
completedSteps: workflow.completedSteps,
|
||||
},
|
||||
requiresFileMakerApproval: f.requiresFileMakerApproval,
|
||||
createdAt: f.createdAt,
|
||||
updatedAt: f.updatedAt,
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
async getMyFileMakerFileDetail(
|
||||
@@ -12777,7 +12840,7 @@ export class RequestManagementService {
|
||||
type: plain.type,
|
||||
status: plain.status,
|
||||
blameStatus: plain.blameStatus,
|
||||
workflow: plain.workflow,
|
||||
workflow: this.fileMakerWorkflowProjection(plain),
|
||||
requiresFileMakerApproval: plain.requiresFileMakerApproval,
|
||||
parties: (plain.parties ?? []).map((p: any) => ({
|
||||
role: p.role,
|
||||
|
||||
Reference in New Issue
Block a user