feat(plans): משיכת תב"ע מ-מנהל-התכנון (mavat) — Phase C backend-slice
All checks were successful
G12 Leak-Guard / leak-guard (pull_request) Successful in 3s
Lint — undefined names / undefined-names (pull_request) Successful in 10s

ליבת-המשיכה למרשם-התכניות (V38): מספר-תכנית → זהות+תוקף מ-mavat דרך
גשר-Camoufox הקיים (G2 — אותו שירות/פורט/סוד כמו X13, בלי חדשים).

- court_fetch_service/mavat_client.py (חדש): דרייבר Camoufox מול mavat —
  עוקף F5-ASM (דפדפן-JS), search→auto-nav ל-SV4, לוכד GET /rest/api/SV4/1,
  מפענח planDetails (E_NAME/AUTH/ENTITY_SUBTYPE/GOALS) + rsInternet
  (פרסום-לאישור→ED_PUBLICATION_FILE=י"פ + DETAILS→תאריך/עמוד). מלכודת-
  דרייבר: init-script window.onerror swallow. reCAPTCHA נשאר דלוק (token).
- court_fetch_service/server.py: POST /plan-fetch (אותו Bearer).
- services/plans_fetch.py (חדש): צד-קונטיינר — httpx לגשר, מנרמל שדות.
- tools/plans.py + server.py: כלי-MCP plan_fetch (מועמד, לא כותב).
- web/app.py: POST /api/plans/fetch (503 גשר-למטה, 404 לא-נמצא).

אומת חי מול mavat: 101-1031020→י"פ 13697 (עמ' 8758, 30/07/2025),
101-1053933→י"פ 13836. מקור-אמת עשיר מתב"ע-עכשיו (שחסר י"פ).

INV-AH: כל ערך נושא source_url; שדה-חסר ריק לא מומצא. G10: מחזיר
מועמד בלבד — שער-יו"ר (review_status) נשמר. G2: מרחיב גשר+מרשם קיימים.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-06-17 11:09:39 +00:00
parent 20a51c572a
commit a55ffd59eb
6 changed files with 442 additions and 0 deletions

View File

@@ -7653,6 +7653,32 @@ async def plan_merge(req: PlanMergeRequest):
raise HTTPException(400, str(e))
class PlanFetchRequest(BaseModel):
plan_number: str
@app.post("/api/plans/fetch")
async def plan_fetch_from_mavat(req: PlanFetchRequest):
"""Pull a plan's identity + validity from mavat (מנהל התכנון) for the chair form.
Returns a candidate dict (display_name/plan_type/purpose/gazette_date/
yalkut_number/source_url) — does NOT write the registry; the chair saves via
POST /api/plans (review_status gate stays, INV-AH source_url carried). The
browser work runs on the host bridge (Camoufox past F5); 503 if it's down,
404 if the plan wasn't found.
"""
from legal_mcp.services import plans_fetch
if not req.plan_number.strip():
raise HTTPException(400, "חסר מספר-תכנית")
try:
return await plans_fetch.fetch_plan(req.plan_number)
except plans_fetch.PlanFetchUnavailable as e:
raise HTTPException(503, str(e))
except plans_fetch.PlanFetchError as e:
raise HTTPException(404, str(e))
# ── Missing Precedents (TaskMaster #35) ────────────────────────────
# Track citations from party briefs that aren't yet in the precedent
# corpus. Researcher logs gaps; chair closes them by uploading the