YARA-1257, YARA-1272, YARA-985

This commit is contained in:
SepehrYahyaee
2026-09-12 11:19:57 +03:30
parent ebe45646c1
commit 15342e16d8
18 changed files with 279 additions and 207 deletions

View File

@@ -78,7 +78,10 @@ import {
extractExpertNamesFromBlame,
extractExpertNamesFromClaim,
} from "./helper/insurer.helper";
import { getEventFaLabel } from "./helper/timeline-fa-labels";
import {
getEventFaDescription,
getEventFaLabel,
} from "./helper/timeline-fa-labels";
import { buildEnrichedDamagedParts } from "src/expert-claim/dto/claim-damaged-part.enricher";
@Injectable()
@@ -2819,6 +2822,7 @@ export class ExpertInsurerService {
source: "blame",
type: ev.type,
faLabel: getEventFaLabel(ev),
description: getEventFaDescription(ev),
timestamp: ev.timestamp,
actor: this.buildTimelineActor(ev.actor, actorName, performedBy),
actorName,
@@ -2827,7 +2831,7 @@ export class ExpertInsurerService {
ExpertInsurerService.resolveTimelinePerformedByCategory(performedBy),
performedByFaLabel:
ExpertInsurerService.resolveTimelinePerformedByFaLabel(performedBy),
metadata: ev.metadata ?? null,
metadata: this.localizeTimelineMetadata(ev),
});
}
}
@@ -2856,6 +2860,7 @@ export class ExpertInsurerService {
source: "claim",
type: ev.type,
faLabel: getEventFaLabel(ev),
description: getEventFaDescription(ev),
timestamp: ev.timestamp,
actor: this.buildTimelineActor(ev.actor, actorName, performedBy),
actorName,
@@ -2864,7 +2869,7 @@ export class ExpertInsurerService {
ExpertInsurerService.resolveTimelinePerformedByCategory(performedBy),
performedByFaLabel:
ExpertInsurerService.resolveTimelinePerformedByFaLabel(performedBy),
metadata: ev.metadata ?? null,
metadata: this.localizeTimelineMetadata(ev),
});
}
}
@@ -2878,4 +2883,22 @@ export class ExpertInsurerService {
// Resolve insurer's client name for context if needed — just return raw events
return { publicId, events };
}
/**
* Keep the timeline metadata intact, but replace persisted system-generated
* descriptions with their Persian presentation value.
*/
private localizeTimelineMetadata(event: {
type: string;
metadata?: Record<string, unknown>;
}): Record<string, unknown> | null {
if (!event.metadata) return null;
return {
...event.metadata,
...(Object.prototype.hasOwnProperty.call(event.metadata, "description")
? { description: getEventFaDescription(event) }
: {}),
};
}
}

View File

@@ -0,0 +1,25 @@
import { getEventFaDescription, getEventFaLabel } from "./timeline-fa-labels";
describe("insurer timeline Persian labels", () => {
it("localizes the user-submission detail shown to insurers", () => {
const event = {
type: "STEP_COMPLETED",
metadata: {
stepKey: "USER_SUBMISSION_COMPLETE",
description:
"User submission complete. Claim ready for damage expert review.",
},
};
expect(getEventFaLabel(event)).toBe("ارسال اطلاعات توسط کاربر");
expect(getEventFaDescription(event)).toBe(
"ثبت اطلاعات کاربر تکمیل شد و پرونده آماده بررسی کارشناس خسارت است.",
);
});
it("never returns an English event type as the description fallback", () => {
expect(getEventFaDescription({ type: "UNRECOGNIZED_EVENT" })).toBe(
"رویدادی در روند پرونده ثبت شد.",
);
});
});

View File

@@ -120,7 +120,8 @@ export const EVENT_TYPE_FA_LABELS: Record<string, string> = {
// Owner insurer approval
OWNER_SIGNED_INSURER_APPROVAL: "صاحب خودرو قرارداد بیمه را امضا کرد",
OWNER_REJECTED_INSURER_APPROVAL_PRICING: "صاحب خودرو قیمت‌گذاری بیمه را رد کرد",
OWNER_REJECTED_INSURER_APPROVAL_PRICING:
"صاحب خودرو قیمت‌گذاری بیمه را رد کرد",
OWNER_SIGNED_PRICED_PARTS_PENDING_FACTOR_UPLOAD:
"صاحب خودرو قطعات قیمت‌گذاری‌شده را امضا کرد و در انتظار بارگذاری فاکتور",
OWNER_REJECTED_PRICED_PARTS_BEFORE_FACTORS:
@@ -129,8 +130,10 @@ export const EVENT_TYPE_FA_LABELS: Record<string, string> = {
// Fanavaran sync
FANAVARAN_AUTO_SUBMIT_SUCCEEDED: "ارسال خودکار به فناوران موفق بود",
FANAVARAN_AUTO_SUBMIT_FAILED: "ارسال خودکار به فناوران ناموفق بود",
FANAVARAN_EARLY_AUTO_SUBMIT_SUCCEEDED: "ارسال زودهنگام خودکار به فناوران موفق بود",
FANAVARAN_EARLY_AUTO_SUBMIT_FAILED: "ارسال زودهنگام خودکار به فناوران ناموفق بود",
FANAVARAN_EARLY_AUTO_SUBMIT_SUCCEEDED:
"ارسال زودهنگام خودکار به فناوران موفق بود",
FANAVARAN_EARLY_AUTO_SUBMIT_FAILED:
"ارسال زودهنگام خودکار به فناوران ناموفق بود",
FANAVARAN_EXPERTISE_AUTO_SUBMIT_SUCCEEDED:
"ارسال خودکار کارشناسی به فناوران موفق بود",
FANAVARAN_EXPERTISE_AUTO_SUBMIT_FAILED:
@@ -168,6 +171,28 @@ export const STEP_KEY_FA_LABELS: Record<string, string> = {
CLAIM_COMPLETED: "پرونده خسارت تکمیل شد",
};
/**
* Persian descriptions for workflow-step events. These are deliberately
* complete sentences because the insurer timeline exposes them as the event
* detail, while `STEP_KEY_FA_LABELS` is intended for short UI labels.
*/
const STEP_KEY_FA_DESCRIPTIONS: Record<string, string> = {
CLAIM_CREATED: "پرونده خسارت ایجاد شد.",
SELECT_OUTER_PARTS: "قطعات بیرونی آسیب‌دیده انتخاب و ثبت شدند.",
SELECT_OTHER_PARTS: "سایر قطعات آسیب‌دیده و اطلاعات بانکی ثبت شدند.",
CAPTURE_PART_DAMAGES: "تصاویر آسیب قطعات و تصاویر مورد نیاز خودرو ثبت شدند.",
UPLOAD_REQUIRED_DOCUMENTS: "مدارک مورد نیاز برای بررسی خسارت بارگذاری شدند.",
USER_SUBMISSION_COMPLETE:
"ثبت اطلاعات کاربر تکمیل شد و پرونده آماده بررسی کارشناس خسارت است.",
USER_EXPERT_RESEND: "مدارک درخواستی توسط کاربر دوباره ارسال شدند.",
EXPERT_DAMAGE_ASSESSMENT: "ارزیابی خسارت توسط کارشناس انجام شد.",
EXPERT_FINAL_REPLY: "پاسخ نهایی کارشناس ثبت شد.",
EXPERT_COST_EVALUATION: "هزینه خسارت توسط کارشناس ارزیابی شد.",
OWNER_UPLOAD_FACTOR_DOCUMENTS: "فاکتورهای تعمیر توسط مالک بارگذاری شدند.",
INSURER_REVIEW: "پرونده توسط بیمه‌گر بررسی شد.",
CLAIM_COMPLETED: "رسیدگی به پرونده خسارت تکمیل شد.",
};
/**
* For `STEP_COMPLETED` and `V3_STEP_COMPLETED` events whose final label
* depends on the `metadata.stepKey` value, this function returns the
@@ -177,10 +202,7 @@ export function resolveStepCompletedFaLabel(event: {
type: string;
metadata?: any;
}): string | undefined {
if (
event.type !== "STEP_COMPLETED" &&
event.type !== "V3_STEP_COMPLETED"
) {
if (event.type !== "STEP_COMPLETED" && event.type !== "V3_STEP_COMPLETED") {
return undefined;
}
const stepKey: string | undefined = event.metadata?.stepKey;
@@ -203,3 +225,23 @@ export function getEventFaLabel(event: {
event.type
);
}
/**
* Returns a Persian sentence suitable for the timeline event `description`.
*
* History is persisted over time, so its older metadata can contain English
* system messages. The insurer endpoint uses this derived value instead of
* exposing persisted text, which localizes both old and new timeline records.
*/
export function getEventFaDescription(event: {
type: string;
metadata?: any;
}): string {
const stepKey: string | undefined = event.metadata?.stepKey;
if (stepKey && STEP_KEY_FA_DESCRIPTIONS[stepKey]) {
return STEP_KEY_FA_DESCRIPTIONS[stepKey];
}
const label = getEventFaLabel(event);
return label === event.type ? "رویدادی در روند پرونده ثبت شد." : `${label}.`;
}