Records the now-complete corpus citation graph: why native not Obsidian (G2), the 6 opt-in node layers (precedent/topic/practice-area · halacha · gaps · digests), node size/color semantics, the Graph Analysis metrics (PageRank/betweenness/community via web/graph_metrics.py), navigation, the /api/graph/* endpoints, the key files, a how-to-extend recipe, the invariants (G2/G5/UI2/UI4), and the PR history. Adds docs/corpus-graph.md + a reference-table row in legal-ai/CLAUDE.md. Docs only — no code change. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
6.5 KiB
מפת הקורפוס — גרף ציטוטים אינטראקטיבי (/graph)
תצוגת‑רשת אינטראקטיבית של קורפוס הפסיקה, בסגנון Obsidian Graph View, מוטמעת נייטיב ב‑web‑ui. כל פריט הוא נקודה, קישורים הם קווים, וגודל הנקודה משקף חשיבות — כך שאפשר להתמקד בנושא ולראות מה קשור אליו.
למה נייטיב ולא Obsidian (G2)
הרעיון המקורי היה לייצא את הקורפוס ל‑Obsidian vault. נדחה — vault הוא עותק מקביל של הקורפוס שמתיישן, בדיוק כשל‑השורש ש‑G2 (מקור‑אמת יחיד, ללא מסלול מקביל) בא לייבש. הגרף הנייטיב קורא את ה‑DB החי → אפס drift, ומתחבר לדפים הקיימים (/precedents, /missing-precedents, /digests).
התובנה המאפשרת: כל קשתות הגרף כבר היו קיימות בטבלאות — הגרף רק חושף אותן. הוא projection קריא‑בלבד (SELECT בלבד), ולכן אינו יכול לסטות מהמקור. הוא אינו מסלול אחזור (03-retrieval) — מחזיר טופולוגיה (nodes+edges+מטריקות), לא תוצאות חיפוש מדורגות.
שכבות (כולן opt‑in דרך toggles, מלבד הבסיס)
| שכבה | נקודות | קשתות | מקור הדאטה |
|---|---|---|---|
| בסיס | פסיקה (cl:) · נושא (tag:) · תחום (pa:) |
cites · same_chain · tagged · in_area |
case_law, precedent_internal_citations, case_law_relations, subject_tags |
| הלכות | הלכה (hal:) |
extracted_from · corroborates · equivalent |
halachot, halacha_citation_corroboration, equivalent_halachot |
| חוסרי מחקר | gap (gap:) — חלול/מקווקו |
cites (פסיקה→gap) |
precedent_internal_citations (cited_case_law_id IS NULL) + העשרה מ‑missing_precedents |
| יומונים | יומון (dig:) — טורקיז |
covers (יומון→פסיקה/gap) |
digests |
גודל נקודה = חשיבות: ציטוטים נכנסים (פסיקה), אזכורים (הלכה), מספר מצטטים (gap). צבע (color‑by, ברירת‑מחדל "סוג"): סוג · תחום · דרגת‑סמכות · אשכול (community) · עדכניות.
אנליטיקה (Graph Analysis)
metrics=true מפעיל חישוב in‑memory (ללא DB) ב‑web/graph_metrics.py — pure, ללא תלויות (אין networkx):
- PageRank (power‑iteration) — השפעה גלובלית.
- Betweenness (Brandes) — "גשריות" (פסיקות שמחברות אשכולות).
- Community (label‑propagation דטרמיניסטי + fallback ל‑connected‑components) — אשכולות תמטיים.
מחושב על תת‑גרף הפסיקות בלבד (cites/same_chain) — קשתות hub/gap/digest/halacha מוחרגות. ב‑UI: בוררי "צביעה לפי" / "גודל לפי" + פאנל דירוג ("המשפיעות" / "גשרים").
ניווט וחוויה
- Deep‑link
/graph?focus=cl:<id>— לינק שיתופי; כפתור "הצג בגרף" בכל דף פסיקה. - Local graph — לחיצה על נקודה → התמקדות בשכניה (BFS, סליידר עומק 1–3).
- ייצוא PNG · פאנל עשיר (headnote/summary) · מקרא נקודות+קשתות · סינון מטא‑דאטה (בית‑משפט/דרגה/יו״ר/מחוז/שנים).
API
קריאה‑בלבד, response_model מפורש (UI2). מוגדר ב‑web/app.py (~/api/graph/*), לוגיקה ב‑web/graph_api.py:
| endpoint | תיאור |
|---|---|
GET /api/graph/corpus |
הגרף המלא. params: node_types (csv), metrics, practice_area/source/court/precedent_level/chair/district/year_from/year_to, min_citations, q, limit (cap 400, max 1500) |
GET /api/graph/node/{id}/neighborhood |
Local graph: צומת + שכנים בעומק 1–3 |
GET /api/graph/facets |
ערכי סינון ייחודיים (courts/levels/chairs/districts) |
קבצים
- Backend:
web/graph_api.py(הרכבת nodes/edges, helpers_edges_and_hubs/_gap_nodes_and_edges/_digest_nodes_and_edges/_halacha_nodes_and_edges) ·web/graph_metrics.py(מטריקות) · endpoints ב‑web/app.py. - Frontend:
web-ui/src/app/graph/page.tsx·web-ui/src/components/graph/(graph-vieworchestrator ·graph-canvasציור react‑force‑graph‑2d ·graph-filter-panel·graph-node-panel) · hooks ב‑web-ui/src/lib/api/graph.ts.
איך מוסיפים שכבה חדשה
- הוסף ערך ל‑
VALID_NODE_TYPESב‑graph_api.py(לא ל‑DEFAULT_NODE_TYPESאם רוצים שיהיה כבוי). - כתוב
_X_nodes_and_edges(conn, prec_ids)— SELECT בלבד; חבר nodes לפסיקות שבתצוגה. - חבר בשתי פונקציות הבנייה (
build_corpus_graph+build_node_neighborhood) מאחוריif "X" in types. - dangling‑edge invariant: כל קשת — שני קצותיה חייבים להיות nodes בתצוגה (סנן מול
prec_ids/קבוצת ה‑ids). - Frontend: toggle ב‑
graph-filter-panel· צבע/רינדור ב‑graph-canvas(NODE_COLORS/colorForNode/linkColor) · ענף בפאנל ב‑graph-node-panel. - אם גדל מודל התגובה — אחרי deploy:
cd web-ui && npm run api:types.
Invariants
- G2 — projection קריא‑בלבד דרך
db.get_pool(); אפס כתיבות; מטריקות in‑memory. ללא store מקביל. - G5 — כל פילטר server‑side, parameterized.
- UI2 —
response_modelמפורש בכל endpoint; UI4 — שגיאות UI מוצגות, לא נבלעות. - טופולוגיה ≠ אחזור — מבנה הקורפוס, לא תוצאות חיפוש.
היסטוריית מימוש
PR #113 (בסיס) · #118 (תיקון תוויות) · #126 (מטא‑דאטה) · #129 (אנליטיקה) · #131 (gaps) · #132 (יומונים) · #134 (ניווט) · #137 (הלכות) · #139 (api:types).