feat: emit missing_precedent + export_complete webhooks to plugin
All checks were successful
Build & Deploy / build-and-deploy (push) Successful in 9s
All checks were successful
Build & Deploy / build-and-deploy (push) Successful in 9s
Adds two webhook emitters in paperclip_api.py that the plugin's
onWebhook handler now routes by ``eventType``:
* ``emit_missing_precedent_webhook(...)`` — fires from
POST /api/missing-precedents on first insert (non-duplicate).
The plugin surfaces an askUserQuestions interaction on the
linked issue so Daphna can choose upload / irrelevant / defer
without needing to open the legal-ai UI.
* ``emit_export_complete_webhook(...)`` — fires from
POST /api/cases/{n}/export-docx after a successful export. The
plugin attaches a "final-decision" markdown document with a
download link to the linked Paperclip issue.
Both are fire-and-forget BackgroundTasks — failures are logged
but never block the originating request. Company resolution
follows the same 1xxx→licensing / 8-9xxx→betterment rule used
by emit_case_status_webhook.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
70
web/app.py
70
web/app.py
@@ -2545,15 +2545,42 @@ async def api_mark_final(case_number: str, filename: str):
|
||||
|
||||
|
||||
@app.post("/api/cases/{case_number}/export-docx")
|
||||
async def api_export_docx(case_number: str):
|
||||
"""Trigger DOCX export for a case."""
|
||||
async def api_export_docx(case_number: str, background_tasks: BackgroundTasks):
|
||||
"""Trigger DOCX export for a case.
|
||||
|
||||
On a successful export, fires a fire-and-forget webhook to the
|
||||
Paperclip plugin so it can attach a "final-decision" document
|
||||
(markdown body + download link) to the linked issue.
|
||||
"""
|
||||
result = await drafting_tools.export_docx(case_number)
|
||||
try:
|
||||
data = json.loads(result)
|
||||
return data
|
||||
except json.JSONDecodeError:
|
||||
raise HTTPException(500, result)
|
||||
|
||||
# Notify the Paperclip plugin to attach the final-decision document.
|
||||
docx_filename = (
|
||||
data.get("filename")
|
||||
or data.get("docx_filename")
|
||||
or data.get("file")
|
||||
or ""
|
||||
)
|
||||
if docx_filename:
|
||||
prefix = case_number[:1]
|
||||
company_id = (
|
||||
PAPERCLIP_COMPANIES["licensing"] if prefix == "1"
|
||||
else PAPERCLIP_COMPANIES["betterment"] if prefix in ("8", "9")
|
||||
else None
|
||||
)
|
||||
background_tasks.add_task(
|
||||
paperclip_api.emit_export_complete_webhook,
|
||||
case_number=case_number,
|
||||
docx_filename=docx_filename,
|
||||
company_id=company_id,
|
||||
)
|
||||
|
||||
return data
|
||||
|
||||
|
||||
@app.get("/api/documents/{doc_id}/text")
|
||||
async def api_document_text(doc_id: str):
|
||||
@@ -4976,18 +5003,33 @@ def _is_internal_committee_citation(citation: str) -> bool:
|
||||
|
||||
|
||||
@app.post("/api/missing-precedents")
|
||||
async def missing_precedent_create(req: MissingPrecedentCreate):
|
||||
async def missing_precedent_create(
|
||||
req: MissingPrecedentCreate, background_tasks: BackgroundTasks,
|
||||
):
|
||||
"""Log a new missing precedent (status='open'). Dedupes by
|
||||
(citation, cited_in_case_id) — duplicate POST returns the existing row."""
|
||||
(citation, cited_in_case_id) — duplicate POST returns the existing row.
|
||||
|
||||
On first insert (non-duplicate) emits a webhook to the Paperclip
|
||||
plugin so it can ask Daphna via an ``askUserQuestions`` interaction
|
||||
whether to upload the missing precedent.
|
||||
"""
|
||||
if not req.citation.strip():
|
||||
raise HTTPException(400, "citation חובה")
|
||||
|
||||
case_id: UUID | None = None
|
||||
if req.case_number.strip():
|
||||
c = await db.get_case_by_number(req.case_number.strip())
|
||||
case_number_for_webhook = req.case_number.strip()
|
||||
company_id_for_webhook: str | None = None
|
||||
if case_number_for_webhook:
|
||||
c = await db.get_case_by_number(case_number_for_webhook)
|
||||
if not c:
|
||||
raise HTTPException(404, f"תיק לא נמצא: {req.case_number}")
|
||||
case_id = UUID(c["id"])
|
||||
prefix = case_number_for_webhook[:1]
|
||||
company_id_for_webhook = (
|
||||
PAPERCLIP_COMPANIES["licensing"] if prefix == "1"
|
||||
else PAPERCLIP_COMPANIES["betterment"] if prefix in ("8", "9")
|
||||
else None
|
||||
)
|
||||
|
||||
doc_id: UUID | None = None
|
||||
if req.cited_in_document_id:
|
||||
@@ -5015,6 +5057,20 @@ async def missing_precedent_create(req: MissingPrecedentCreate):
|
||||
claim_quote=req.claim_quote,
|
||||
notes=req.notes,
|
||||
)
|
||||
|
||||
# Trigger plugin to ask Daphna via askUserQuestions interaction.
|
||||
if case_number_for_webhook and row.get("id"):
|
||||
background_tasks.add_task(
|
||||
paperclip_api.emit_missing_precedent_webhook,
|
||||
case_number=case_number_for_webhook,
|
||||
missing_precedent_id=str(row["id"]),
|
||||
citation=req.citation.strip(),
|
||||
cited_by_party=req.cited_by_party,
|
||||
cited_by_party_name=req.cited_by_party_name,
|
||||
legal_topic=req.legal_topic,
|
||||
legal_issue=req.legal_issue,
|
||||
company_id=company_id_for_webhook,
|
||||
)
|
||||
return row
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user