Rewrite architecture.md — add Track Changes edit flow + 8 stages
All checks were successful
Build & Deploy / build-and-deploy (push) Successful in 6s

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 <w:ins>/<w:del> 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) <noreply@anthropic.com>
This commit is contained in:
2026-04-16 19:10:11 +00:00
parent 36925c589b
commit e068a611e7

View File

@@ -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) │ │
└──────────┘ └──────────┘ └──────────────────┘
│ ┌──────────────────────────────────────────────────────┐
│ │ legal-ai container (Coolify UUID: gyjo0mtw2c42ej3...) │
│ │ ┌────────────┐ ┌──────────────────────────┐
│ │ Next.js UI │ │ FastAPI backend │ │
│ │ │ :3000 │◄──►│ :8000 (internal) │ │ │
│ │ └────────────┘ │ + MCP server │ │ │
│ │ └──────────────────────────┘ │ │
│ └──────────────────────────────────────────────────────┘ │
│ │
│ ┌──────────────────┐ ┌──────────────────────────┐ │
│ │ PostgreSQL │ │ Redis │ │
│ │ + pgvector │ │ (task queue) │ │
│ │ (legal-ai-postgres│ │ (legal-ai-redis) │ │
│ │ PostgreSQL + │ │ Redis │
│ │ pgvector (1024D) │ │ (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 │
└──────────────────────────────────────────────┘
└─────────────────────────────────────────────────────┘
│ ┌──────────────┐ ┌──────────────────────────┐
│ │ 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** בתחילת וסיום כל בלוק — אנקורים לעריכות עתידיות:
- `<w:bookmarkStart w:name="block-alef">` ... `<w:bookmarkEnd>`
- כך עד `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 דו-שכבתי:
- א) מרקרים עבריים בתחילת פסקה: `א.`, `ב.`, ..., `יב.`
- ב) כותרות סגנון דפנה: "רקע", "תמצית טענות", "דיון והכרעה", "סוף דבר", וכו'
- מזריק `<w:bookmarkStart>` / `<w:bookmarkEnd>` חסרים
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. מוסיף `<w:trackRevisions/>` ב-`word/settings.xml` (אם חסר)
3. לכל revision:
- מאתר את ה-bookmark בעץ
- בונה פסקה חדשה עם RTL + David + המילה "מערכת AI" כמחבר
- עוטף את ה-runs החדשים ב-`<w:ins w:id w:author w:date>`
- שומר 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) — כל הסקריפטים והשימוש בהם