# System Architecture — Legal Decision Assistant > עודכן: 2026-04-16 — הוספת ארכיטקטורת Track Changes לעריכת טיוטות ## רכיבי המערכת ``` ┌───────────────────────────────────────────────────────────────┐ │ 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 (Opus 4.7 for agents) ← Voyage AI (voyage-3, 1024-dim embeddings) ← Infisical (secret management) ← Gmail SMTP (agent notifications) ``` --- ## הזרימה המלאה — מהעלאת מסמכים ועד טיוטה סופית ### שלב 1 — יצירת תיק + העלאת מסמכי מקור **מה קורה:** 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, 1024D), שומר ב-`document_chunks` 4. סטטוס תיק: `new` → `proofread` ### שלב 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 `cases`, `documents`, `document_chunks` **חדש (2026-04):** `cases.active_draft_path TEXT` — הנתיב המלא ל-DOCX שהוא מקור האמת הנוכחי של התיק. null עד לייצוא הראשון. ### Layer 2: Decision `decisions`, `decision_blocks`, `decision_paragraphs`, `claims` ### Layer 3: Legal Knowledge `case_law`, `statutory_provisions`, `transition_phrases`, `lessons_learned`, `style_corpus`, `style_patterns` ### Layer 4: Semantic Search (RAG) `document_embeddings`, `paragraph_embeddings`, `case_law_embeddings` (pgvector 1024-dim, voyage-3) ### 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) | --- ## טכנולוגיות עיקריות - **Database**: PostgreSQL 15 + pgvector 0.8.1 - **Embeddings**: Voyage AI (`voyage-3`, 1024-dim) + cross-encoder rerank (`rerank-2`) - bi-encoder: voyage-3 לכל chunk (חד-פעמי בעת ingestion) - cross-encoder: rerank-2 לכל query (top-50 → top-K), feature flag `VOYAGE_RERANK_ENABLED` - **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) — כל הסקריפטים והשימוש בהם