RICS / backend /api /routes /admin.py
StormShadow308's picture
Add demo documentation and Docker setup for v2 report generation system
aad7814
Raw
History Blame Contribute Delete
2.31 kB
"""Gated admin override for the operator master template.
Enabled only when ``master_template_upload_enabled=true`` and a valid admin token
is supplied (see :func:`backend.api.deps.require_admin`). Lets an operator replace
the master at runtime (re-discover schema + rebuild MASTER RAG) without redeploy.
"""
from __future__ import annotations
import shutil
import tempfile
from pathlib import Path
from fastapi import APIRouter, Depends, HTTPException, UploadFile, status
from backend.api.deps import require_admin
from backend.core import ingest, pii_scrubber
router = APIRouter(prefix="/admin", tags=["admin"])
_ALLOWED = {".docx", ".docm", ".doc", ".pdf"}
@router.post("/template", status_code=status.HTTP_201_CREATED)
async def override_template(
file: UploadFile,
tenant_id: str = Depends(require_admin),
) -> dict:
"""Replace the master template from an uploaded file."""
suffix = Path(file.filename or "").suffix.lower()
if suffix not in _ALLOWED:
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,
detail=f"Unsupported file type '{suffix}'. Allowed: {sorted(_ALLOWED)}",
)
tmp_dir = Path(tempfile.mkdtemp(prefix="rics_v2_master_"))
tmp_path = tmp_dir / (file.filename or f"master{suffix}")
try:
with tmp_path.open("wb") as out:
shutil.copyfileobj(file.file, out)
result = ingest.ingest_master(tenant_id, tmp_path)
except pii_scrubber.PiiDetectedError as exc:
raise HTTPException(status_code=status.HTTP_422_UNPROCESSABLE_ENTITY, detail=str(exc)) from exc
finally:
shutil.rmtree(tmp_dir, ignore_errors=True)
return {"status": "master_replaced", **result}
@router.post("/template/reingest")
async def reingest_template(tenant_id: str = Depends(require_admin)) -> dict:
"""Re-run schema discovery + standard-paragraph ingest from configured paths."""
try:
result = ingest.ingest_operator_bundle(tenant_id)
except pii_scrubber.PiiDetectedError as exc:
raise HTTPException(status_code=status.HTTP_422_UNPROCESSABLE_ENTITY, detail=str(exc)) from exc
except FileNotFoundError as exc:
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=str(exc)) from exc
return {"status": "reingested", **result}