Add settings page for tag-to-company mappings and auto-create Paperclip projects
All checks were successful
Build & Deploy / build-and-deploy (push) Successful in 1m22s
All checks were successful
Build & Deploy / build-and-deploy (push) Successful in 1m22s
When a case is created, a Paperclip project is now automatically created in the correct company based on the appeal_subtype tag. Tag-to-company mappings are managed via a new Settings page that pulls companies from Paperclip DB. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
65
web/app.py
65
web/app.py
@@ -2090,6 +2090,71 @@ async def api_paperclip_create_project(req: PaperclipProjectRequest):
|
||||
return project
|
||||
|
||||
|
||||
# ── Settings: Tag → Company Mappings ──────────────────────────────
|
||||
|
||||
@app.get("/api/settings/paperclip-companies")
|
||||
async def api_paperclip_companies():
|
||||
"""List all companies from Paperclip's DB."""
|
||||
pc_url = os.environ.get(
|
||||
"PAPERCLIP_DB_URL", "postgresql://paperclip:paperclip@127.0.0.1:54329/paperclip"
|
||||
)
|
||||
try:
|
||||
conn = await asyncpg.connect(pc_url)
|
||||
try:
|
||||
rows = await conn.fetch(
|
||||
"SELECT id, name, identifier FROM companies ORDER BY name"
|
||||
)
|
||||
return [{"id": str(r["id"]), "name": r["name"], "identifier": r.get("identifier", "")} for r in rows]
|
||||
finally:
|
||||
await conn.close()
|
||||
except Exception as e:
|
||||
raise HTTPException(502, f"Cannot reach Paperclip DB: {e}")
|
||||
|
||||
|
||||
@app.get("/api/settings/tag-mappings")
|
||||
async def api_get_tag_mappings():
|
||||
"""Get all tag → company mappings."""
|
||||
pool = await db.get_pool()
|
||||
rows = await pool.fetch(
|
||||
"SELECT id, tag, tag_label, company_id, company_name, created_at FROM tag_company_mappings ORDER BY tag"
|
||||
)
|
||||
return [dict(r) for r in rows]
|
||||
|
||||
|
||||
class TagMappingRequest(BaseModel):
|
||||
tag: str
|
||||
tag_label: str = ""
|
||||
company_id: str
|
||||
company_name: str = ""
|
||||
|
||||
|
||||
@app.post("/api/settings/tag-mappings")
|
||||
async def api_add_tag_mapping(req: TagMappingRequest):
|
||||
"""Add a tag → company mapping."""
|
||||
pool = await db.get_pool()
|
||||
try:
|
||||
row = await pool.fetchrow(
|
||||
"""INSERT INTO tag_company_mappings (tag, tag_label, company_id, company_name)
|
||||
VALUES ($1, $2, $3, $4)
|
||||
ON CONFLICT (tag, company_id) DO UPDATE SET tag_label = $2, company_name = $4
|
||||
RETURNING id, tag, tag_label, company_id, company_name""",
|
||||
req.tag, req.tag_label, req.company_id, req.company_name,
|
||||
)
|
||||
return dict(row)
|
||||
except Exception as e:
|
||||
raise HTTPException(400, str(e))
|
||||
|
||||
|
||||
@app.delete("/api/settings/tag-mappings/{mapping_id}")
|
||||
async def api_delete_tag_mapping(mapping_id: str):
|
||||
"""Delete a tag → company mapping."""
|
||||
pool = await db.get_pool()
|
||||
result = await pool.execute("DELETE FROM tag_company_mappings WHERE id = $1::uuid", mapping_id)
|
||||
if result == "DELETE 0":
|
||||
raise HTTPException(404, "Mapping not found")
|
||||
return {"ok": True}
|
||||
|
||||
|
||||
# ── Skill Management API ───────────────────────────────────────────
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user