feat(digests): Phase 2 — API endpoints + /digests UI (X12) #111

Merged
chaim merged 1 commits from worktree-digests-ui into main 2026-06-07 18:11:45 +00:00
Owner

מה ולמה

משטחי-משתמש לקורפוס היומונים (X12, המשך ל-PR #109): endpoints ב-FastAPI + דף UI נפרד /digests לדפדוף, חיפוש, העלאה וקישור לפסק המקורי. היומון נשאר מקור-משני המצביע על הפסק — אינו מצוטט בהחלטה (INV-DIG1) ואינו מחלץ הלכות (INV-DIG2). משימת-אב TaskMaster legal-ai #104 (תתי 8).

Backend — פיצול container-safe ↔ local

צינור הקליטה של היומון משתמש ב-LLM (claude_session local-only, לא בקונטיינר). לכן:

  • digest_library פוצל: create_pending_digest (CONTAINER-SAFE — stage + extract_text(PyMuPDF) + יצירת שורה pending, ללא LLM) ↔ enrich_digest/process_pending_digests (מקומי — LLM + embedding + autolink). ingest_digest (batch) מאחד את השניים.
  • db.list_pending_digests; כלי MCP digest_process_pending (tool+server) — חלופה ל-batch לריקון התור.
  • web/app.py: 10 endpoints /api/digests/*upload (INSERT-only pending), list, search, queue/pending, get, patch, delete, link, relink, unlink. כולם DB/voyage-only (בטוחים בקונטיינר); מחזירים dict בדפוס precedent.

Frontend — Next 16, דף נפרד

  • lib/api/digests.ts — hooks (useDigests/useDigestSearch/useDigestPending/useUploadDigest/useLink/Relink/Unlink/Delete/Update). ללא api:types — טיפוסים hand-written, בדיוק כמו precedent-library.ts (הקונבנציה הקיימת: מודולי-domain כותבים טיפוסים ידנית).
  • דף /digests נפרד (לא כרטיסייה ב-/precedents — לשמור את הגבול סמכותי/משני, INV-DIG1): טאבים יומונים/חיפוש, DigestCard (badge "מקושר לפסק" / "הפסק טרם בקורפוס"), DigestUploadDialog, pending-badge. nav + header-context.

אימות

  • Backend round-trip מלא: create_pending_digestlist_pending_digests (1) → process_pending_digests (completed) → search מדרג נכון → restore. כל 10 ה-endpoints נרשמו ב-OpenAPI (אומת ע"י import של ה-app).
  • Frontend: lint נקי בקבצים החדשים; TypeScript נקי; build מצליח והנתיב /digests נוצר.
  • ⚠️ הערה: next build הדיפולטי (turbopack) נכשל ב-worktree עקב symlink ל-node_modules (מגבלת worktree, לא קוד) — אומת עם --webpack; ב-CI/Docker (node_modules אמיתי) הדיפולטי יעבוד.

Invariants

מקיים — INV-DIG1/2 (upload לא מחלץ הלכות; ה-UI ממסגר "מצביע לא מצוטט"), INV-DIG3 (link/relink/queue), G2 (מסלול נפרד), G4 (אין בליעה — שגיאות→toast/HTTPException), X6 (חוזה UI↔API — endpoints בדפוס precedent; hooks hand-written כשאר מודולי-ה-domain).

פתוח (Phase 3)

אוטומציית Gmail (קליטה יומית מהמייל) + פיצול העלון החודשי 201.

🤖 Generated with Claude Code

## מה ולמה משטחי-משתמש לקורפוס היומונים (X12, המשך ל-PR #109): **endpoints ב-FastAPI** + **דף UI נפרד `/digests`** לדפדוף, חיפוש, העלאה וקישור לפסק המקורי. היומון נשאר **מקור-משני המצביע** על הפסק — אינו מצוטט בהחלטה (INV-DIG1) ואינו מחלץ הלכות (INV-DIG2). משימת-אב TaskMaster `legal-ai` #104 (תתי 8). ## Backend — פיצול container-safe ↔ local צינור הקליטה של היומון משתמש ב-LLM (claude_session **local-only**, לא בקונטיינר). לכן: - `digest_library` פוצל: **`create_pending_digest`** (CONTAINER-SAFE — stage + extract_text(PyMuPDF) + יצירת שורה `pending`, ללא LLM) ↔ **`enrich_digest`/`process_pending_digests`** (מקומי — LLM + embedding + autolink). `ingest_digest` (batch) מאחד את השניים. - `db.list_pending_digests`; כלי MCP **`digest_process_pending`** (tool+server) — חלופה ל-batch לריקון התור. - `web/app.py`: 10 endpoints `/api/digests/*` — `upload` (INSERT-only pending), `list`, `search`, `queue/pending`, `get`, `patch`, `delete`, `link`, `relink`, `unlink`. כולם DB/voyage-only (בטוחים בקונטיינר); מחזירים dict בדפוס precedent. ## Frontend — Next 16, דף נפרד - `lib/api/digests.ts` — hooks (useDigests/useDigestSearch/useDigestPending/useUploadDigest/useLink/Relink/Unlink/Delete/Update). **ללא `api:types`** — טיפוסים hand-written, בדיוק כמו `precedent-library.ts` (הקונבנציה הקיימת: מודולי-domain כותבים טיפוסים ידנית). - דף **`/digests` נפרד** (לא כרטיסייה ב-`/precedents` — לשמור את הגבול סמכותי/משני, INV-DIG1): טאבים יומונים/חיפוש, `DigestCard` (badge "מקושר לפסק" / "הפסק טרם בקורפוס"), `DigestUploadDialog`, pending-badge. nav + header-context. ## אימות - **Backend round-trip מלא:** `create_pending_digest` → `list_pending_digests` (1) → `process_pending_digests` (completed) → `search` מדרג נכון → restore. כל 10 ה-endpoints נרשמו ב-OpenAPI (אומת ע"י import של ה-app). - **Frontend:** lint נקי בקבצים החדשים; TypeScript נקי; build מצליח והנתיב `/digests` נוצר. - ⚠️ הערה: `next build` הדיפולטי (turbopack) נכשל ב-worktree עקב symlink ל-node_modules (מגבלת worktree, לא קוד) — אומת עם `--webpack`; ב-CI/Docker (node_modules אמיתי) הדיפולטי יעבוד. ## Invariants **מקיים** — INV-DIG1/2 (upload לא מחלץ הלכות; ה-UI ממסגר "מצביע לא מצוטט"), INV-DIG3 (link/relink/queue), **G2** (מסלול נפרד), **G4** (אין בליעה — שגיאות→toast/HTTPException), **X6** (חוזה UI↔API — endpoints בדפוס precedent; hooks hand-written כשאר מודולי-ה-domain). ## פתוח (Phase 3) אוטומציית Gmail (קליטה יומית מהמייל) + פיצול העלון החודשי `201`. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
chaim added 1 commit 2026-06-07 18:11:36 +00:00
משטחי-משתמש לקורפוס היומונים: endpoints ב-FastAPI + דף UI נפרד /digests
(לדפדוף, חיפוש, העלאה, וקישור לפסק המקורי). היומון נשאר מקור-משני המצביע
על הפסק — אינו מצוטט בהחלטה (INV-DIG1) ואינו מחלץ הלכות (INV-DIG2).

Backend (container-safe + local split):
- digest_library: פוצל ל-create_pending_digest (CONTAINER-SAFE: stage+
  extract_text+create row 'pending', בלי LLM) ↔ enrich_digest/
  process_pending_digests (local: LLM+embed+autolink). ingest_digest מאחד.
- db.list_pending_digests; MCP digest_process_pending (tool+server) — חלופה
  ל-batch script לריקון התור.
- web/app.py: 10 endpoints /api/digests/* (upload/list/search/queue-pending/
  get/patch/delete/link/relink/unlink). upload=INSERT-only pending (ה-LLM רץ
  מקומית — claude_session local-only). כולם מחזירים dict בדפוס precedent.

Frontend (Next 16, ללא api:types — hooks עם טיפוסים hand-written כמו
precedent-library.ts):
- lib/api/digests.ts — hooks (useDigests/useDigestSearch/useDigestPending/
  useUploadDigest/useLink/Relink/Unlink/Delete/Update).
- דף /digests נפרד (לא כרטיסייה ב-/precedents — לשמור גבול סמכותי/משני,
  INV-DIG1): טאבים יומונים/חיפוש + DigestCard (badge קישור-לפסק) +
  DigestUploadDialog + pending badge. nav + header-context.

אומת: backend round-trip מלא (create_pending→list_pending→process_pending→
search→restore); web-ui מתקמפל (webpack/tsc נקי, route /digests נוצר).
הערה: build דיפולטי (turbopack) נכשל ב-worktree עקב symlink ל-node_modules —
ב-CI/Docker (node_modules אמיתי) עובד; אומת עם --webpack.

Invariants: מקיים INV-DIG1/2 (upload לא מחלץ הלכות, UI מציג "מצביע לא
מצוטט"), INV-DIG3 (link/relink/queue). G4 (אין בליעה — שגיאות→toast/HTTP),
G2 (מסלול נפרד, לא מקביל). X6 (חוזה UI↔API — endpoints בדפוס precedent;
hooks hand-written כמו שאר ה-domain modules).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
chaim merged commit 692eea76f0 into main 2026-06-07 18:11:45 +00:00
chaim deleted branch worktree-digests-ui 2026-06-07 18:11:45 +00:00
Sign in to join this conversation.
No Reviewers
No Label
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: ezer-mishpati/legal-ai#111