Compare commits
4 Commits
d5043100a7
...
015e553d06
| Author | SHA1 | Date | |
|---|---|---|---|
| 015e553d06 | |||
| 6bdf9786ac | |||
| d87f9c5a5f | |||
| a0fab1f6de |
32
web/app.py
32
web/app.py
@@ -20,7 +20,7 @@ sys.path.insert(0, str(Path(__file__).resolve().parent.parent / "mcp-server" / "
|
||||
|
||||
import zipfile
|
||||
|
||||
from fastapi import FastAPI, File, Form, HTTPException, UploadFile
|
||||
from fastapi import BackgroundTasks, FastAPI, File, Form, HTTPException, UploadFile
|
||||
from fastapi.responses import FileResponse, StreamingResponse
|
||||
from typing import Any, Literal
|
||||
from pydantic import BaseModel
|
||||
@@ -44,7 +44,7 @@ from web.mcp_env_catalog import (
|
||||
normalize_for_compare,
|
||||
)
|
||||
from web.progress_store import ProgressStore
|
||||
from web.paperclip_api import pc_request
|
||||
from web.paperclip_api import emit_case_status_webhook, pc_request
|
||||
from web.paperclip_client import (
|
||||
COMPANIES as PAPERCLIP_COMPANIES,
|
||||
accept_interaction as pc_accept_interaction,
|
||||
@@ -1337,8 +1337,12 @@ async def api_case_get(case_number: str):
|
||||
|
||||
|
||||
@app.put("/api/cases/{case_number}")
|
||||
async def api_case_update(case_number: str, req: CaseUpdateRequest):
|
||||
async def api_case_update(case_number: str, req: CaseUpdateRequest, background_tasks: BackgroundTasks):
|
||||
"""Update case details."""
|
||||
# Capture old status before the update so we can detect changes.
|
||||
existing = await db.get_case_by_number(case_number)
|
||||
old_status = (existing or {}).get("status", "")
|
||||
|
||||
result = await cases_tools.case_update(
|
||||
case_number=case_number,
|
||||
status=req.status,
|
||||
@@ -1351,10 +1355,30 @@ async def api_case_update(case_number: str, req: CaseUpdateRequest):
|
||||
expected_outcome=req.expected_outcome,
|
||||
)
|
||||
try:
|
||||
return json.loads(result)
|
||||
parsed = json.loads(result)
|
||||
except json.JSONDecodeError:
|
||||
raise HTTPException(404, result)
|
||||
|
||||
# Emit webhook when status changes (fire-and-forget via BackgroundTasks).
|
||||
new_status = req.status
|
||||
if new_status and old_status != new_status:
|
||||
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(
|
||||
emit_case_status_webhook,
|
||||
case_number=case_number,
|
||||
old_status=old_status,
|
||||
new_status=new_status,
|
||||
company_id=company_id, # None is safe — plugin handles unknown company gracefully
|
||||
)
|
||||
logger.debug("webhook scheduled: case %s %s → %s", case_number, old_status, new_status)
|
||||
|
||||
return parsed
|
||||
|
||||
|
||||
@app.delete("/api/cases")
|
||||
async def api_case_delete(case_number: str, remove_files: bool = False):
|
||||
|
||||
@@ -19,6 +19,7 @@ from __future__ import annotations
|
||||
|
||||
import logging
|
||||
import os
|
||||
from datetime import datetime
|
||||
from typing import Any
|
||||
|
||||
import httpx
|
||||
@@ -81,3 +82,35 @@ async def pc_request(
|
||||
if raise_on_error:
|
||||
resp.raise_for_status()
|
||||
return resp
|
||||
|
||||
|
||||
async def emit_case_status_webhook(
|
||||
case_number: str,
|
||||
old_status: str,
|
||||
new_status: str,
|
||||
company_id: str | None = None,
|
||||
run_id: str | None = None,
|
||||
) -> None:
|
||||
"""Notify the Paperclip plugin that a case status changed.
|
||||
|
||||
Fire-and-forget: logs errors but never raises, so callers aren't blocked.
|
||||
"""
|
||||
try:
|
||||
await pc_request(
|
||||
"POST",
|
||||
"/api/plugins/marcusgroup.legal-ai/webhooks/case-status",
|
||||
json={
|
||||
"caseNumber": case_number,
|
||||
"oldStatus": old_status,
|
||||
"newStatus": new_status,
|
||||
"companyId": company_id,
|
||||
"timestamp": datetime.utcnow().isoformat() + "Z",
|
||||
},
|
||||
run_id=run_id,
|
||||
timeout=5.0,
|
||||
)
|
||||
except Exception as exc:
|
||||
logger.warning(
|
||||
"emit_case_status_webhook failed for case %s (%s → %s): %s",
|
||||
case_number, old_status, new_status, exc,
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user