feat(generate): סימון-סטטוס לריצת-הרקע של "הפקת מסמכים" (#227 ג)
עד כה ה-"מייצר…" כיסה רק את שנייה-ה-POST; אחרי זה לא היה חיווי אם ההפקה
רצה/הצליחה/נכשלה — ריצה שבוטלה נראתה כמו הצלחה. עכשיו צ'יפ-סטטוס ליד כל
כפתור-הפקה: בתור · רץ+שעון-חי · הושלם+מתי · נכשל+סיבה+"נסה שוב".
**נשמר-שרת (דרישת חיים):** הסטטוס נגזר בשרת מ-issue-הילד של ה-CEO +
ה-heartbeat_run האחרון + קיום-הקובץ — לא מזיכרון-הדף. שעון-הריצה מעוגן
ל-started_at של השרת, כך שעזיבה+חזרה לדף מציגות את המצב והזמן הנכונים,
בלי צורך להישאר בדף.
Backend:
- paperclip_client.get_generation_run_status — קורא issue-ילד + latest run
מ-Paperclip DB (read-only, מאחורי שער-הפלטפורמה G12); dedup לפי כותרת.
- GET /api/cases/{n}/generate/{action}/status — ממפה ל-idle/queued/running/
done/failed + output_ready + started_at/finished_at (UTC). run שהסתיים בלי
קובץ = failed (שלא ייראה כהצלחה).
Frontend:
- useGenerateStatus (poll 5s רק כשפעיל; עוצר בטרמינלי) + GenerateStatusChip
(שעון-ריצה חי מ-started_at; רכיב חסר-מצב). כפתורי-ההפקה מרעננים את
שאילתת-הסטטוס ב-onSuccess. שורה 3 (החלטה מלאה, סינכרוני) — בלי צ'יפ.
עיצוב: מוקאפ 29-generate-status-indicator אושר ע"י חיים דרך שער Claude Design (X17).
tsc + eslint + py_compile ירוקים. (api:types לריענון post-deploy.)
Invariants: G12 (Paperclip רק בשער), G1.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -31,7 +31,9 @@ import {
|
||||
usePartyClaimsSummary,
|
||||
useGeneratePartyClaimsSummary,
|
||||
useGenerateInterimDraft,
|
||||
useGenerateStatus,
|
||||
} from "@/lib/api/generate";
|
||||
import { GenerateStatusChip } from "@/components/cases/generate-status-chip";
|
||||
import {
|
||||
useCaseFeedback,
|
||||
useCreateFeedback,
|
||||
@@ -133,6 +135,9 @@ export function DraftsPanel({
|
||||
const { data: summary } = usePartyClaimsSummary(caseNumber);
|
||||
const genSummary = useGeneratePartyClaimsSummary(caseNumber);
|
||||
const genInterim = useGenerateInterimDraft(caseNumber);
|
||||
// Server-derived background-run status (#227 ג) — survives navigation/reload.
|
||||
const summaryStatus = useGenerateStatus(caseNumber, "party_claims_summary");
|
||||
const interimStatus = useGenerateStatus(caseNumber, "interim_draft");
|
||||
const qc = useQueryClient();
|
||||
|
||||
const fileRef = useRef<HTMLInputElement>(null);
|
||||
@@ -342,6 +347,11 @@ export function DraftsPanel({
|
||||
"הפק"
|
||||
)}
|
||||
</Button>
|
||||
<GenerateStatusChip
|
||||
status={summaryStatus.data}
|
||||
onRetry={handleGenerateSummary}
|
||||
retrying={genSummary.isPending}
|
||||
/>
|
||||
{summaryReady && (
|
||||
<>
|
||||
<Button
|
||||
@@ -410,6 +420,11 @@ export function DraftsPanel({
|
||||
"הפק"
|
||||
)}
|
||||
</Button>
|
||||
<GenerateStatusChip
|
||||
status={interimStatus.data}
|
||||
onRetry={handleGenerateInterim}
|
||||
retrying={genInterim.isPending}
|
||||
/>
|
||||
{latestInterim && (
|
||||
<span className="text-[0.7rem] text-ink-muted">
|
||||
{latestInterim.version
|
||||
|
||||
Reference in New Issue
Block a user