Retain inquiry audit context on failure

This commit is contained in:
SepehrYahyaee
2026-09-13 11:42:20 +03:30
parent fe22e69351
commit 287978a555
3 changed files with 67 additions and 20 deletions

View File

@@ -230,10 +230,18 @@ describe("inquiry participant resolver", () => {
expect(query).toHaveBeenCalledTimes(2); expect(query).toHaveBeenCalledTimes(2);
expect(result.plateKind).toBe("PREVIOUS"); expect(result.plateKind).toBe("PREVIOUS");
expect(result.attempts).toEqual([ expect(result.attempts).toMatchObject([
{ plateKind: "CURRENT", succeeded: false, error: "not found" }, { plateKind: "CURRENT", succeeded: false, error: "not found" },
{ plateKind: "PREVIOUS", succeeded: true, usable: true }, { plateKind: "PREVIOUS", succeeded: true, usable: true },
]); ]);
expect(result.attempts[0]).toMatchObject({
plate: currentPlate,
vin: "NAAM01E15HK123456",
});
expect(result.attempts[1]).toMatchObject({
plate: previousPlate,
vin: "NAAM01E15HK123456",
});
}); });
it("rejects a car-body policyholder on a third-party case", () => { it("rejects a car-body policyholder on a third-party case", () => {

View File

@@ -421,6 +421,8 @@ export async function runPlateInquiryWithFallback<T>(options: {
plateKind: "CURRENT" | "PREVIOUS"; plateKind: "CURRENT" | "PREVIOUS";
attempts: Array<{ attempts: Array<{
plateKind: "CURRENT" | "PREVIOUS"; plateKind: "CURRENT" | "PREVIOUS";
plate: InquiryVehicleInputDto["currentPlate"];
vin?: string;
succeeded: boolean; succeeded: boolean;
usable?: boolean; usable?: boolean;
error?: string; error?: string;
@@ -432,6 +434,8 @@ export async function runPlateInquiryWithFallback<T>(options: {
let lastError: unknown; let lastError: unknown;
const attempts: Array<{ const attempts: Array<{
plateKind: "CURRENT" | "PREVIOUS"; plateKind: "CURRENT" | "PREVIOUS";
plate: InquiryVehicleInputDto["currentPlate"];
vin?: string;
succeeded: boolean; succeeded: boolean;
usable?: boolean; usable?: boolean;
error?: string; error?: string;
@@ -446,6 +450,8 @@ export async function runPlateInquiryWithFallback<T>(options: {
if (!usable) { if (!usable) {
attempts.push({ attempts.push({
plateKind: candidate.kind, plateKind: candidate.kind,
plate: candidate.plate,
...(options.vehicle?.vin ? { vin: options.vehicle.vin } : {}),
succeeded: true, succeeded: true,
usable: false, usable: false,
}); });
@@ -464,6 +470,8 @@ export async function runPlateInquiryWithFallback<T>(options: {
} }
attempts.push({ attempts.push({
plateKind: candidate.kind, plateKind: candidate.kind,
plate: candidate.plate,
...(options.vehicle?.vin ? { vin: options.vehicle.vin } : {}),
succeeded: true, succeeded: true,
usable: true, usable: true,
}); });
@@ -477,6 +485,8 @@ export async function runPlateInquiryWithFallback<T>(options: {
if (!alreadyRecorded) { if (!alreadyRecorded) {
attempts.push({ attempts.push({
plateKind: candidate.kind, plateKind: candidate.kind,
plate: candidate.plate,
...(options.vehicle?.vin ? { vin: options.vehicle.vin } : {}),
succeeded: false, succeeded: false,
error: error instanceof Error ? error.message : String(error), error: error instanceof Error ? error.message : String(error),
}); });

View File

@@ -336,6 +336,18 @@ export class RequestManagementService {
} }
} }
private recordInquiryParticipantContext(
req: any,
role: PartyRole,
submission: NormalizedInquirySubmission<Record<string, any>>,
): void {
this.recordPartyCaseInquiryStatus(req, "participantContext", role, true, {
participants: submission.participants.participants,
participantRoles: submission.participants.roles,
vehicle: submission.vehicle,
});
}
private async getThirdPartyPlateInquiry( private async getThirdPartyPlateInquiry(
submission: NormalizedInquirySubmission<Record<string, any>>, submission: NormalizedInquirySubmission<Record<string, any>>,
options?: Record<string, any>, options?: Record<string, any>,
@@ -587,7 +599,10 @@ export class RequestManagementService {
if (!req?._id || !req.inquiries) return; if (!req?._id || !req.inquiries) return;
try { try {
await this.blameRequestDbService.findByIdAndUpdate(req._id, { await this.blameRequestDbService.findByIdAndUpdate(req._id, {
$set: { inquiries: req.inquiries }, $set: {
inquiries: req.inquiries,
...(Array.isArray(req.parties) ? { parties: req.parties } : {}),
},
}); });
} catch (error: any) { } catch (error: any) {
this.logger.error( this.logger.error(
@@ -1791,9 +1806,7 @@ export class RequestManagementService {
{}, {},
err, err,
); );
await this.blameRequestDbService.findByIdAndUpdate(req._id, { await this.persistBlameInquiryAudit(req);
$set: { inquiries: req.inquiries },
});
throw new HttpException("Inquiry failed", HttpStatus.BAD_REQUEST); throw new HttpException("Inquiry failed", HttpStatus.BAD_REQUEST);
} }
@@ -1808,9 +1821,7 @@ export class RequestManagementService {
raw: inquiryRaw, raw: inquiryRaw,
mapped: inquiryMapped, mapped: inquiryMapped,
}); });
await this.blameRequestDbService.findByIdAndUpdate(req._id, { await this.persistBlameInquiryAudit(req);
$set: { inquiries: req.inquiries },
});
throw new HttpException( throw new HttpException(
inquiryMapped.Error.Message || "Inquiry returned error", inquiryMapped.Error.Message || "Inquiry returned error",
HttpStatus.BAD_REQUEST, HttpStatus.BAD_REQUEST,
@@ -1932,9 +1943,7 @@ export class RequestManagementService {
{}, {},
err, err,
); );
await this.blameRequestDbService.findByIdAndUpdate(req._id, { await this.persistBlameInquiryAudit(req);
$set: { inquiries: req.inquiries },
});
this.throwCarBodyInquiryFailure(err); this.throwCarBodyInquiryFailure(err);
} }
@@ -2189,9 +2198,7 @@ export class RequestManagementService {
{}, {},
err, err,
); );
await this.blameRequestDbService.findByIdAndUpdate(req._id, { await this.persistBlameInquiryAudit(req);
$set: { inquiries: req.inquiries },
});
throw new HttpException("VIN inquiry failed", HttpStatus.BAD_REQUEST); throw new HttpException("VIN inquiry failed", HttpStatus.BAD_REQUEST);
} }
@@ -2204,9 +2211,7 @@ export class RequestManagementService {
raw: inquiryRaw, raw: inquiryRaw,
mapped: inquiryMapped, mapped: inquiryMapped,
}); });
await this.blameRequestDbService.findByIdAndUpdate(req._id, { await this.persistBlameInquiryAudit(req);
$set: { inquiries: req.inquiries },
});
throw new HttpException( throw new HttpException(
inquiryMapped.Error.Message || "VIN inquiry returned error", inquiryMapped.Error.Message || "VIN inquiry returned error",
HttpStatus.BAD_REQUEST, HttpStatus.BAD_REQUEST,
@@ -2363,9 +2368,7 @@ export class RequestManagementService {
{}, {},
err, err,
); );
await this.blameRequestDbService.findByIdAndUpdate(req._id, { await this.persistBlameInquiryAudit(req);
$set: { inquiries: req.inquiries },
});
this.throwCarBodyInquiryFailure(err); this.throwCarBodyInquiryFailure(err);
} }
} }
@@ -6832,6 +6835,18 @@ export class RequestManagementService {
formData.firstPartyPlate, formData.firstPartyPlate,
PartyRole.FIRST, PartyRole.FIRST,
); );
this.recordInquiryParticipantContext(
req,
PartyRole.FIRST,
inquirySubmission,
);
const existingFirstPartyIndex = this.getPartyIndex(req, PartyRole.FIRST);
if (existingFirstPartyIndex !== -1) {
this.applyInquiryParticipantsToParty(
req.parties[existingFirstPartyIndex],
inquirySubmission,
);
}
const firstPartyPlate = inquirySubmission.dto; const firstPartyPlate = inquirySubmission.dto;
let sandHubReport: any; let sandHubReport: any;
try { try {
@@ -7130,6 +7145,14 @@ export class RequestManagementService {
plateDto, plateDto,
role, role,
); );
this.recordInquiryParticipantContext(req, role, inquirySubmission);
const existingPartyIndex = this.getPartyIndex(req, role);
if (existingPartyIndex !== -1) {
this.applyInquiryParticipantsToParty(
req.parties[existingPartyIndex],
inquirySubmission,
);
}
plateDto = inquirySubmission.dto; plateDto = inquirySubmission.dto;
const policyholderUnknown = const policyholderUnknown =
inquirySubmission.thirdPartyPolicyholder.unknown === true; inquirySubmission.thirdPartyPolicyholder.unknown === true;
@@ -9667,6 +9690,7 @@ export class RequestManagementService {
} }
if (inquiryMapped?.Error) { if (inquiryMapped?.Error) {
await this.persistBlameInquiryAudit(req);
throw new BadRequestException( throw new BadRequestException(
inquiryMapped.Error.Message || inquiryMapped.Error.Message ||
`${roleLabel} party plate inquiry returned an error`, `${roleLabel} party plate inquiry returned an error`,
@@ -9676,6 +9700,7 @@ export class RequestManagementService {
const clientName = inquiryMapped?.CompanyName; const clientName = inquiryMapped?.CompanyName;
const companyCode = inquiryMapped?.CompanyCode; const companyCode = inquiryMapped?.CompanyCode;
if (!clientName && !policyholderUnknown) { if (!clientName && !policyholderUnknown) {
await this.persistBlameInquiryAudit(req);
throw new BadRequestException( throw new BadRequestException(
`CompanyName missing from ${roleLabel} party inquiry response`, `CompanyName missing from ${roleLabel} party inquiry response`,
); );
@@ -9687,6 +9712,7 @@ export class RequestManagementService {
) )
: null; : null;
if (clientName && !client) { if (clientName && !client) {
await this.persistBlameInquiryAudit(req);
throw new BadRequestException( throw new BadRequestException(
`CompanyCode missing or invalid in ${roleLabel} party inquiry response`, `CompanyCode missing or invalid in ${roleLabel} party inquiry response`,
); );
@@ -10517,6 +10543,7 @@ export class RequestManagementService {
} }
if (inquiryMapped?.Error) { if (inquiryMapped?.Error) {
await this.persistBlameInquiryAudit(req);
throw new BadRequestException( throw new BadRequestException(
inquiryMapped.Error.Message || inquiryMapped.Error.Message ||
`${roleLabel} party VIN inquiry returned an error`, `${roleLabel} party VIN inquiry returned an error`,
@@ -10526,6 +10553,7 @@ export class RequestManagementService {
const clientName = inquiryMapped?.CompanyName; const clientName = inquiryMapped?.CompanyName;
const companyCode = inquiryMapped?.CompanyCode; const companyCode = inquiryMapped?.CompanyCode;
if (!clientName) { if (!clientName) {
await this.persistBlameInquiryAudit(req);
throw new BadRequestException( throw new BadRequestException(
`CompanyName missing from ${roleLabel} party VIN inquiry response`, `CompanyName missing from ${roleLabel} party VIN inquiry response`,
); );
@@ -10535,6 +10563,7 @@ export class RequestManagementService {
clientName, clientName,
); );
if (!client) { if (!client) {
await this.persistBlameInquiryAudit(req);
throw new BadRequestException( throw new BadRequestException(
`CompanyCode missing or invalid in ${roleLabel} party VIN inquiry response`, `CompanyCode missing or invalid in ${roleLabel} party VIN inquiry response`,
); );