Spaces:
Sleeping
Sleeping
chih.yikuan
✨ Add database management: Supabase persistence, teacher profiles, admin dashboard
9f97e28 | """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"]) | |
| async def admin_stats(_admin=Depends(get_current_admin)): | |
| stats = await get_stats() | |
| stats["schema_version"] = await get_schema_version() | |
| return stats | |
| async def admin_users(_admin=Depends(get_current_admin)): | |
| return {"users": await list_all_users()} | |
| class SetAdminRequest(BaseModel): | |
| is_admin: bool | |
| 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} | |
| 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"} | |
| async def admin_sessions(_admin=Depends(get_current_admin)): | |
| return {"sessions": await admin_list_sessions()} | |
| 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"} | |
| async def admin_students(_admin=Depends(get_current_admin)): | |
| return {"students": await admin_list_students()} | |
| 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)} | |