from __future__ import annotations from fastapi import APIRouter, Depends, HTTPException, Query from ..auth import verify_admin_auth from ..config import ( ACCOUNTS_PATH, ADMIN_TASKS_PATH, CLASSNOTES_PATH, COURSE_SUMMARIES_ROOT, OPERATION_LOGS_PATH, write_lock, ) from ..data import ( append_operation_log, approve_admin_task, delete_course_summary, list_admin_tasks, list_operation_logs, query_course_summaries, reject_admin_task, update_course_summary_time, ) router = APIRouter() @router.get("/api/admin/tasks") def admin_tasks( status_filter: str = Query("", alias="status"), task_type: str = Query("", alias="type"), _user: str = Depends(verify_admin_auth), ): try: return list_admin_tasks(ADMIN_TASKS_PATH, status_filter=status_filter, task_type=task_type) except ValueError as exc: raise HTTPException(status_code=500, detail=str(exc)) from exc @router.get("/api/admin/operation-logs") def admin_operation_logs( limit: int = Query(100, ge=1, le=500), operation: str = Query(""), status_filter: str = Query("", alias="status"), student: str = Query(""), _user: str = Depends(verify_admin_auth), ): return list_operation_logs( OPERATION_LOGS_PATH, limit=limit, operation=operation, status_filter=status_filter, student=student, ) @router.get("/api/admin/course-summaries") def admin_course_summaries( q: str = Query(""), student: str = Query(""), teacher: str = Query(""), subject: str = Query(""), date_from: str = Query(""), date_to: str = Query(""), missing_time: bool = Query(False), limit: int = Query(200, ge=1, le=1000), _user: str = Depends(verify_admin_auth), ): try: return query_course_summaries( COURSE_SUMMARIES_ROOT, q=q, student=student, teacher=teacher, subject=subject, date_from=date_from, date_to=date_to, missing_time=missing_time, limit=limit, ) except ValueError as exc: raise HTTPException(status_code=400, detail=str(exc)) from exc @router.post("/api/admin/tasks/{task_id}/approve") def admin_approve_task(task_id: int, _user: str = Depends(verify_admin_auth)): try: with write_lock: result = approve_admin_task(ADMIN_TASKS_PATH, CLASSNOTES_PATH, ACCOUNTS_PATH, task_id) task = result.get("task", {}) append_operation_log( OPERATION_LOGS_PATH, "admin_task_approve", "approved", task_id=task_id, task_type=str(task.get("type") or ""), student=str(task.get("student") or task.get("corrected", {}).get("student") or ""), source_id=str(task.get("source_id") or ""), backup_id=str(result.get("backup_id") or task.get("backup_id") or ""), ) except ValueError as exc: raise HTTPException(status_code=409, detail=str(exc)) from exc return {"ok": True, **result} @router.post("/api/admin/tasks/{task_id}/reject") def admin_reject_task(task_id: int, _user: str = Depends(verify_admin_auth)): try: with write_lock: task = reject_admin_task(ADMIN_TASKS_PATH, task_id) append_operation_log( OPERATION_LOGS_PATH, "admin_task_reject", "rejected", task_id=task_id, task_type=str(task.get("type") or ""), student=str(task.get("student") or task.get("corrected", {}).get("student") or ""), source_id=str(task.get("source_id") or ""), ) except ValueError as exc: raise HTTPException(status_code=400, detail=str(exc)) from exc return {"ok": True, "task": task} @router.post("/api/admin/course-summaries/{summary_id}/time") def admin_update_course_summary_time(summary_id: str, payload: dict, _user: str = Depends(verify_admin_auth)): try: with write_lock: result = update_course_summary_time(COURSE_SUMMARIES_ROOT, summary_id, str(payload.get("time_range") or "")) append_operation_log( OPERATION_LOGS_PATH, "admin_course_summary_update_time", "updated", summary_id=summary_id, time_range=str(payload.get("time_range") or ""), backup_id=str(result.get("backup_id") or ""), ) except ValueError as exc: raise HTTPException(status_code=400, detail=str(exc)) from exc return {"ok": True, **result} @router.delete("/api/admin/course-summaries/{summary_id}") def admin_delete_course_summary(summary_id: str, _user: str = Depends(verify_admin_auth)): try: with write_lock: result = delete_course_summary(COURSE_SUMMARIES_ROOT, summary_id) append_operation_log( OPERATION_LOGS_PATH, "admin_course_summary_delete", "deleted", summary_id=summary_id, backup_id=str(result.get("backup_id") or ""), ) except ValueError as exc: raise HTTPException(status_code=400, detail=str(exc)) from exc return {"ok": True, **result}