ClassLens / chatkit /backend /app /admin.py
chih.yikuan
✨ Add database management: Supabase persistence, teacher profiles, admin dashboard
9f97e28
Raw
History Blame
2.64 kB
"""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)}