From fe22e693512c659c4a14998c3aaf18ea200830ca Mon Sep 17 00:00:00 2001 From: SepehrYahyaee <7heycallmegray@gmail.com> Date: Sun, 13 Sep 2026 11:36:03 +0330 Subject: [PATCH] Persist failed inquiry audit trails --- .../request-management.service.ts | 213 +++++++++++++++--- 1 file changed, 187 insertions(+), 26 deletions(-) diff --git a/src/request-management/request-management.service.ts b/src/request-management/request-management.service.ts index 2f2e9ab..f4945d3 100644 --- a/src/request-management/request-management.service.ts +++ b/src/request-management/request-management.service.ts @@ -442,6 +442,7 @@ export class RequestManagementService { }, error, ); + await this.persistBlameInquiryAudit(req); throw new BadRequestException( `${participant.participantId} personal identity inquiry failed: ${error?.message || "استعلام در دسترس نیست"}`, ); @@ -491,6 +492,7 @@ export class RequestManagementService { { participantId: submission.vehicleOwner.participantId }, error, ); + await this.persistBlameInquiryAudit(req); throw new BadRequestException( `Vehicle ownership inquiry failed: ${error?.message || "استعلام در دسترس نیست"}`, ); @@ -536,6 +538,7 @@ export class RequestManagementService { { participantId: submission.driver.participantId }, error, ); + await this.persistBlameInquiryAudit(req); throw new BadRequestException( `Driver licence inquiry failed: ${error?.message || "استعلام در دسترس نیست"}`, ); @@ -580,6 +583,51 @@ export class RequestManagementService { return { personal, ownership, drivingLicence }; } + private async persistBlameInquiryAudit(req: any): Promise { + if (!req?._id || !req.inquiries) return; + try { + await this.blameRequestDbService.findByIdAndUpdate(req._id, { + $set: { inquiries: req.inquiries }, + }); + } catch (error: any) { + this.logger.error( + `Failed to persist inquiry audit for blame request ${req._id}: ${error?.message || error}`, + ); + } + } + + private async persistLegacyInquiryAudit( + requestId: string, + partyDetails: "firstPartyDetails" | "secondPartyDetails", + submission: NormalizedInquirySubmission>, + audit: Record, + ): Promise { + if (submission.participants.legacy) return; + const prefix = partyDetails; + try { + await this.requestManagementDbService.findAndUpdate( + { _id: requestId }, + { + $set: { + [`${prefix}.participants`]: submission.participants.participants, + [`${prefix}.participantRoles`]: submission.participants.roles, + [`${prefix}.registrationState`]: + submission.vehicle?.registrationState, + [`${prefix}.previousPlateId`]: submission.vehicle?.previousPlate + ? this.plateToPlateIdString(submission.vehicle.previousPlate) + : undefined, + [`${prefix}.vehicleVin`]: submission.vehicle?.vin, + [`${prefix}.policyInquiry`]: audit, + }, + }, + ); + } catch (error: any) { + this.logger.error( + `Failed to persist legacy inquiry audit for request ${requestId}: ${error?.message || error}`, + ); + } + } + private getPartyIndex(req: any, role: PartyRole): number { return Array.isArray(req.parties) ? req.parties.findIndex((p) => p?.role === role) @@ -3574,23 +3622,63 @@ export class RequestManagementService { // TODO: Activate // --- Proceed with existing logic if the check passes --- // 1) Main third-party/block inquiry (existing behavior) - const policyInquiry = inquirySubmission.participants.legacy - ? await (async () => { - const response = await this.sandHubService.getSandHubResponse({ - plate: body.plate, - nationalCodeOfInsurer: body.nationalCodeOfInsurer, - }); - return { - raw: response, - mapped: response["_doc"] || response, - plateKind: "CURRENT", - attempts: [{ plateKind: "CURRENT", succeeded: true, usable: true }], - }; - })() - : await this.getThirdPartyPlateInquiry(inquirySubmission); + const legacyPartyPath = isFirstParty + ? "firstPartyDetails" + : "secondPartyDetails"; + let policyInquiry: any; + try { + policyInquiry = inquirySubmission.participants.legacy + ? await (async () => { + const response = await this.sandHubService.getSandHubResponse({ + plate: body.plate, + nationalCodeOfInsurer: body.nationalCodeOfInsurer, + }); + return { + raw: response, + mapped: response["_doc"] || response, + plateKind: "CURRENT", + attempts: [ + { plateKind: "CURRENT", succeeded: true, usable: true }, + ], + }; + })() + : await this.getThirdPartyPlateInquiry(inquirySubmission); + await this.persistLegacyInquiryAudit( + requestId, + legacyPartyPath, + inquirySubmission, + policyInquiry, + ); + } catch (error: any) { + await this.persistLegacyInquiryAudit( + requestId, + legacyPartyPath, + inquirySubmission, + { + failed: true, + attempts: error?.attempts ?? [], + error: this.normalizeInquiryError(error), + }, + ); + throw error; + } const sanHubResponse = policyInquiry.mapped; - const participantInquiries = - await this.collectLegacyParticipantInquiries(inquirySubmission); + let participantInquiries: Record | undefined; + try { + participantInquiries = + await this.collectLegacyParticipantInquiries(inquirySubmission); + } catch (error: any) { + await this.persistLegacyInquiryAudit( + requestId, + legacyPartyPath, + inquirySubmission, + { + ...policyInquiry, + participantInquiryFailure: this.normalizeInquiryError(error), + }, + ); + throw error; + } // if (sanHubResponse.Error) { // throw new HttpException( @@ -7811,8 +7899,9 @@ export class RequestManagementService { PartyRole.FIRST, ); const firstPartyPlate = firstInquirySubmission.dto; + let firstPolicyInquiry: any; try { - const firstPolicyInquiry = firstInquirySubmission.participants.legacy + firstPolicyInquiry = firstInquirySubmission.participants.legacy ? await (async () => { const response = await this.sandHubService.getSandHubResponse({ plate: firstPartyPlate.plate, @@ -7829,6 +7918,12 @@ export class RequestManagementService { })() : await this.getThirdPartyPlateInquiry(firstInquirySubmission); const sandHubReport = firstPolicyInquiry.mapped; + await this.persistLegacyInquiryAudit( + requestId, + "firstPartyDetails", + firstInquirySubmission, + firstPolicyInquiry, + ); this.sandHubService.assertInsuranceMatchesDeployment( sandHubReport, "THIRD_PARTY", @@ -7906,6 +8001,17 @@ export class RequestManagementService { stepsToAdd.push(StepsEnum.F_addPlate); } catch (plateError) { + await this.persistLegacyInquiryAudit( + requestId, + "firstPartyDetails", + firstInquirySubmission, + { + ...(firstPolicyInquiry ?? {}), + failed: true, + attempts: (plateError as any)?.attempts ?? [], + error: this.normalizeInquiryError(plateError), + }, + ); this.logger.error("Error processing first party plate:", plateError); if (plateError instanceof HttpException) throw plateError; throw new InternalServerErrorException( @@ -7914,14 +8020,15 @@ export class RequestManagementService { } // Process second party plate + const secondInquirySubmission = this.normalizeInquiryInput( + BlameRequestType.THIRD_PARTY, + formData.secondParty.plate, + PartyRole.SECOND, + ); + let secondPolicyInquiry: any; try { - const secondInquirySubmission = this.normalizeInquiryInput( - BlameRequestType.THIRD_PARTY, - formData.secondParty.plate, - PartyRole.SECOND, - ); const secondPartyPlate = secondInquirySubmission.dto; - const secondPolicyInquiry = secondInquirySubmission.participants.legacy + secondPolicyInquiry = secondInquirySubmission.participants.legacy ? await (async () => { const response = await this.sandHubService.getSandHubResponse({ plate: secondPartyPlate.plate, @@ -7938,6 +8045,12 @@ export class RequestManagementService { })() : await this.getThirdPartyPlateInquiry(secondInquirySubmission); const sandHubReport = secondPolicyInquiry.mapped; + await this.persistLegacyInquiryAudit( + requestId, + "secondPartyDetails", + secondInquirySubmission, + secondPolicyInquiry, + ); const clientName = sandHubReport?.CompanyName || sandHubReport?.LastCompanyName; @@ -8017,6 +8130,17 @@ export class RequestManagementService { stepsToAdd.push(StepsEnum.S_addPlate); } catch (plateError) { + await this.persistLegacyInquiryAudit( + requestId, + "secondPartyDetails", + secondInquirySubmission, + { + ...(secondPolicyInquiry ?? {}), + failed: true, + attempts: (plateError as any)?.attempts ?? [], + error: this.normalizeInquiryError(plateError), + }, + ); this.logger.error("Error processing second party plate:", plateError); throw new InternalServerErrorException( "Failed to process second party plate information", @@ -8236,9 +8360,10 @@ export class RequestManagementService { PartyRole.FIRST, ); const firstPartyPlate = firstInquirySubmission.dto; + let thirdPartyPolicyInquiry: any; + let carBodyInquiry: any; try { - const thirdPartyPolicyInquiry = firstInquirySubmission.participants - .legacy + thirdPartyPolicyInquiry = firstInquirySubmission.participants.legacy ? await (async () => { const response = await this.sandHubService.getSandHubResponse({ plate: firstPartyPlate.plate, @@ -8255,6 +8380,12 @@ export class RequestManagementService { })() : await this.getThirdPartyPlateInquiry(firstInquirySubmission); const sandHubReport = thirdPartyPolicyInquiry.mapped; + await this.persistLegacyInquiryAudit( + requestId, + "firstPartyDetails", + firstInquirySubmission, + { thirdParty: thirdPartyPolicyInquiry }, + ); const clientName = sandHubReport?.CompanyName || sandHubReport?.LastCompanyName; @@ -8304,7 +8435,7 @@ export class RequestManagementService { }; // CAR_BODY specific insurance info - const carBodyInquiry = firstInquirySubmission.participants.legacy + carBodyInquiry = firstInquirySubmission.participants.legacy ? await this.sandHubService.getCarBodyInquiry({ nationalCodeOfInsurer: firstPartyPlate.nationalCodeOfInsurer, plate: firstPartyPlate.plate, @@ -8358,6 +8489,30 @@ export class RequestManagementService { stepsToAdd.push(StepsEnum.F_addPlate); } catch (plateError) { + await this.persistLegacyInquiryAudit( + requestId, + "firstPartyDetails", + firstInquirySubmission, + { + ...(thirdPartyPolicyInquiry + ? { thirdParty: thirdPartyPolicyInquiry } + : {}), + ...(carBodyInquiry + ? { + carBody: { + source: carBodyInquiry.source, + plateKind: carBodyInquiry.plateKind, + attempts: carBodyInquiry.attempts, + raw: carBodyInquiry.raw, + mapped: carBodyInquiry.mapped, + }, + } + : {}), + failed: true, + attempts: (plateError as any)?.attempts ?? [], + error: this.normalizeInquiryError(plateError), + }, + ); this.logger.error("Error processing first party plate:", plateError); throw new InternalServerErrorException( "Failed to process first party plate information", @@ -9505,6 +9660,7 @@ export class RequestManagementService { {}, err, ); + await this.persistBlameInquiryAudit(req); throw new BadRequestException( `${roleLabel} party plate inquiry failed: ${err?.message || "استعلام در دسترس نیست"}`, ); @@ -9660,6 +9816,7 @@ export class RequestManagementService { {}, err, ); + await this.persistBlameInquiryAudit(req); this.throwCarBodyInquiryFailure(err); } } @@ -9733,6 +9890,7 @@ export class RequestManagementService { {}, err, ); + await this.persistBlameInquiryAudit(req); throw new BadRequestException( `${roleLabel} party driving license inquiry failed: ${err?.message || "استعلام در دسترس نیست"}`, ); @@ -10352,6 +10510,7 @@ export class RequestManagementService { {}, err, ); + await this.persistBlameInquiryAudit(req); throw new BadRequestException( `${roleLabel} party VIN inquiry failed: ${err?.message || "استعلام در دسترس نیست"}`, ); @@ -10516,6 +10675,7 @@ export class RequestManagementService { {}, err, ); + await this.persistBlameInquiryAudit(req); this.throwCarBodyInquiryFailure(err); } } @@ -10589,6 +10749,7 @@ export class RequestManagementService { {}, err, ); + await this.persistBlameInquiryAudit(req); throw new BadRequestException( `${roleLabel} party driving license inquiry failed: ${err?.message || "استعلام در دسترس نیست"}`, );