feat(case-ui): חלוקת רשימת-המסמכים בטאב-הסקירה ל-4 קבוצות
חלוקה פנימית (לנוחות בלבד, לא משנה doc_type) של רשימת מסמכי-התיק:
1. עיקריים (appeal/response/appraisal) · 2. נלווים · 3. פרוטוקול ועדת הערר ·
4. לאחר הדיון. הסיווג נגזר בצד-הלקוח מ-doc_type + שני דגלי-metadata.
שני פקדים חדשים בעורך-התיוג:
- מתג "התקבל אחרי הדיון" → metadata.is_post_hearing (כבר נצרך ע"י בלוק-ח);
גובר על הסיווג-לפי-סוג ומעביר לקבוצה 4.
- בורר "פרוטוקול של: ועדת הערר / ועדה מקומית-מחוזית" → metadata.protocol_scope
(נראה רק כשהסוג protocol); ברירת-מחדל appeal→קבוצה 3, lower→קבוצה 2.
Backend: PATCH /documents/{id} + MCP document_update מקבלים is_post_hearing
ו-protocol_scope, נשמרים ב-metadata JSONB (אותו מסלול כמו appraiser_side).
עיצוב אושר ב-Claude Design (X17): 18k-case-documents-grouped.html.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
44
web/app.py
44
web/app.py
@@ -5722,13 +5722,21 @@ async def api_reprocess_document(case_number: str, doc_id: str):
|
||||
|
||||
|
||||
_ALLOWED_APPRAISER_SIDES = {"committee", "appellant", "deciding"}
|
||||
# metadata.protocol_scope — only meaningful when doc_type == "protocol".
|
||||
# "appeal" = ועדת הערר (default when absent), "lower" = ועדה מקומית/מחוזית.
|
||||
# Used by the overview panel to sort a protocol into group 3 vs group 2.
|
||||
_ALLOWED_PROTOCOL_SCOPES = {"appeal", "lower"}
|
||||
|
||||
|
||||
class DocumentPatchRequest(BaseModel):
|
||||
"""Patch payload for a single document. Both fields are optional."""
|
||||
"""Patch payload for a single document. All fields are optional; only the
|
||||
ones present are applied. The metadata.* flags are display/processing hints
|
||||
that never change the stored doc_type."""
|
||||
|
||||
doc_type: str | None = None
|
||||
appraiser_side: str | None = None # committee | appellant | deciding | "" to clear
|
||||
is_post_hearing: bool | None = None # material submitted after the hearing (→ group 4, block-chet)
|
||||
protocol_scope: str | None = None # appeal | lower | "" to clear (protocol docs only)
|
||||
|
||||
|
||||
@app.patch("/api/cases/{case_number}/documents/{doc_id}")
|
||||
@@ -5753,6 +5761,13 @@ async def api_patch_document(case_number: str, doc_id: str, req: DocumentPatchRe
|
||||
|
||||
updates: dict = {}
|
||||
|
||||
# Load metadata once — appraiser_side, is_post_hearing and protocol_scope
|
||||
# all live in the same JSONB blob, so a single patch may touch several.
|
||||
metadata = doc.get("metadata") or {}
|
||||
if isinstance(metadata, str):
|
||||
metadata = json.loads(metadata)
|
||||
metadata_dirty = False
|
||||
|
||||
if req.doc_type is not None:
|
||||
if req.doc_type not in DOC_TYPE_NAMES:
|
||||
raise HTTPException(
|
||||
@@ -5769,13 +5784,34 @@ async def api_patch_document(case_number: str, doc_id: str, req: DocumentPatchRe
|
||||
f"appraiser_side לא תקין: {req.appraiser_side}. ערכים מותרים: "
|
||||
f"{', '.join(sorted(_ALLOWED_APPRAISER_SIDES))}",
|
||||
)
|
||||
metadata = doc.get("metadata") or {}
|
||||
if isinstance(metadata, str):
|
||||
metadata = json.loads(metadata)
|
||||
if req.appraiser_side:
|
||||
metadata["appraiser_side"] = req.appraiser_side
|
||||
else:
|
||||
metadata.pop("appraiser_side", None)
|
||||
metadata_dirty = True
|
||||
|
||||
if req.is_post_hearing is not None:
|
||||
# Store True; drop the key entirely when False so absence == "before".
|
||||
if req.is_post_hearing:
|
||||
metadata["is_post_hearing"] = True
|
||||
else:
|
||||
metadata.pop("is_post_hearing", None)
|
||||
metadata_dirty = True
|
||||
|
||||
if req.protocol_scope is not None:
|
||||
if req.protocol_scope and req.protocol_scope not in _ALLOWED_PROTOCOL_SCOPES:
|
||||
raise HTTPException(
|
||||
422,
|
||||
f"protocol_scope לא תקין: {req.protocol_scope}. ערכים מותרים: "
|
||||
f"{', '.join(sorted(_ALLOWED_PROTOCOL_SCOPES))}",
|
||||
)
|
||||
if req.protocol_scope:
|
||||
metadata["protocol_scope"] = req.protocol_scope
|
||||
else:
|
||||
metadata.pop("protocol_scope", None)
|
||||
metadata_dirty = True
|
||||
|
||||
if metadata_dirty:
|
||||
updates["metadata"] = metadata
|
||||
|
||||
if not updates:
|
||||
|
||||
Reference in New Issue
Block a user