feat(analysis): סיכום-מנהלים מזוקק של טענות הצדדים — מסמך הכנה לדיון (#202, WS3)
מסמך פרוזה נפרד מטיוטת-הביניים (החלטת-יו"ר): תמצית מוקפדת של טענות+תשובות
להכנת היו"ר לדיון. נגזר מ-legal_arguments/claims הקיימים — אותו מקור-אמת,
ללא חילוץ-מחדש (G2). מתוחם לטענות-התיק בלבד (INV-AH).
- כלי-MCP חדש summarize_party_claims (drafting.py + server.py); ייצור עובר
claude_session נעוץ Opus 4.8 + effort=high (זיקוק/סינתזה); local-only.
- שירות party_claims_summary.py: בחירת-מקור arguments→claims, פרומפט מעוגן-מקור,
שמירה ל-data/cases/{n}/documents/research/ (git + S3).
- ייצוא DOCX בסגנון-תבנית דפנה (build_party_claims_summary_docx) + endpoints
read/download/export-docx ב-web/app.py (מגישים בלבד — אין claude CLI בקונטיינר).
- _next_version הוכלל ל-prefix-scoped (תאימות-לאחור) למניעת התנגשות-גרסאות.
- ספ 04-analysis-writing.md §1.3 + 8 בדיקות אופליין (מקור/נעיצת-מודל/markdown→docx).
Invariants: G2 (מקור-אמת יחיד, בלי מסלול מקביל) · X9 TOOL1/TOOL4 (envelope +
extract↔serve) · INV-AH (עיגון-מקור, abstention על טענה לא-ברורה) ·
claude_session local-only · G9 (provenance — נשמר durably + git/S3).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
52
web/app.py
52
web/app.py
@@ -3063,6 +3063,58 @@ async def api_research_analysis_export_docx(case_number: str):
|
||||
)
|
||||
|
||||
|
||||
# ── Party-claims executive summary (party-claims-summary.md) — #202 ─
|
||||
# A distilled prose document of the parties' claims, SEPARATE from the interim
|
||||
# draft, to prepare the chair for the hearing. Generation is local-only (the
|
||||
# summarize_party_claims MCP tool via claude_session); these endpoints only
|
||||
# SERVE the saved file — they never generate (the container has no claude CLI).
|
||||
|
||||
|
||||
@app.get("/api/cases/{case_number}/research/party-claims-summary")
|
||||
async def api_party_claims_summary(case_number: str):
|
||||
"""Return the raw markdown of the party-claims executive summary."""
|
||||
from legal_mcp.services import party_claims_summary as pcs
|
||||
path = pcs.summary_file_path(case_number)
|
||||
if not path.exists():
|
||||
raise HTTPException(404, "טרם הופק סיכום-מנהלים לטענות הצדדים לתיק זה")
|
||||
return {"markdown": path.read_text(encoding="utf-8")}
|
||||
|
||||
|
||||
@app.get("/api/cases/{case_number}/research/party-claims-summary/download")
|
||||
async def api_party_claims_summary_download(case_number: str):
|
||||
"""Download the raw party-claims-summary.md file."""
|
||||
from legal_mcp.services import party_claims_summary as pcs
|
||||
path = pcs.summary_file_path(case_number)
|
||||
if not path.exists():
|
||||
raise HTTPException(404, "טרם הופק סיכום-מנהלים לטענות הצדדים לתיק זה")
|
||||
return await serve_blob(
|
||||
path,
|
||||
media_type="text/markdown; charset=utf-8",
|
||||
filename=f"party-claims-summary-{case_number}.md",
|
||||
)
|
||||
|
||||
|
||||
@app.get("/api/cases/{case_number}/research/party-claims-summary/export-docx")
|
||||
async def api_party_claims_summary_export_docx(case_number: str):
|
||||
"""Export the party-claims summary as a DOCX using דפנה's template styles."""
|
||||
from legal_mcp.services.analysis_docx_exporter import build_party_claims_summary_docx
|
||||
try:
|
||||
path = await build_party_claims_summary_docx(case_number)
|
||||
except FileNotFoundError as e:
|
||||
raise HTTPException(404, str(e))
|
||||
except Exception as e:
|
||||
logger.exception("Failed to export party-claims summary DOCX for %s", case_number)
|
||||
raise HTTPException(500, f"שגיאה בייצוא: {e}")
|
||||
case_dir = config.find_case_dir(case_number)
|
||||
if case_dir.exists():
|
||||
commit_and_push(case_dir, f"סיכום-מנהלים: {path.name}")
|
||||
return await serve_blob(
|
||||
path,
|
||||
media_type="application/vnd.openxmlformats-officedocument.wordprocessingml.document",
|
||||
filename=path.name,
|
||||
)
|
||||
|
||||
|
||||
@app.put("/api/cases/{case_number}/research/analysis/upload")
|
||||
async def api_research_analysis_upload(
|
||||
case_number: str,
|
||||
|
||||
Reference in New Issue
Block a user