Spaces:
Runtime error
Runtime error
| """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"} | |
| 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} | |
| 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} | |