diff --git a/src/expert-insurer/expert-insurer.file-summary.spec.ts b/src/expert-insurer/expert-insurer.file-summary.spec.ts new file mode 100644 index 0000000..1ac54c7 --- /dev/null +++ b/src/expert-insurer/expert-insurer.file-summary.spec.ts @@ -0,0 +1,52 @@ +import { ExpertInsurerService } from "./expert-insurer.service"; + +describe("insurer expert file summaries", () => { + const service = Object.create( + ExpertInsurerService.prototype, + ) as ExpertInsurerService; + + it("calculates blame review duration in minutes on the backend", () => { + const summary = (service as any).mapBlameFileSummaryForInsurerExpert({ + _id: "6aa50ce70545fc1906433c85", + publicId: "RPT832-00049", + requestNo: "BL-RPT832-000049", + type: "THIRD_PARTY", + status: "WAITING_FOR_SIGNATURES", + blameStatus: "AGREED", + createdAt: new Date("2026-06-21T12:42:28.000Z"), + updatedAt: new Date("2026-06-21T15:32:28.000Z"), + }); + + expect(summary.reviewDurationMinutes).toBe(170); + }); + + it("calculates claim review duration with the same contract", () => { + const summary = (service as any).mapClaimFileSummaryForInsurerExpert({ + _id: "6aa50ce70545fc1906433c86", + publicId: "RPT832-00049", + createdAt: "2026-06-21T12:42:28.000Z", + updatedAt: "2026-06-21T12:43:58.000Z", + }); + + expect(summary.reviewDurationMinutes).toBe(1.5); + }); + + it("returns null instead of NaN when a duration timestamp is unavailable", () => { + const summary = (service as any).mapBlameFileSummaryForInsurerExpert({ + _id: "6aa50ce70545fc1906433c85", + createdAt: "invalid", + }); + + expect(summary.reviewDurationMinutes).toBeNull(); + }); + + it("clamps malformed negative durations to zero", () => { + const summary = (service as any).mapClaimFileSummaryForInsurerExpert({ + _id: "6aa50ce70545fc1906433c86", + createdAt: "2026-06-21T15:32:28.000Z", + updatedAt: "2026-06-21T12:42:28.000Z", + }); + + expect(summary.reviewDurationMinutes).toBe(0); + }); +}); diff --git a/src/expert-insurer/expert-insurer.service.ts b/src/expert-insurer/expert-insurer.service.ts index ba50fa4..227a42d 100644 --- a/src/expert-insurer/expert-insurer.service.ts +++ b/src/expert-insurer/expert-insurer.service.ts @@ -264,6 +264,18 @@ export class ExpertInsurerService { return String(aid); } + private calculateReviewDurationMinutes( + createdAt: Date | string | undefined, + updatedAt: Date | string | undefined, + ): number | null { + const startedAtMs = new Date(createdAt as any).getTime(); + const reviewedAtMs = new Date(updatedAt as any).getTime(); + if (Number.isNaN(startedAtMs) || Number.isNaN(reviewedAtMs)) return null; + + const durationMinutes = Math.max(reviewedAtMs - startedAtMs, 0) / 60_000; + return Math.round(durationMinutes * 100) / 100; + } + private mapBlameFileSummaryForInsurerExpert(b: any) { return { kind: "blame" as const, @@ -275,6 +287,10 @@ export class ExpertInsurerService { blameStatus: b.blameStatus, createdAt: b.createdAt, updatedAt: b.updatedAt, + reviewDurationMinutes: this.calculateReviewDurationMinutes( + b.createdAt, + b.updatedAt, + ), }; } @@ -288,6 +304,10 @@ export class ExpertInsurerService { claimStatus: c.claimStatus, createdAt: c.createdAt, updatedAt: c.updatedAt, + reviewDurationMinutes: this.calculateReviewDurationMinutes( + c.createdAt, + c.updatedAt, + ), }; }