/** * Persian (Farsi) display labels for every timeline event `type` that can * appear in a blame or claim history array. * * For generic `STEP_COMPLETED` / `V3_STEP_COMPLETED` events the label is * derived from the `metadata.stepKey` value; those keys are listed at the * bottom under STEP_KEY_FA_LABELS. * * Usage: * const label = EVENT_TYPE_FA_LABELS[event.type] * ?? resolveStepCompletedFaLabel(event) * ?? "رویداد پرونده"; */ // --------------------------------------------------------------------------- // Blame-phase events (recorded on BlameRequest.history) // --------------------------------------------------------------------------- export const EVENT_TYPE_FA_LABELS: Record = { // File creation FILE_CREATED_BY_REGISTRAR: "پرونده توسط ثبت‌کننده ایجاد شد", FILE_CREATED_BY_FIELD_EXPERT: "پرونده توسط کارشناس میدانی ایجاد شد", FILE_CREATED_BY_CALL_CENTER: "پرونده توسط اپراتور کال‌سنتر ایجاد شد", // Expert link / OTP flow LINK_SENT: "لینک ارسال شد", CALL_CENTER_LINK_SENT: "لینک توسط اپراتور کال‌سنتر ارسال شد", PARTY_OTP_SENT: "کد تأیید ارسال شد", PARTY_OTP_VERIFIED: "کد تأیید تأیید شد", PARTY_OTPS_VERIFIED: "کدهای تأیید هر دو طرف تأیید شدند", SECOND_PARTY_OTP_SENT: "کد تأیید طرف دوم ارسال شد", SECOND_PARTY_OTP_VERIFIED_ADVANCED: "کد طرف دوم تأیید و پیشرفت انجام شد", // Confession / accident type FIRST_BLAME_CONFESSION_SUBMITTED: "اقرار اولیه طرف اول ثبت شد", CALL_CENTER_INQUIRY_COMPLETED: "استعلام کال‌سنتر تکمیل شد", CAR_BODY_ACCIDENT_TYPE_SUBMITTED: "نوع تصادف بدنه خودرو ثبت شد", AUTO_ADVANCED_TO_CAR_BODY_FORM: "پیشرفت خودکار به فرم بدنه خودرو", AUTO_CONFESSION_SKIPPED: "مرحله اقرار به‌صورت خودکار رد شد", // First video FIRST_VIDEO_UPLOADED: "ویدیوی اول بارگذاری شد", // Legacy first/second-party self-service flow FIRST_INITIAL_FORM_SUBMITTED: "فرم اولیه طرف اول ثبت شد", SECOND_INITIAL_FORM_SUBMITTED: "فرم اولیه طرف دوم ثبت شد", FIRST_LOCATION_SUBMITTED: "موقعیت مکانی طرف اول ثبت شد", SECOND_LOCATION_SUBMITTED: "موقعیت مکانی طرف دوم ثبت شد", FIRST_VOICE_UPLOADED: "صدای طرف اول بارگذاری شد", SECOND_VOICE_UPLOADED: "صدای طرف دوم بارگذاری شد", FIRST_DESCRIPTION_SUBMITTED: "توضیحات طرف اول ثبت شد", SECOND_DESCRIPTION_SUBMITTED: "توضیحات طرف دوم ثبت شد", // Second party invitation SECOND_PARTY_INVITED: "طرف دوم دعوت شد", // Accident fields / expert in-person completion ACCIDENT_FIELDS_SAVED: "اطلاعات تصادف ثبت شد", ACCIDENT_FIELDS_SAVED_ADVANCED_TO_SIGNATURES: "اطلاعات تصادف ذخیره و به مرحله امضاها پیشرفت شد", EXPERT_COMPLETED_CAR_BODY_FORM_V2: "کارشناس فرم بدنه خودرو را تکمیل کرد", EXPERT_COMPLETED_THIRD_PARTY_FORM_V2: "کارشناس فرم شخص ثالث را تکمیل کرد", EXPERT_ADDED_LOCATIONS_V2: "کارشناس موقعیت مکانی را ثبت کرد", EXPERT_UPLOADED_VIDEO_V2: "کارشناس ویدیو را بارگذاری کرد", EXPERT_UPLOADED_VOICE_V2: "کارشناس صدا را بارگذاری کرد", // Party rejection / disagreement PARTY_REJECTED_EXPERT_DECISION: "طرف حساب با نظر کارشناس مخالفت کرد", PARTIES_DISAGREED_ON_EXPERT_DECISION: "طرفین با نظر کارشناس توافق نکردند", // Document resend (blame) BLAME_DOCUMENT_RESEND_STARTED: "درخواست ارسال مجدد مدارک پرونده شروع شد", BLAME_DOCUMENT_RESEND_CLEARED: "ارسال مجدد مدارک پرونده پاک‌سازی شد", // Expert assignment (blame) BLAME_ASSIGNED: "پرونده به کارشناس تخصیص داده شد", AUTO_ASSIGNED_TO_EXPERT: "پرونده به‌صورت خودکار به کارشناس تخصیص یافت", // Auto-assignment helpers READY_FOR_EXPERT_EVALUATION: "پرونده آماده ارزیابی کارشناس شد", SECOND_PARTY_DESCRIPTION_COMPLETED: "توضیحات طرف دوم تکمیل شد", // V3 blame steps V3_PARTY_SIGNATURE_RECORDED: "امضای طرف ثبت شد", V3_ACCIDENT_FIELDS_SAVED: "اطلاعات تصادف ثبت شد", V3_BLAME_ACCIDENT_VIDEO_UPLOADED: "ویدیوی تصادف بارگذاری شد", V3_PARTY_VOICE_UPLOADED: "صدای طرف بارگذاری شد", V3_PARTY_LOCATION_SAVED: "موقعیت مکانی طرف ذخیره شد", V3_PARTY_DESCRIPTION_SAVED: "توضیحات طرف ذخیره شد", V4_PARTY_DESCRIPTION_SAVED: "توضیحات طرف ذخیره شد", V3_CAR_BODY_ACCIDENT_TYPE_SAVED: "نوع تصادف بدنه خودرو ذخیره شد", // V5 blame steps V5_BLAME_ACCIDENT_VIDEO_UPLOADED: "ویدیوی تصادف (نسخه ۵) بارگذاری شد", V5_FILE_MAKER_APPROVED: "پرونده‌ساز پرونده را تأیید کرد", V5_FILE_MAKER_REJECTED: "پرونده‌ساز پرونده را رد کرد", V5_FILE_MAKER_REJECTED_BLAME_RESET: "پرونده‌ساز پرونده را رد کرد و پرونده به مرحله قبل بازگردانده شد", // --------------------------------------------------------------------------- // Claim-phase events (recorded on ClaimCase.history) // --------------------------------------------------------------------------- // Claim creation CLAIM_CREATED: "پرونده خسارت ایجاد شد", // Expert assignment (claim) CLAIM_ASSIGNED: "پرونده خسارت به کارشناس ارزیابی تخصیص داده شد", // Expert actions on claim EXPERT_RESEND_REQUESTED: "کارشناس درخواست ارسال مجدد مدارک داد", EXPERT_RESEND_FULFILLED: "مدارک درخواستی ارسال شد", IN_PERSON_VISIT_REQUESTED: "کارشناس بازدید حضوری درخواست کرد", EXPERT_DAMAGED_PARTS_UPDATED: "کارشناس قطعات آسیب‌دیده را به‌روزرسانی کرد", EXPERT_REPLY_SUBMITTED: "پاسخ کارشناس ثبت شد", EXPERT_FINAL_REPLY_SUBMITTED: "پاسخ نهایی کارشناس ثبت شد", FACTORS_REJECTED_REPRICED_AUTO_COMPLETED: "بررسی فاکتورها با قیمت‌گذاری مجدد تکمیل شد", FACTORS_VALIDATED_ALL_APPROVED_AUTO_COMPLETED: "همه فاکتورها تأیید و پرونده تکمیل شد", // Workflow steps (generic) STEP_COMPLETED: "مرحله تکمیل شد", V3_STEP_COMPLETED: "مرحله تکمیل شد", // Documents & media DOCUMENT_UPLOADED: "مدرک بارگذاری شد", VIDEO_CAPTURE_UPLOADED: "تصویر ویدیویی بارگذاری شد", PART_CAPTURED: "تصویر قطعه آسیب‌دیده بارگذاری شد", ANGLE_CAPTURED: "تصویر زاویه خودرو بارگذاری شد", ALL_FACTORS_UPLOADED_PENDING_VALIDATION: "تمام فاکتورها بارگذاری شدند و در انتظار تأیید هستند", // User responses USER_OBJECTION_SUBMITTED: "اعتراض کاربر ثبت شد", USER_RATING_SUBMITTED: "امتیاز کاربر ثبت شد", // Owner insurer approval OWNER_SIGNED_INSURER_APPROVAL: "صاحب خودرو قرارداد بیمه را امضا کرد", OWNER_REJECTED_INSURER_APPROVAL_PRICING: "صاحب خودرو قیمت‌گذاری بیمه را رد کرد", OWNER_SIGNED_PRICED_PARTS_PENDING_FACTOR_UPLOAD: "صاحب خودرو قطعات قیمت‌گذاری‌شده را امضا کرد و در انتظار بارگذاری فاکتور", OWNER_REJECTED_PRICED_PARTS_BEFORE_FACTORS: "صاحب خودرو قطعات قیمت‌گذاری‌شده را پیش از فاکتور رد کرد", // Fanavaran sync FANAVARAN_AUTO_SUBMIT_SUCCEEDED: "ارسال خودکار به فناوران موفق بود", FANAVARAN_AUTO_SUBMIT_FAILED: "ارسال خودکار به فناوران ناموفق بود", FANAVARAN_EARLY_AUTO_SUBMIT_SUCCEEDED: "ارسال زودهنگام خودکار به فناوران موفق بود", FANAVARAN_EARLY_AUTO_SUBMIT_FAILED: "ارسال زودهنگام خودکار به فناوران ناموفق بود", FANAVARAN_EXPERTISE_AUTO_SUBMIT_SUCCEEDED: "ارسال خودکار کارشناسی به فناوران موفق بود", FANAVARAN_EXPERTISE_AUTO_SUBMIT_FAILED: "ارسال خودکار کارشناسی به فناوران ناموفق بود", FANAVARAN_ATTACHMENT_AUTO_SUBMIT_SUCCEEDED: "ارسال خودکار پیوست به فناوران موفق بود", FANAVARAN_ATTACHMENT_AUTO_SUBMIT_FAILED: "ارسال خودکار پیوست به فناوران ناموفق بود", FANAVARAN_DAMAGE_CASE_AUTO_SUBMIT_SUCCEEDED: "ارسال خودکار پرونده خسارت به فناوران موفق بود", FANAVARAN_DAMAGE_CASE_AUTO_SUBMIT_FAILED: "ارسال خودکار پرونده خسارت به فناوران ناموفق بود", // V5 claim V5_HELD_FOR_FILE_MAKER_APPROVAL: "پرونده در انتظار تأیید پرونده‌ساز متوقف شد", }; // --------------------------------------------------------------------------- // Persian labels for `metadata.stepKey` inside STEP_COMPLETED events // --------------------------------------------------------------------------- export const STEP_KEY_FA_LABELS: Record = { // Claim workflow steps 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: "پرونده خسارت تکمیل شد", }; const GENERIC_EVENT_FA_LABEL = "رویداد پرونده"; const GENERIC_EVENT_FA_DESCRIPTION = "رویدادی در روند پرونده ثبت شد."; const SYSTEM_REASON_FA_TRANSLATIONS: Record = { "IN_PERSON expert-initiated: first party is always guilty; confession auto-resolved": "در پرونده حضوری ایجادشده توسط کارشناس، طرف اول همیشه مقصر است؛ بنابراین مرحله اقرار به‌صورت خودکار تعیین تکلیف شد.", "V6 call-center initiated: first party is always guilty; confession auto-resolved": "در پرونده ایجادشده توسط مرکز تماس، طرف اول همیشه مقصر است؛ بنابراین مرحله اقرار به‌صورت خودکار تعیین تکلیف شد.", }; /** * 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 = { 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 * most specific Persian label available. */ export function resolveStepCompletedFaLabel(event: { type: string; metadata?: any; }): string | undefined { if (event.type !== "STEP_COMPLETED" && event.type !== "V3_STEP_COMPLETED") { return undefined; } const stepKey: string | undefined = event.metadata?.stepKey; if (stepKey && STEP_KEY_FA_LABELS[stepKey]) { return STEP_KEY_FA_LABELS[stepKey]; } return "مرحله تکمیل شد"; } /** * Returns the best Persian label for any timeline event. */ export function getEventFaLabel(event: { type: string; metadata?: any; }): string { return ( resolveStepCompletedFaLabel(event) ?? EVENT_TYPE_FA_LABELS[event.type] ?? GENERIC_EVENT_FA_LABEL ); } /** * 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 = resolveStepCompletedFaLabel(event) ?? EVENT_TYPE_FA_LABELS[event.type]; return label ? `${label}.` : GENERIC_EVENT_FA_DESCRIPTION; } /** * Keeps the established metadata contract intact. Only a pre-existing * description field is localized; no keys are added, removed, or renamed. */ export function localizeTimelineMetadata(event: { type: string; metadata?: Record | null; }): Record | null { if (!event.metadata) return null; const reason = event.metadata.reason; const localizedReason = typeof reason === "string" ? SYSTEM_REASON_FA_TRANSLATIONS[reason] : null; return { ...event.metadata, ...(Object.prototype.hasOwnProperty.call(event.metadata, "description") ? { description: getEventFaDescription(event) } : {}), ...(localizedReason ? { reason: localizedReason } : {}), }; }