From 8e1384b897bc366e4167467236dcd8b89d59f284 Mon Sep 17 00:00:00 2001 From: Chaim Date: Sun, 3 May 2026 12:28:35 +0000 Subject: [PATCH] fix(precedents): wrap citation column + extractor fills source_type MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Two follow-ups after running the metadata extractor on 403-17: 1. Library table: shadcn TableCell defaults to whitespace-nowrap and the table wrapper has overflow-x-auto, so the long citation forced a horizontal scrollbar inside the row. Override on the citation cell only — whitespace-normal + break-words + min/max-w to keep the column readable. Same for the case-name cell. Row aligns to top so wrapping doesn't push neighbours up. 2. Extractor now also fills source_type (court_ruling / appeals_committee). The previous round added decision_date_iso, precedent_level, and court but left source_type empty. Same closed-enum + merge-only-if-empty policy. Co-Authored-By: Claude Opus 4.7 (1M context) --- .../services/precedent_metadata_extractor.py | 13 ++++++++++++- .../components/precedents/library-list-panel.tsx | 15 ++++++++++++--- 2 files changed, 24 insertions(+), 4 deletions(-) diff --git a/mcp-server/src/legal_mcp/services/precedent_metadata_extractor.py b/mcp-server/src/legal_mcp/services/precedent_metadata_extractor.py index 27de536..5ec7af9 100644 --- a/mcp-server/src/legal_mcp/services/precedent_metadata_extractor.py +++ b/mcp-server/src/legal_mcp/services/precedent_metadata_extractor.py @@ -49,6 +49,7 @@ METADATA_EXTRACTION_PROMPT = """אתה מסייע משפטי בכיר. קרא א "subject_tags": ["תגיות", "נושא", "בעברית"], "decision_date_iso": "YYYY-MM-DD — תאריך מתן ההחלטה כפי שמופיע בטקסט (בכותרת או בחתימה הסופית). אם לא ניתן לזהות במדויק — מחרוזת ריקה.", "precedent_level": "אחד מ-4: 'עליון' / 'מנהלי' / 'ועדת_ערר_ארצית' / 'ועדת_ערר_מחוזית'. בחר לפי הערכאה שמסומנת בכותרת הפסק. אם לא ברור — מחרוזת ריקה.", + "source_type": "אחד מ-2: 'court_ruling' (פסק דין של בית משפט — עליון/מנהלי) / 'appeals_committee' (החלטה של ועדת ערר). אם לא ברור — מחרוזת ריקה.", "court": "שם הערכאה כפי שהוא מופיע בכותרת (למשל 'בית המשפט העליון', 'בית המשפט המחוזי בירושלים בשבתו כבית משפט לעניינים מנהליים', 'ועדת הערר לתכנון ובניה פיצויים והיטלי השבחה — מחוז ירושלים'). מחרוזת ריקה אם לא ניתן לזהות." } @@ -61,7 +62,8 @@ METADATA_EXTRACTION_PROMPT = """אתה מסייע משפטי בכיר. קרא א 6. **subject_tags** — 3-7 תגיות בעברית, snake_case (חניה, קווי_בניין, שיקול_דעת, פגם_פרוצדורלי, סמכות, מועדים, פגיעה_במקרקעין, ירידת_ערך, תכנית_רחביה, מימוש_במכר, וכד'). שייך לתחום של ועדת ערר תכנון ובניה. 7. **decision_date_iso** — תאריך מדויק בלבד. אם בטקסט יש "ניתנה היום, ט' באלול תשפ"א, 5 בספטמבר 2022" — הפלט: "2022-09-05". 8. **precedent_level** — קבע לפי הערכאה: בית המשפט העליון = "עליון"; בית משפט מחוזי בשבתו כבית משפט לעניינים מנהליים = "מנהלי"; ועדת ערר ארצית = "ועדת_ערר_ארצית"; ועדת ערר מחוזית (כמו ועדות תכנון ובניה ירושלים/מחוז המרכז וכד') = "ועדת_ערר_מחוזית". השתמש ב-underscore כפי שמופיע — לא ברווח. -9. **court** — מהכותרת הראשית של הפסק. ניסוח מלא (לא קיצור). מחרוזת ריקה אם לא ניתן לזהות. +9. **source_type** — שני ערכים בלבד: "court_ruling" כשהמסמך הוא פסק דין/החלטה של בית משפט (עליון/בג"ץ/מנהלי/מחוזי); "appeals_committee" כשהמסמך הוא החלטה של ועדת ערר (ארצית או מחוזית). זה משלים את `precedent_level` — שני השדות צריכים להיות תואמים. +10. **court** — מהכותרת הראשית של הפסק. ניסוח מלא (לא קיצור). מחרוזת ריקה אם לא ניתן לזהות. """ @@ -153,6 +155,10 @@ async def extract_metadata(case_law_id: UUID | str) -> dict: lvl = result["precedent_level"].strip() if lvl in {"עליון", "מנהלי", "ועדת_ערר_ארצית", "ועדת_ערר_מחוזית"}: out["precedent_level"] = lvl + if isinstance(result.get("source_type"), str): + st = result["source_type"].strip() + if st in {"court_ruling", "appeals_committee"}: + out["source_type"] = st if isinstance(result.get("court"), str): out["court"] = result["court"].strip() return out @@ -234,6 +240,11 @@ async def apply_to_record( if lvl: fields_to_update["precedent_level"] = lvl + if not (record.get("source_type") or "").strip(): + st = (suggested.get("source_type") or "").strip() + if st: + fields_to_update["source_type"] = st + if not (record.get("court") or "").strip(): c = (suggested.get("court") or "").strip() if c: diff --git a/web-ui/src/components/precedents/library-list-panel.tsx b/web-ui/src/components/precedents/library-list-panel.tsx index 5bef6fe..bf19cd7 100644 --- a/web-ui/src/components/precedents/library-list-panel.tsx +++ b/web-ui/src/components/precedents/library-list-panel.tsx @@ -83,11 +83,20 @@ function PrecedentRow({ }; return ( - - + + {cleanCitation(p.case_number)} - +
{cleanCitation(p.case_name)}
{p.court ? (
{p.court}