"""Admin-only API: analytics dashboard, user/session management, schema info. All routes require an admin teacher (see auth.get_current_admin). """ from __future__ import annotations from fastapi import APIRouter, Depends, HTTPException from pydantic import BaseModel from .auth import get_current_admin from .database import ( admin_list_sessions, admin_list_students, delete_session, delete_user, get_schema_version, get_session, get_stats, get_student, get_student_timeline, list_all_users, set_user_admin, ) router = APIRouter(prefix="/api/admin", tags=["admin"]) @router.get("/stats") async def admin_stats(_admin=Depends(get_current_admin)): stats = await get_stats() stats["schema_version"] = await get_schema_version() return stats @router.get("/users") async def admin_users(_admin=Depends(get_current_admin)): return {"users": await list_all_users()} class SetAdminRequest(BaseModel): is_admin: bool @router.put("/users/{user_id}/admin") async def admin_set_admin(user_id: int, body: SetAdminRequest, admin=Depends(get_current_admin)): if user_id == admin["id"] and not body.is_admin: raise HTTPException(status_code=400, detail="You cannot remove your own admin access") await set_user_admin(user_id, body.is_admin) return {"status": "ok", "user_id": user_id, "is_admin": body.is_admin} @router.delete("/users/{user_id}") async def admin_delete_user(user_id: int, admin=Depends(get_current_admin)): if user_id == admin["id"]: raise HTTPException(status_code=400, detail="You cannot delete your own account here") await delete_user(user_id) return {"status": "deleted"} @router.get("/sessions") async def admin_sessions(_admin=Depends(get_current_admin)): return {"sessions": await admin_list_sessions()} @router.delete("/sessions/{session_id}") async def admin_delete_session(session_id: int, _admin=Depends(get_current_admin)): if not await get_session(session_id): raise HTTPException(status_code=404, detail="Session not found") await delete_session(session_id) return {"status": "deleted"} @router.get("/students") async def admin_students(_admin=Depends(get_current_admin)): return {"students": await admin_list_students()} @router.get("/students/{student_id}") async def admin_student_detail(student_id: int, _admin=Depends(get_current_admin)): student = await get_student(student_id) if not student: raise HTTPException(status_code=404, detail="Student not found") return {"student": student, "timeline": await get_student_timeline(student_id)}