Merge pull request 'Fixed v6 flow' (#242) from s.yahyaee/yara724-api:main into main

Reviewed-on: Yara724/api#242
This commit is contained in:
2026-08-03 11:06:35 +03:30

View File

@@ -110,6 +110,19 @@ import {
} from "src/helpers/party-access-queries"; } from "src/helpers/party-access-queries";
import { resolveLinkedUserIdStrings } from "src/helpers/user-access-resolver"; import { resolveLinkedUserIdStrings } from "src/helpers/user-access-resolver";
/**
* Formats a compact Jalali date (number or string like 13780624) as YYYY/MM/DD.
* Returns the original value as a string if it cannot be parsed.
*/
function formatJalaliCompact(raw: number | string | null | undefined): string | null | undefined {
if (raw == null) return raw as null | undefined;
const s = String(raw).replace(/\D/g, "");
if (s.length === 8) {
return `${s.slice(0, 4)}/${s.slice(4, 6)}/${s.slice(6, 8)}`;
}
return String(raw);
}
@Injectable() @Injectable()
export class RequestManagementService { export class RequestManagementService {
private readonly logger = new Logger(RequestManagementService.name); private readonly logger = new Logger(RequestManagementService.name);
@@ -10750,7 +10763,7 @@ export class RequestManagementService {
publicId: (req as any).publicId, publicId: (req as any).publicId,
type: (req as any).type, type: (req as any).type,
status: (req as any).status, status: (req as any).status,
message: "Guilty-party inquiry complete. You can now send the blame link to the user.", message: "استعلام طرف مقصر با موفقیت انجام شد. اکنون می‌توانید لینک تقصیر را برای کاربر ارسال کنید.",
guiltyParty: { guiltyParty: {
vehicle: firstPartyAfter?.vehicle vehicle: firstPartyAfter?.vehicle
? { ? {
@@ -10773,8 +10786,8 @@ export class RequestManagementService {
nationalCodeOfInsurer: firstPartyAfter.person.nationalCodeOfInsurer, nationalCodeOfInsurer: firstPartyAfter.person.nationalCodeOfInsurer,
nationalCodeOfDriver: firstPartyAfter.person.nationalCodeOfDriver, nationalCodeOfDriver: firstPartyAfter.person.nationalCodeOfDriver,
driverIsInsurer: firstPartyAfter.person.driverIsInsurer, driverIsInsurer: firstPartyAfter.person.driverIsInsurer,
insurerBirthday: firstPartyAfter.person.insurerBirthday, insurerBirthday: formatJalaliCompact(firstPartyAfter.person.insurerBirthday),
driverBirthday: firstPartyAfter.person.driverBirthday, driverBirthday: formatJalaliCompact(firstPartyAfter.person.driverBirthday),
} }
: undefined, : undefined,
}, },
@@ -10813,6 +10826,55 @@ export class RequestManagementService {
req.parties[firstIdx].person.phoneNumber = normalizeIranMobile(phone) ?? phone; req.parties[firstIdx].person.phoneNumber = normalizeIranMobile(phone) ?? phone;
req.parties[firstIdx].person.userId = userId; req.parties[firstIdx].person.userId = userId;
// V6 call-center flow: the first party is always the guilty party.
// Auto-skip FIRST_BLAME_CONFESSION, set blameStatus=AGREED, and advance
// the workflow to FIRST_VIDEO — exactly the same as the IN_PERSON expert flow.
if (req.workflow?.currentStep === WorkflowStep.CREATED) {
const step2 = await this.getWorkflowStep({ stepNumber: 2 }); // FIRST_BLAME_CONFESSION
const step2Key = step2.stepKey as WorkflowStep;
if (req.type === BlameRequestType.CAR_BODY) {
// CAR_BODY: advance CREATED → CAR_BODY_ACCIDENT_TYPE
const carBodyStepDoc = await this.getWorkflowStep({ stepKey: WorkflowStep.CAR_BODY_ACCIDENT_TYPE });
const afterCarBody = (carBodyStepDoc?.nextPossibleSteps?.[0] as WorkflowStep) ?? WorkflowStep.FIRST_VIDEO;
const completedSteps = Array.isArray(req.workflow.completedSteps) ? req.workflow.completedSteps : [];
req.workflow.completedSteps = completedSteps;
req.workflow.currentStep = WorkflowStep.CAR_BODY_ACCIDENT_TYPE;
req.workflow.nextStep = afterCarBody;
} else {
// THIRD_PARTY: skip confession — first party is always guilty
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 completedSteps = Array.isArray(req.workflow.completedSteps) ? req.workflow.completedSteps : [];
if (!completedSteps.includes(step2Key)) completedSteps.push(step2Key);
req.workflow.completedSteps = completedSteps;
req.workflow.currentStep = step3Key;
req.workflow.nextStep = nextAfterVideo;
}
// Auto-guilt: first party is always the guilty party in call-center v6 flow
if (!req.parties[firstIdx].statement) req.parties[firstIdx].statement = {} as any;
req.parties[firstIdx].statement.admitsGuilt = true;
req.parties[firstIdx].statement.claimsDamage = false;
req.parties[firstIdx].statement.acceptsExpertOpinion = false;
req.blameStatus = BlameStatus.AGREED;
if (!Array.isArray((req as any).history)) (req as any).history = [];
(req as any).history.push({
type: "AUTO_CONFESSION_SKIPPED",
actor: {
actorId: new Types.ObjectId(agent.sub),
actorName: `${agent.firstName || ""} ${agent.lastName || ""}`.trim(),
actorType: RoleEnum.CALL_CENTER,
},
metadata: {
reason: "V6 call-center initiated: first party is always guilty; confession auto-resolved",
advancedTo: req.workflow.currentStep,
},
});
}
const expertName = `${agent?.lastName || ""}`.trim() || "اپراتور"; const expertName = `${agent?.lastName || ""}`.trim() || "اپراتور";
const firstLink = this.smsOrchestrationService.buildBlamePartyLink(requestId, "FIRST", "v6"); const firstLink = this.smsOrchestrationService.buildBlamePartyLink(requestId, "FIRST", "v6");
const smsSent = await this.smsOrchestrationService.sendFieldExpertLink({ const smsSent = await this.smsOrchestrationService.sendFieldExpertLink({