feat: emit missing_precedent + export_complete webhooks to plugin
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:
2026-05-26 13:29:04 +00:00
parent 1d4f214abe
commit b01722b1b4
2 changed files with 151 additions and 7 deletions

View File

@@ -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