Add REST API endpoints for Paperclip integration
Expose case management, search, workflow status, and drafting tools via HTTP endpoints for the Paperclip plugin to consume. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
124
web/app.py
124
web/app.py
@@ -26,6 +26,7 @@ from pydantic import BaseModel
|
|||||||
|
|
||||||
from legal_mcp import config
|
from legal_mcp import config
|
||||||
from legal_mcp.services import chunker, db, embeddings, extractor, processor
|
from legal_mcp.services import chunker, db, embeddings, extractor, processor
|
||||||
|
from legal_mcp.tools import cases as cases_tools, search as search_tools, workflow as workflow_tools, drafting as drafting_tools
|
||||||
|
|
||||||
# Din Leumi imports (aliased to avoid collision)
|
# Din Leumi imports (aliased to avoid collision)
|
||||||
from din_leumi import config as dl_config
|
from din_leumi import config as dl_config
|
||||||
@@ -202,6 +203,129 @@ async def list_cases():
|
|||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
# ── Paperclip Integration API ─────────────────────────────────────
|
||||||
|
|
||||||
|
|
||||||
|
class CaseCreateRequest(BaseModel):
|
||||||
|
case_number: str
|
||||||
|
title: str
|
||||||
|
appellants: list[str] | None = None
|
||||||
|
respondents: list[str] | None = None
|
||||||
|
subject: str = ""
|
||||||
|
property_address: str = ""
|
||||||
|
permit_number: str = ""
|
||||||
|
committee_type: str = "ועדה מקומית"
|
||||||
|
hearing_date: str = ""
|
||||||
|
notes: str = ""
|
||||||
|
expected_outcome: str = ""
|
||||||
|
|
||||||
|
|
||||||
|
class CaseUpdateRequest(BaseModel):
|
||||||
|
status: str = ""
|
||||||
|
title: str = ""
|
||||||
|
subject: str = ""
|
||||||
|
notes: str = ""
|
||||||
|
hearing_date: str = ""
|
||||||
|
decision_date: str = ""
|
||||||
|
tags: list[str] | None = None
|
||||||
|
expected_outcome: str = ""
|
||||||
|
|
||||||
|
|
||||||
|
@app.post("/api/cases/create")
|
||||||
|
async def api_case_create(req: CaseCreateRequest):
|
||||||
|
"""Create a new appeal case."""
|
||||||
|
result = await cases_tools.case_create(
|
||||||
|
case_number=req.case_number,
|
||||||
|
title=req.title,
|
||||||
|
appellants=req.appellants,
|
||||||
|
respondents=req.respondents,
|
||||||
|
subject=req.subject,
|
||||||
|
property_address=req.property_address,
|
||||||
|
permit_number=req.permit_number,
|
||||||
|
committee_type=req.committee_type,
|
||||||
|
hearing_date=req.hearing_date,
|
||||||
|
notes=req.notes,
|
||||||
|
expected_outcome=req.expected_outcome,
|
||||||
|
)
|
||||||
|
return json.loads(result)
|
||||||
|
|
||||||
|
|
||||||
|
@app.get("/api/cases/{case_number}/details")
|
||||||
|
async def api_case_get(case_number: str):
|
||||||
|
"""Get full case details including documents."""
|
||||||
|
result = await cases_tools.case_get(case_number)
|
||||||
|
try:
|
||||||
|
return json.loads(result)
|
||||||
|
except json.JSONDecodeError:
|
||||||
|
raise HTTPException(404, result)
|
||||||
|
|
||||||
|
|
||||||
|
@app.put("/api/cases/{case_number}")
|
||||||
|
async def api_case_update(case_number: str, req: CaseUpdateRequest):
|
||||||
|
"""Update case details."""
|
||||||
|
result = await cases_tools.case_update(
|
||||||
|
case_number=case_number,
|
||||||
|
status=req.status,
|
||||||
|
title=req.title,
|
||||||
|
subject=req.subject,
|
||||||
|
notes=req.notes,
|
||||||
|
hearing_date=req.hearing_date,
|
||||||
|
decision_date=req.decision_date,
|
||||||
|
tags=req.tags,
|
||||||
|
expected_outcome=req.expected_outcome,
|
||||||
|
)
|
||||||
|
try:
|
||||||
|
return json.loads(result)
|
||||||
|
except json.JSONDecodeError:
|
||||||
|
raise HTTPException(404, result)
|
||||||
|
|
||||||
|
|
||||||
|
@app.get("/api/cases/{case_number}/status")
|
||||||
|
async def api_case_status(case_number: str):
|
||||||
|
"""Get full workflow status for a case."""
|
||||||
|
result = await workflow_tools.workflow_status(case_number)
|
||||||
|
try:
|
||||||
|
return json.loads(result)
|
||||||
|
except json.JSONDecodeError:
|
||||||
|
raise HTTPException(404, result)
|
||||||
|
|
||||||
|
|
||||||
|
@app.get("/api/search")
|
||||||
|
async def api_search(query: str, limit: int = 10, section_type: str = ""):
|
||||||
|
"""Semantic search across decisions and documents."""
|
||||||
|
result = await search_tools.search_decisions(query, limit, section_type)
|
||||||
|
try:
|
||||||
|
return json.loads(result)
|
||||||
|
except json.JSONDecodeError:
|
||||||
|
return {"message": result}
|
||||||
|
|
||||||
|
|
||||||
|
@app.get("/api/cases/{case_number}/search")
|
||||||
|
async def api_case_search(case_number: str, query: str, limit: int = 10):
|
||||||
|
"""Semantic search within a specific case's documents."""
|
||||||
|
result = await search_tools.search_case_documents(case_number, query, limit)
|
||||||
|
try:
|
||||||
|
return json.loads(result)
|
||||||
|
except json.JSONDecodeError:
|
||||||
|
return {"message": result}
|
||||||
|
|
||||||
|
|
||||||
|
@app.get("/api/cases/{case_number}/template")
|
||||||
|
async def api_case_template(case_number: str):
|
||||||
|
"""Get outcome-aware decision template for a case."""
|
||||||
|
result = await drafting_tools.get_decision_template(case_number)
|
||||||
|
if result.startswith("תיק"):
|
||||||
|
raise HTTPException(404, result)
|
||||||
|
return {"template": result}
|
||||||
|
|
||||||
|
|
||||||
|
@app.get("/api/processing-status")
|
||||||
|
async def api_processing_status():
|
||||||
|
"""Get overall processing status."""
|
||||||
|
result = await workflow_tools.processing_status()
|
||||||
|
return json.loads(result)
|
||||||
|
|
||||||
|
|
||||||
# ── Din Leumi Endpoint ────────────────────────────────────────────
|
# ── Din Leumi Endpoint ────────────────────────────────────────────
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user