From e068a611e7fb59516eccf6c655dd1e19c574d08f Mon Sep 17 00:00:00 2001 From: Chaim Date: Thu, 16 Apr 2026 19:10:11 +0000 Subject: [PATCH] =?UTF-8?q?Rewrite=20architecture.md=20=E2=80=94=20add=20T?= =?UTF-8?q?rack=20Changes=20edit=20flow=20+=208=20stages?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The old architecture.md was out of date (mentioned n8n which isn't used, wrong embedding dimensions, missing multi-tenancy, no edit loop). The rewrite documents the full process end-to-end: 1. Document upload + OCR + embedding 2. Analysis (proofreader, researcher) 3. Outcome + direction decision (CEO + human) 4. Deep analysis (pass 2) 5. Drafting (writer writes 12 blocks) 6. QA 7. Initial DOCX export (with bookmarks for future revisions) 8. Edit loop with Track Changes — the new architecture: a. User downloads + edits in Word + uploads עריכה-v{N}.docx b. Backend auto-retrofits bookmarks + registers as active_draft c. User asks CEO for specific change in Paperclip comment d. CEO stage G: calls writer in revision mode → builds revisions JSON e. docx_reviser applies / preserving user's template f. User Accept/Reject from Word Review tab g. Repeat until marked final Plus MCP tool reference, API endpoints, DB schema, multi-tenancy, technology stack. Co-Authored-By: Claude Opus 4.7 (1M context) --- docs/architecture.md | 343 +++++++++++++++++++++++++++++++++++-------- 1 file changed, 283 insertions(+), 60 deletions(-) diff --git a/docs/architecture.md b/docs/architecture.md index 0c65af2..d74bb8a 100644 --- a/docs/architecture.md +++ b/docs/architecture.md @@ -1,82 +1,305 @@ # System Architecture — Legal Decision Assistant -## Components +> עודכן: 2026-04-16 — הוספת ארכיטקטורת Track Changes לעריכת טיוטות + +## רכיבי המערכת ``` -┌─────────────────────────────────────────────────────┐ -│ Nautilus Server │ -│ 158.178.131.193 │ -│ │ -│ ┌──────────┐ ┌──────────┐ ┌──────────────────┐ │ -│ │ Coolify │ │ Traefik │ │ ezer-mishpati-web│ │ -│ │ (manage) │ │ (proxy) │ │ (upload UI) │ │ -│ └──────────┘ └──────────┘ └──────────────────┘ │ -│ │ -│ ┌──────────────────┐ ┌──────────────────────────┐ │ -│ │ PostgreSQL │ │ Redis │ │ -│ │ + pgvector │ │ (task queue) │ │ -│ │ (legal-ai-postgres│ │ (legal-ai-redis) │ │ -│ └──────────────────┘ └──────────────────────────┘ │ -│ │ -│ ┌──────────┐ ┌──────────┐ │ -│ │ Gitea │ │ n8n │ │ -│ │ (code) │ │ (automate│ │ -│ └──────────┘ └──────────┘ │ -│ │ -│ ┌──────────────────────────────────────────────┐ │ -│ │ Claude Code (via SSH or API) │ │ -│ │ — Skills: legal-decision, legal-docx │ │ -│ │ — MCP: postgres, n8n, cloudflare, chrome │ │ -│ └──────────────────────────────────────────────┘ │ -└─────────────────────────────────────────────────────┘ +┌───────────────────────────────────────────────────────────────┐ +│ Nautilus Server │ +│ 158.178.131.193 │ +│ │ +│ ┌──────────────────────────────────────────────────────┐ │ +│ │ legal-ai container (Coolify UUID: gyjo0mtw2c42ej3...) │ │ +│ │ ┌────────────┐ ┌──────────────────────────┐ │ │ +│ │ │ Next.js UI │ │ FastAPI backend │ │ │ +│ │ │ :3000 │◄──►│ :8000 (internal) │ │ │ +│ │ └────────────┘ │ + MCP server │ │ │ +│ │ └──────────────────────────┘ │ │ +│ └──────────────────────────────────────────────────────┘ │ +│ │ +│ ┌──────────────────┐ ┌──────────────────────────┐ │ +│ │ PostgreSQL + │ │ Redis │ │ +│ │ pgvector (1024D) │ │ (task queue) │ │ +│ │ legal-ai-postgres│ │ legal-ai-redis │ │ +│ └──────────────────┘ └──────────────────────────┘ │ +│ │ +│ ┌──────────────┐ ┌──────────────────────────┐ │ +│ │ Gitea │ │ Traefik (SSL + routing) │ │ +│ │ (code + cases)│ │ (*.nautilus.marcusgroup) │ │ +│ └──────────────┘ └──────────────────────────┘ │ +└───────────────────────────────────────────────────────────────┘ + +Local (developer machine, pm2): +┌──────────────────────────────────────────────────────────────┐ +│ Paperclip — agent orchestrator │ +│ localhost:3100, DB localhost:54329 │ +│ Runs Claude Code agents: legal-ceo, legal-writer, │ +│ legal-exporter, legal-researcher, legal-qa, legal-proofreader│ +└──────────────────────────────────────────────────────────────┘ External: - ← Claude API (embeddings, analysis) - ← Cloudflare DNS (*.nautilus.marcusgroup.org) - ← User (Putty SSH / Browser) + ← Claude API (Opus 4.7 for agents) + ← Voyage AI (voyage-3-large, 1024-dim embeddings) + ← Infisical (secret management) + ← Gmail SMTP (agent notifications) ``` -## Data Flow +--- -``` -1. Document Upload - User → ezer-mishpati-web → file storage → n8n trigger - → classify document → store metadata in PostgreSQL - → generate embeddings → store in pgvector +## הזרימה המלאה — מהעלאת מסמכים ועד טיוטה סופית -2. Decision Writing - Claude Code → read source materials from DB - → generate structure DOCX (12 blocks) - → write each block with appropriate model/parameters - → validate against block-schema - → export final DOCX +### שלב 1 — יצירת תיק + העלאת מסמכי מקור -3. Precedent Search (RAG) - Query → generate embedding → pgvector similarity search - → return relevant paragraphs/decisions - → Claude analyzes relevance → present to user -``` +**מה קורה:** +1. חיים יוצר תיק דרך UI (`/cases/new`) — מקבל `case_number` (1xxx = CMP, 8xxx/9xxx = CMPA) +2. מעלה PDFs/DOCX: כתב ערר, תשובה, פרוטוקול, תכניות, היתר, פסיקה +3. ה-backend: + - שומר קובץ ב-`data/cases/{case_number}/documents/originals/` + - מפעיל OCR (Google Vision) אם PDF ללא טקסט + - מריץ proofreader להסרת artifacts מ-Nevo + - מחלץ טקסט ל-`documents.extracted_text` + - מפצל ל-chunks של ~500 מילים, מחשב embeddings (voyage-3-large, 1024D), שומר ב-`document_chunks` +4. סטטוס תיק: `new` → `proofread` -## Database Schema — 4 Layers +### שלב 2 — ניתוח משפטי (legal-researcher + analyst) + +**מי רץ:** סוכני Paperclip (מתוזמרים ע"י legal-ceo). + +1. **legal-proofreader** — מנקה את המסמכים אחרי OCR +2. **legal-researcher** — מפה תכניות, תקדימים, חקיקה רלוונטית. שומר `research_md` +3. **analyst (legal-researcher pass 1)** — מחלץ טענות (`extract_claims`), ממפה סוגיות, בודק שלמות + +סטטוס: `proofread` → `documents_ready` → `analyst_verified` + +### שלב 3 — החלטת תוצאה + כיוונים (CEO + חיים) + +1. **legal-ceo** מציג סיכום לחיים: סיווג, טענות, פסיקה רלוונטית, שאלות מפתח +2. חיים בוחר תוצאה (דחייה/קבלה חלקית/קבלה מלאה) +3. CEO מציג 2-3 **כיוונים סילוגיסטיים** לנימוק +4. חיים מאשר כיוון + +סטטוס: `analyst_verified` → `outcome_set` → `direction_approved` + +### שלב 4 — ניתוח מעמיק (analyst pass 2) + +legal-researcher (תפקיד analyst) מעמיק בפסיקה ובחקיקה על בסיס הכיוון שאושר, מאמת ציטוטים מדויקים. + +סטטוס: `direction_approved` → `analysis_enriched` + +### שלב 5 — כתיבת טיוטה (legal-writer) + +1. CEO יוצר issue לכותב עם **כל ההקשר**: תוצאה, סוגיות, מבנה סילוגיסטי, מסמכי מקור, תקדימים +2. legal-writer כותב בלוק-אחרי-בלוק (12 בלוקים: א-יב) בסגנון דפנה +3. כל בלוק נשמר ב-DB (`decision_blocks.content`) + +סטטוס: `ready_for_writing` → `drafted` + +### שלב 6 — QA + +legal-qa מריץ 6 בדיקות איכות: +- שלמות (כל 12 הבלוקים מלאים) +- ניטרליות (בלוק ו אין ציטוטים מצדדים) +- אין כפילות (בלוק י מפנה, לא חוזר) +- מספור רציף +- פסיקה מצוטטת במדויק +- תואם `chair_directions` של דפנה + +אם עובר → `qa_passed`. אם נכשל → `qa_failed` + issue תיקון לכותב. + +### שלב 7 — ייצוא טיוטה ראשונית (legal-exporter) + +**מה עשה עד עכשיו:** בונה DOCX מאפס מבלוקים ב-DB. + +**מה חדש (2026-04):** הייצוא מזריק **bookmarks** בתחילת וסיום כל בלוק — אנקורים לעריכות עתידיות: +- `` ... `` +- כך עד `block-yod-bet` + +הקובץ: `data/cases/{case_number}/exports/טיוטה-v1.docx` (גופן David, RTL, גודל ~43KB) + +**חשוב:** הטיוטה הזו נרשמת ב-`cases.active_draft_path` = **המקור הרשמי של התיק**. + +סטטוס: `qa_passed` → `exported` + +--- + +## שלב 8 — לולאת עריכה מול דפנה (החלק החדש) + +> זה הלב של ארכיטקטורת Track Changes שנוספה ב-2026-04. + +### 8א. חיים מוריד + עורך + מעלה + +1. חיים מוריד `טיוטה-v1.docx` מה-UI +2. פותח ב-Word (שולחן עבודה או Word Online) +3. עורך ידנית: תיקוני ניסוח, עיצוב, תוספות של תוכן שהמערכת לא ידעה עליו +4. שומר מחדש בשם שמתחיל ב-`עריכה-` +5. מעלה חזרה דרך ה-UI (`/cases/{case}` → "העלה גרסה מתוקנת") + +### 8ב. Backend קולט — אוטומטית + +ה-endpoint `POST /api/cases/{case}/exports/upload` ([web/app.py:1991](web/app.py#L1991)) עושה שלושה דברים: + +1. **שומר את הקובץ** כ-`עריכה-v{N}.docx` (כאשר N = הגרסה הבאה) +2. **מריץ retrofit** דרך `apply_user_edit` ב-MCP: + - פותח את ה-DOCX, מזהה גבולות בלוקים לפי heuristic דו-שכבתי: + - א) מרקרים עבריים בתחילת פסקה: `א.`, `ב.`, ..., `יב.` + - ב) כותרות סגנון דפנה: "רקע", "תמצית טענות", "דיון והכרעה", "סוף דבר", וכו' + - מזריק `` / `` חסרים +3. **מעדכן את DB**: `cases.active_draft_path = '/data/cases/{case}/exports/עריכה-v{N}.docx'` + +התגובה ל-UI כוללת `bookmarks_added`, `missing_blocks`, `apply_status` — ה-UI מציג toast: +- ✓ "הועלה: עריכה-v2.docx — זוהו N בלוקים" +- ⚠ "M בלוקים לא זוהו — ייתכנו בעיות בתיקונים עתידיים" + +### 8ג. חיים מבקש תיקון ספציפי מ-CEO + +חיים כותב ב-Paperclip comment ל-CEO של החברה: + +> "העליתי טיוטה ערוכה. בבקשה הוסף פסק הלכה של בג"ץ 1234/21 בבלוק י' (דיון), ותקן את הניסוח של סוף דבר." + +### 8ד. CEO מתזמר — שלב G + +[.claude/agents/legal-ceo.md — שלב G](.claude/agents/legal-ceo.md) מפעיל: + +1. `list_bookmarks(case_number)` — מקבל את רשימת האנקורים הזמינים +2. אם הבקשה דורשת ניסוח חדש → מפעיל legal-writer במצב **revision** + - writer מקבל `block_id` + `bookmark_anchor` + הוראת ניסוח + - מחזיר טקסט נקי בסגנון דפנה + - **לא שומר ב-DB** (ה-revision חי בקובץ) +3. בונה JSON array של revisions: + ```json + [{ + "id": "r1", + "type": "insert_after", + "anchor_bookmark": "block-yod", + "content": "<הטקסט שהכותב ניסח>", + "style": "body", + "reason": "הוספת פסק הלכה לפי בקשת חיים" + }] + ``` +4. קורא ל-`revise_draft(case_number, revisions)` + +### 8ה. docx_reviser מבצע XML surgery + +[mcp-server/src/legal_mcp/services/docx_reviser.py](mcp-server/src/legal_mcp/services/docx_reviser.py): + +1. פותח את `עריכה-v{N}.docx` כ-ZIP + טוען `word/document.xml` עם lxml +2. מוסיף `` ב-`word/settings.xml` (אם חסר) +3. לכל revision: + - מאתר את ה-bookmark בעץ + - בונה פסקה חדשה עם RTL + David + המילה "מערכת AI" כמחבר + - עוטף את ה-runs החדשים ב-`` + - שומר IDs ייחודיים (סורק max קיים) +4. שומר כ-`טיוטה-v{N+1}.docx` — **הקובץ החדש שומר על כל העיצוב המקורי של המשתמש** (הטמפלט, הפונטים, הטבלאות, הכל) +5. מעדכן `cases.active_draft_path` לקובץ החדש + +### 8ו. חיים מקבל + מאשר/דוחה + +1. UI מציג: "טיוטה v{N+1} (מתוקנת) מוכנה לעיון" +2. חיים מוריד, פותח ב-Word +3. ה-Track Changes מופעל — השינויים מסומנים בצבע, סרגל Review פעיל +4. חיים לוחץ Accept על כל שינוי שהוא מסכים איתו, Reject על מה שלא +5. אם יש עוד שינויים שהוא רוצה לבקש — חוזר לשלב 8א (שומר, מעלה `עריכה-v{N+2}.docx`, מבקש עוד שינוי) + +### 8ז. סיום — `final` + +כשחיים מרוצה, הוא מסמן בייוויי "סמן כסופי" ב-UI → הקובץ מועתק ל-`סופי-{case}.docx` + ל-`data/training/` ללמידה עתידית של דפוסי סגנון. + +סטטוס: `exported` → `final` + +--- + +## סכמת DB — 4 שכבות ### Layer 1: Core -appeals, parties, panels, documents +`cases`, `documents`, `document_chunks` + +**חדש (2026-04):** `cases.active_draft_path TEXT` — הנתיב המלא ל-DOCX שהוא מקור האמת הנוכחי של התיק. null עד לייצוא הראשון. ### Layer 2: Decision -decisions, decision_blocks, decision_paragraphs, claims +`decisions`, `decision_blocks`, `decision_paragraphs`, `claims` ### Layer 3: Legal Knowledge -case_law, case_law_citations, statutory_provisions, transition_phrases, lessons_learned +`case_law`, `statutory_provisions`, `transition_phrases`, `lessons_learned`, `style_corpus`, `style_patterns` ### Layer 4: Semantic Search (RAG) -document_embeddings, paragraph_embeddings, case_law_embeddings -(all using pgvector vector(1536) columns) +`document_embeddings`, `paragraph_embeddings`, `case_law_embeddings` (pgvector 1024-dim, voyage-3-large) + +### Layer 5 — Multi-tenancy +`companies`, `tag_company_mappings` (appeal_subtype → company_id) + +--- + +## רב-חברתיות (CMP + CMPA) + +**חברות:** +- CMP (`42a7acd0-30c5-4cbd-ac97-7424f65df294`) — תיקי 1xxx (רישוי ובניה) +- CMPA (`8639e837-4c9d-47fa-a76b-95788d651896`) — תיקי 8xxx/9xxx (היטלי השבחה, פיצויים ס' 197) + +**מה משותף לשתי החברות:** +- DB יחיד, backend יחיד, frontend יחיד +- כל הקוד + agents — פועלים לפי `$PAPERCLIP_COMPANY_ID` בזמן ריצה +- ארכיטקטורת Track Changes (docx_reviser, docx_retrofit, apply_user_edit, revise_draft) + +**מה כפול לכל חברה:** +- Paperclip skills (`/home/chaim/.paperclip/instances/default/skills/{company_uuid}/`) +- ניתוח סגנון נפרד (`style_patterns` filtered by appeal_subtype) +- CEO agent משלה (CMP: `752cebdd...`, CMPA: `cdbfa8bc...`) + +**סקריפט סנכרון:** [scripts/deploy-track-changes.sh](scripts/deploy-track-changes.sh) — מעתיק skills מ-CMP ל-CMPA. + +--- + +## MCP Tools (חלקי — הרלוונטיים לטיוטות) + +| Tool | מה עושה | +|------|----------| +| `export_docx(case)` | ייצוא טיוטה ראשונית מה-DB, עם bookmarks. מעדכן `active_draft_path`. | +| `apply_user_edit(case, filename)` | רישום `עריכה-*.docx` כ-active_draft + הזרקת bookmarks. | +| `list_bookmarks(case)` | רשימת אנקורים זמינים ב-active_draft. | +| `revise_draft(case, revisions_json)` | החלת Track Changes על active_draft → יוצר `טיוטה-v{N+1}.docx`. | +| `write_block`, `save_block_content` | כתיבה/שמירה של בלוקים ב-DB (לשלב הכתיבה הראשוני). | +| `validate_decision` | 6 בדיקות QA. | + +--- + +## API Endpoints (הרלוונטיים לטיוטות) + +| Endpoint | שימוש | +|----------|--------| +| `POST /api/cases/{case}/export-docx` | ייצוא טיוטה מה-DB | +| `GET /api/cases/{case}/exports` | רשימת טיוטות + עריכות קיימות | +| `GET /api/cases/{case}/exports/{filename}/download` | הורדת קובץ | +| `POST /api/cases/{case}/exports/upload` | **העלאת עריכה → auto-retrofit + register כ-active_draft** | +| `DELETE /api/cases/{case}/exports/{filename}` | מחיקה | +| `POST /api/cases/{case}/exports/{filename}/mark-final` | סימון כסופי | +| `POST /api/cases/{case}/exports/revise` | החלת revisions (Track Changes) | +| `GET /api/cases/{case}/exports/bookmarks` | רשימת bookmarks ב-active_draft | +| `POST /api/cases/{case}/exports/{filename}/retrofit` | ריצת retrofit ידנית (לקבצים ישנים) | +| `GET /api/cases/{case}/active-draft` | סטטוס active_draft (path + exists) | + +--- + +## טכנולוגיות עיקריות -## Technology Choices - **Database**: PostgreSQL 15 + pgvector 0.8.1 -- **Embedding model**: TBD (Claude/OpenAI ada-002/local) -- **Automation**: n8n (workflow engine) -- **Code repository**: Gitea (self-hosted) -- **Deployment**: Coolify (Docker management) -- **Proxy**: Traefik v3.6 (auto-SSL) -- **Frontend**: ezer-mishpati-web (static HTML + API) +- **Embeddings**: Voyage AI (`voyage-3-large`, 1024-dim) +- **Agents**: Claude Opus 4.7 (via Paperclip pm2) +- **DOCX manipulation**: `python-docx` 1.2+ ו-`lxml` 5.2+ (XML surgery) +- **Frontend**: Next.js + TanStack Query + Tailwind +- **Backend**: FastAPI + asyncpg +- **Deployment**: Coolify + Docker + Traefik (SSL ב-Let's Encrypt) +- **Code repo**: Gitea (`gitea.nautilus.marcusgroup.org/ezer-mishpati/legal-ai`) +- **Secret management**: Infisical + +--- + +## מסמכים קשורים + +- [`block-schema.md`](block-schema.md) — מבנה 12 הבלוקים, content model, constraints +- [`decision-methodology.md`](decision-methodology.md) — מתודולוגיה אנליטית +- [`legal-decision-lessons.md`](legal-decision-lessons.md) — לקחים מ-3 החלטות +- [`new-company-setup-guide.md`](new-company-setup-guide.md) — הקמת חברה חדשה (CMPA) +- [`product-specification.md`](product-specification.md) — איפיון מוצר מלא (persona, תהליכים עסקיים) +- [`../CLAUDE.md`](../CLAUDE.md) — הנחיות לסוכני AI שעובדים על הקוד +- [`../scripts/SCRIPTS.md`](../scripts/SCRIPTS.md) — כל הסקריפטים והשימוש בהם