Calculate insurer report review duration

This commit is contained in:
SepehrYahyaee
2026-09-13 16:15:12 +03:30
parent f9d4b5df9a
commit 6a26811555
2 changed files with 72 additions and 0 deletions

View File

@@ -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);
});
});

View File

@@ -264,6 +264,18 @@ export class ExpertInsurerService {
return String(aid); 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) { private mapBlameFileSummaryForInsurerExpert(b: any) {
return { return {
kind: "blame" as const, kind: "blame" as const,
@@ -275,6 +287,10 @@ export class ExpertInsurerService {
blameStatus: b.blameStatus, blameStatus: b.blameStatus,
createdAt: b.createdAt, createdAt: b.createdAt,
updatedAt: b.updatedAt, updatedAt: b.updatedAt,
reviewDurationMinutes: this.calculateReviewDurationMinutes(
b.createdAt,
b.updatedAt,
),
}; };
} }
@@ -288,6 +304,10 @@ export class ExpertInsurerService {
claimStatus: c.claimStatus, claimStatus: c.claimStatus,
createdAt: c.createdAt, createdAt: c.createdAt,
updatedAt: c.updatedAt, updatedAt: c.updatedAt,
reviewDurationMinutes: this.calculateReviewDurationMinutes(
c.createdAt,
c.updatedAt,
),
}; };
} }