Spaces:
Running
Running
| """superadmin/routers/platform.py β Platform-wide operations. | |
| Routes: | |
| GET / | |
| GET /diag | |
| GET /health | |
| GET /audit | |
| POST /announce | |
| POST /backup | |
| """ | |
| from fastapi import APIRouter, Depends, Query | |
| from sqlalchemy.ext.asyncio import AsyncSession | |
| from app.dependencies import check_health, get_db, get_current_superadmin | |
| from app.repositories.audit_repo import AuditRepository | |
| from app.schemas.admin import AnnouncementRequest | |
| from app.superadmin.routers._utils import _err | |
| router = APIRouter() | |
| async def superadmin_index(): | |
| """SuperAdmin API index β lists available endpoints.""" | |
| return { | |
| "message": "SuperAdmin API. Requires SuperAdmin JWT (Bearer token).", | |
| "endpoints": { | |
| "list_authors": "GET /api/super/authors", | |
| "create_author": "POST /api/super/authors", | |
| "suspend_author": "POST /api/super/authors/{id}/suspend", | |
| "grant_access": "POST /api/super/authors/{id}/grant", | |
| "revoke_access": "POST /api/super/grants/{id}/revoke", | |
| "audit_log": "GET /api/super/audit", | |
| "platform_health": "GET /api/super/health", | |
| }, | |
| "docs": "/docs", | |
| } | |
| async def diagnostic(superadmin=Depends(get_current_superadmin)): | |
| """R-045: Diagnostic endpoint β requires SuperAdmin auth.""" | |
| return {"status": "ok", "router": "superadmin", "auth": "verified"} | |
| async def platform_health(superadmin=Depends(get_current_superadmin)): | |
| """Platform health: Redis, ChromaDB, DB status.""" | |
| try: | |
| return await check_health() | |
| except Exception as e: | |
| return _err(e, "platform_health") | |
| async def get_audit_log( | |
| limit: int = Query(100, ge=1, le=500), | |
| cursor: str | None = Query(None), | |
| actor_id: str | None = Query(None), | |
| action: str | None = Query(None), | |
| superadmin=Depends(get_current_superadmin), | |
| db: AsyncSession = Depends(get_db), | |
| ): | |
| """Retrieve the immutable audit log. No DELETE allowed.""" | |
| try: | |
| audit_repo = AuditRepository(db) | |
| entries = await audit_repo.list_recent( | |
| limit=limit, cursor=cursor, actor_id=actor_id, action=action | |
| ) | |
| result = [ | |
| { | |
| "id": e.id, | |
| "timestamp": e.timestamp.isoformat() if e.timestamp else None, | |
| "actor_email": e.actor_email, | |
| "action": e.action, | |
| "target_type": e.target_type, | |
| "target_id": e.target_id, | |
| "details": e.details, | |
| } | |
| for e in entries | |
| ] | |
| return {"entries": result, "count": len(result)} | |
| except Exception as e: | |
| return _err(e, "get_audit_log") | |
| async def broadcast_announcement( | |
| body: AnnouncementRequest, | |
| superadmin=Depends(get_current_superadmin), | |
| db: AsyncSession = Depends(get_db), | |
| ): | |
| """Broadcast an announcement visible to all authors. R-029: Validated via Pydantic schema.""" | |
| try: | |
| audit_repo = AuditRepository(db) | |
| await audit_repo.log( | |
| actor_id=superadmin.id, | |
| actor_email=superadmin.email, | |
| action="broadcast_announcement", | |
| target_type="platform", | |
| target_id=None, | |
| details={"message": body.message}, | |
| ) | |
| return {"message": "Announcement sent"} | |
| except Exception as e: | |
| return _err(e, "broadcast_announcement") | |
| async def trigger_backup( | |
| superadmin=Depends(get_current_superadmin), | |
| db: AsyncSession = Depends(get_db), | |
| ): | |
| """Dispatch backup to Celery worker (R-080 β non-blocking).""" | |
| try: | |
| from app.tasks.backup_task import run_backup | |
| task = run_backup.delay() | |
| audit_repo = AuditRepository(db) | |
| await audit_repo.log( | |
| actor_id=superadmin.id, | |
| actor_email=superadmin.email, | |
| action="trigger_backup", | |
| target_type="platform", | |
| target_id=None, | |
| details={"task_id": task.id}, | |
| ) | |
| return {"message": "Backup dispatched", "task_id": task.id} | |
| except Exception as e: | |
| return _err(e, "trigger_backup") | |