/** * Single source of truth for the case-status lifecycle (UI-B1 / G2). * * The 17-status manual menu was trimmed to the **10 core statuses** that the * pipeline actually sets or that gate real logic. Decorative mid-stage markers * (uploading, analyst_verified, research_complete, brainstorming, * analysis_enriched, ready_for_writing, drafting) plus the legacy/dead * `in_progress` and `qa_failed` were removed — no pipeline code ever set them. * * Every status consumer (badge, changer, timeline, guide, donut, KPI cards, * compose chip) imports the list / labels / phases from here instead of * re-declaring its own array. Keep this file in sync with the backend * STATUS_ORDER in `mcp-server/src/legal_mcp/tools/cases.py`. */ /** Ordered lifecycle — also the order shown in the manual status dropdown. */ export const CASE_STATUSES = [ "new", "processing", "documents_ready", "outcome_set", "direction_approved", "qa_review", "drafted", "exported", "reviewed", "final", ] as const; export type CaseStatus = (typeof CASE_STATUSES)[number]; export type PhaseKey = "intake" | "prep" | "thinking" | "writing" | "done"; /** The 5 visual phases the lifecycle collapses into across the app. */ export const PHASES: { key: PhaseKey; label: string; statuses: CaseStatus[] }[] = [ { key: "intake", label: "קליטה ועיבוד", statuses: ["new", "processing"] }, { key: "prep", label: "הכנת תיק", statuses: ["documents_ready"] }, { key: "thinking", label: "ניתוח וכיוון", statuses: ["outcome_set", "direction_approved"] }, { key: "writing", label: "כתיבת טיוטה", statuses: ["qa_review", "drafted"] }, { key: "done", label: "סגירה", statuses: ["exported", "reviewed", "final"] }, ]; /** Which phase a status belongs to (undefined for unknown/legacy values). */ export function phaseOf(status?: CaseStatus | string): PhaseKey | undefined { if (!status) return undefined; return PHASES.find((p) => (p.statuses as string[]).includes(status))?.key; } export const STATUS_LABELS: Record = { new: "חדש", processing: "בעיבוד", documents_ready: "מסמכים מוכנים", outcome_set: "תוצאה נקבעה", direction_approved: "כיוון אושר", qa_review: "בדיקת איכות", drafted: "טיוטה", exported: "יוצא", reviewed: "נבדק", final: "סופי", }; /** * Hebrew labels for the removed/legacy statuses — display-only fallback so a * row that hasn't been migrated yet (or arrives from an old client) never * renders a raw English slug as a label. These are NOT selectable statuses. */ const LEGACY_STATUS_LABELS: Record = { in_progress: "בעבודה", uploading: "מעלה", analyst_verified: "ניתוח אומת", research_complete: "מחקר הושלם", brainstorming: "סיעור מוחות", analysis_enriched: "ניתוח הועמק", ready_for_writing: "מוכן לכתיבה", drafting: "בכתיבה", qa_failed: "בדיקת איכות נכשלה", qa_passed: "טיוטה", }; /** * Always-Hebrew label for any status string. Use this everywhere a status is * rendered as a label so an unknown/legacy value never leaks an English slug. */ export function statusLabel(status?: string): string { if (!status) return ""; return ( STATUS_LABELS[status as CaseStatus] ?? LEGACY_STATUS_LABELS[status] ?? "לא ידוע" ); } export const STATUS_DESCRIPTIONS: Record = { new: "התיק נוצר וממתין להעלאת מסמכים", processing: "המערכת מעבדת ומנתחת את המסמכים", documents_ready: "כל המסמכים עובדו ומוכנים לעבודה", outcome_set: "נקבעה תוצאה צפויה לערר", direction_approved: "כיוון ההחלטה אושר — בהעמקת ניתוח וכתיבה", qa_review: "הטיוטה בבדיקת איכות אוטומטית", drafted: "טיוטה מוכנה לעיון", exported: "ההחלטה יוצאה לקובץ DOCX", reviewed: 'ההחלטה נבדקה ע"י היו"ר', final: "החלטה סופית — מוכנה להגשה", };