refactor(cases): צמצום תפריט-סטטוס 17→10 + מקור-אמת יחיד (UI-B1/G2)
תפריט הסטטוס-הידני הכיל 17 סטטוסים שמתוכם ~9 דקורציה טהורה — שלבי-ביניים שאף קוד בפייפליין לא קבע ושום לוגיקה לא הסתעפה לפיהם, עם רשימות כפולות לא-עקביות ב-6+ קבצים (UI-B1) ו-exported כסטטוס-רפאים (באג agent-audit). הליבה (10): new, processing, documents_ready, outcome_set, direction_approved, qa_review, drafted, exported, reviewed, final. - SSoT חדש web-ui/src/lib/api/case-status.ts (רשימה/שלבים/תוויות/statusLabel); כל הצרכנים (badge/changer/timeline/guide/donut/kpi/compose) מייבאים משם. - statusLabel() מבטיח תווית עברית תמיד — גם לערך-מורשת (נפילה עברית, לא סלאג). - בקאנד: STATUS_ORDER 10, models.CaseStatus מיושר, set_outcome קובע outcome_set/direction_approved (במקום in_progress) כמו endpoint ה-web. - exported מוקשח אחרי export-DOCX מוצלח (forward-only); widget "נכשל ב-QA" עודכן ל-qa_review (הסטטוס שנקבע בפועל בכשל-QA). - scripts/backfill_case_status_trim.py: מיפוי שורות-מורשת לסטטוס-הליבה הקודם. Invariants: UI-B1 (מקור-אמת יחיד) ✅ · G2 (אין מסלול מקביל) ✅ · GAP-42 (חלקי). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,23 +1,16 @@
|
||||
"use client";
|
||||
|
||||
import type { Case, CaseStatus } from "@/lib/api/cases";
|
||||
import type { Case } from "@/lib/api/cases";
|
||||
import { phaseOf, type PhaseKey } from "@/lib/api/case-status";
|
||||
import { STATUS_LABELS } from "@/components/cases/status-badge";
|
||||
|
||||
/*
|
||||
* Conic-gradient donut — ported from legal-ai/web/static/index.html renderHero().
|
||||
* Kept deliberately dependency-free (no D3/recharts) — a single background-image.
|
||||
* Five status groups map onto the navy/gold/info/warn/success palette.
|
||||
* Five status groups (= the SSoT phases) map onto navy/gold/info/warn/success.
|
||||
*/
|
||||
|
||||
type GroupKey = "intake" | "prep" | "thinking" | "writing" | "done";
|
||||
|
||||
const GROUP_OF: Record<CaseStatus, GroupKey> = {
|
||||
new: "intake", in_progress: "intake", uploading: "intake", processing: "intake",
|
||||
documents_ready: "prep", analyst_verified: "prep", research_complete: "prep", outcome_set: "prep",
|
||||
brainstorming: "thinking", direction_approved: "thinking", analysis_enriched: "thinking", ready_for_writing: "thinking",
|
||||
drafting: "writing", qa_review: "writing", qa_failed: "writing", drafted: "writing",
|
||||
exported: "done", reviewed: "done", final: "done",
|
||||
};
|
||||
type GroupKey = PhaseKey;
|
||||
|
||||
const GROUP_META: Record<GroupKey, { label: string; color: string }> = {
|
||||
intake: { label: "חדש / בעיבוד", color: "var(--color-ink-muted)" },
|
||||
@@ -32,7 +25,7 @@ export function StatusDonut({ cases }: { cases?: Case[] }) {
|
||||
intake: 0, prep: 0, thinking: 0, writing: 0, done: 0,
|
||||
};
|
||||
(cases ?? []).forEach((c) => {
|
||||
const g = GROUP_OF[c.status];
|
||||
const g = phaseOf(c.status);
|
||||
if (g) counts[g] += 1;
|
||||
});
|
||||
const total = Object.values(counts).reduce((a, b) => a + b, 0);
|
||||
|
||||
Reference in New Issue
Block a user