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,6 +1,6 @@
|
||||
"use client";
|
||||
|
||||
import type { CaseStatus } from "@/lib/api/cases";
|
||||
import { PHASES, type CaseStatus, type PhaseKey } from "@/lib/api/case-status";
|
||||
import { STATUS_LABELS, STATUS_ICONS, STATUS_DESCRIPTIONS } from "@/components/cases/status-badge";
|
||||
import {
|
||||
FolderInput, ClipboardList, Brain, PenLine, CheckCircle2,
|
||||
@@ -8,27 +8,19 @@ import {
|
||||
import type { LucideIcon } from "lucide-react";
|
||||
|
||||
/*
|
||||
* Vertical RTL workflow timeline showing the 13-status case pipeline.
|
||||
* Groups the raw statuses into the 5 visual phases used across the app
|
||||
* (intake → prep → thinking → writing → done) so the user sees
|
||||
* "where am I in the process" rather than 13 micro-steps.
|
||||
* Vertical RTL workflow timeline. Phases + their statuses come from the SSoT
|
||||
* (@/lib/api/case-status); only the per-phase icon is a view-layer concern and
|
||||
* stays here. The user sees "where am I in the process" rather than micro-steps.
|
||||
*/
|
||||
|
||||
type Phase = {
|
||||
key: string;
|
||||
label: string;
|
||||
icon: LucideIcon;
|
||||
statuses: CaseStatus[];
|
||||
const PHASE_ICONS: Record<PhaseKey, LucideIcon> = {
|
||||
intake: FolderInput,
|
||||
prep: ClipboardList,
|
||||
thinking: Brain,
|
||||
writing: PenLine,
|
||||
done: CheckCircle2,
|
||||
};
|
||||
|
||||
const PHASES: Phase[] = [
|
||||
{ key: "intake", label: "קליטה ועיבוד", icon: FolderInput, statuses: ["new", "uploading", "processing"] },
|
||||
{ key: "prep", label: "הכנת תיק", icon: ClipboardList, statuses: ["documents_ready", "analyst_verified", "research_complete", "outcome_set"] },
|
||||
{ key: "thinking", label: "ניתוח וכיוון", icon: Brain, statuses: ["brainstorming", "direction_approved", "analysis_enriched", "ready_for_writing"] },
|
||||
{ key: "writing", label: "כתיבת טיוטה", icon: PenLine, statuses: ["drafting", "qa_review", "drafted"] },
|
||||
{ key: "done", label: "סגירה", icon: CheckCircle2, statuses: ["exported", "reviewed", "final"] },
|
||||
];
|
||||
|
||||
function phaseIndexOf(status?: CaseStatus): number {
|
||||
if (!status) return -1;
|
||||
return PHASES.findIndex((p) => p.statuses.includes(status));
|
||||
@@ -61,7 +53,7 @@ export function WorkflowTimeline({ status }: { status?: CaseStatus }) {
|
||||
: state === "current" ? "text-gold-deep"
|
||||
: "text-ink-muted/50";
|
||||
|
||||
const PhaseIcon = phase.icon;
|
||||
const PhaseIcon = PHASE_ICONS[phase.key];
|
||||
const isLast = i === PHASES.length - 1;
|
||||
|
||||
return (
|
||||
|
||||
Reference in New Issue
Block a user