Update teacher profiles and record summaries

This commit is contained in:
Codex
2026-06-16 01:09:51 +08:00
parent a7fbe91266
commit 2785f3eb41
18 changed files with 1088 additions and 40 deletions
+46 -2
View File
@@ -2,7 +2,7 @@ from __future__ import annotations
from fastapi import APIRouter, Depends, HTTPException, Query, Request
from ..api_utils import file_meta, load_accounts, payload_to_account, read_register_payload
from ..api_utils import file_meta, load_accounts, load_teachers, payload_to_account, payload_to_teacher, read_register_payload
from ..auth import verify_accounts_auth, verify_admin_auth
from ..config import (
ACCOUNTS_PATH,
@@ -11,21 +11,26 @@ from ..config import (
COURSE_SUMMARIES_ROOT,
COURSE_SUMMARY_STATE_PATH,
OPERATION_LOGS_PATH,
TEACHERS_PATH,
write_lock,
)
from ..data import (
ACCOUNT_STATUSES,
TEACHER_STATUSES,
DuplicateRecordError,
account_summary,
account_to_dict,
create_account,
create_teacher,
filter_accounts,
register_class_record_lines,
register_course_summary_texts,
register_payment_lines,
teacher_to_dict,
update_account,
update_teacher,
)
from ..schemas import AccountPayload
from ..schemas import AccountPayload, TeacherPayload
router = APIRouter()
@@ -83,10 +88,13 @@ async def register_course_summaries(request: Request, _user: str = Depends(verif
@router.get("/api/account-health")
def account_health(_user: str = Depends(verify_accounts_auth)):
accounts = load_accounts()
teachers = load_teachers()
return {
"ok": True,
"accounts": file_meta(ACCOUNTS_PATH),
"teachers": file_meta(TEACHERS_PATH),
"accounts_count": len(accounts),
"teachers_count": len(teachers),
"account_summary": account_summary(accounts),
}
@@ -119,6 +127,42 @@ def admin_statuses(_user: str = Depends(verify_admin_auth)):
return {"account_statuses": sorted(ACCOUNT_STATUSES)}
@router.get("/api/admin/teacher-statuses")
def admin_teacher_statuses(_user: str = Depends(verify_admin_auth)):
return {"teacher_statuses": sorted(TEACHER_STATUSES)}
@router.get("/api/admin/teachers")
def admin_teachers(_user: str = Depends(verify_admin_auth)):
return {
"teachers": [teacher_to_dict(teacher) for teacher in load_teachers()],
}
@router.post("/api/admin/teachers")
def admin_create_teacher(payload: TeacherPayload, _user: str = Depends(verify_admin_auth)):
try:
with write_lock:
result = create_teacher(TEACHERS_PATH, payload_to_teacher(payload))
except ValueError as exc:
raise HTTPException(status_code=400, detail=str(exc)) from exc
return {"ok": True, **result}
@router.put("/api/admin/teachers/{teacher_id}")
def admin_update_teacher(teacher_id: str, payload: TeacherPayload, _user: str = Depends(verify_admin_auth)):
try:
with write_lock:
result = update_teacher(
TEACHERS_PATH,
teacher_id,
payload_to_teacher(payload, teacher_id=payload.teacher_id.strip() or teacher_id),
)
except ValueError as exc:
raise HTTPException(status_code=400, detail=str(exc)) from exc
return {"ok": True, **result}
@router.post("/api/admin/accounts")
def admin_create_account(payload: AccountPayload, _user: str = Depends(verify_admin_auth)):
try:
+39
View File
@@ -14,10 +14,12 @@ from ..config import (
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,
)
@@ -61,6 +63,7 @@ def admin_course_summaries(
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),
):
@@ -73,6 +76,7 @@ def admin_course_summaries(
subject=subject,
date_from=date_from,
date_to=date_to,
missing_time=missing_time,
limit=limit,
)
except ValueError as exc:
@@ -117,3 +121,38 @@ def admin_reject_task(task_id: int, _user: str = Depends(verify_admin_auth)):
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}
+5 -1
View File
@@ -2,7 +2,7 @@ from __future__ import annotations
from fastapi import APIRouter, Depends
from ..api_utils import file_meta, load_accounts, load_records
from ..api_utils import file_meta, load_accounts, load_records, load_teachers
from ..auth import verify_records_auth
from ..config import (
ACCOUNTS_PATH,
@@ -10,6 +10,7 @@ from ..config import (
COURSE_SUMMARIES_ROOT,
COURSE_SUMMARY_STATE_PATH,
OPERATION_LOGS_PATH,
TEACHERS_PATH,
)
from ..data import account_summary
@@ -21,14 +22,17 @@ router = APIRouter()
def health(_user: str = Depends(verify_records_auth)):
records = load_records()
accounts = load_accounts()
teachers = load_teachers()
return {
"ok": True,
"classnotes": file_meta(CLASSNOTES_PATH),
"accounts": file_meta(ACCOUNTS_PATH),
"teachers": file_meta(TEACHERS_PATH),
"course_summaries": file_meta(COURSE_SUMMARIES_ROOT),
"course_summary_state": file_meta(COURSE_SUMMARY_STATE_PATH),
"operation_logs": file_meta(OPERATION_LOGS_PATH),
"records_count": len(records),
"accounts_count": len(accounts),
"teachers_count": len(teachers),
"account_summary": account_summary(accounts),
}
+14 -6
View File
@@ -2,10 +2,15 @@ from __future__ import annotations
from fastapi import APIRouter, Depends, HTTPException, Query
from ..api_utils import load_accounts, load_records
from ..api_utils import load_accounts, load_records, load_teachers
from ..auth import verify_records_auth
from ..config import ADMIN_TASKS_PATH
from ..data import account_to_dict, query_records, submit_correction_tasks, submit_deletion_tasks
from ..config import ADMIN_TASKS_PATH, COURSE_SUMMARIES_ROOT
from ..data import (
account_to_dict,
query_public_records,
submit_public_correction_tasks,
submit_public_deletion_tasks,
)
from ..schemas import CorrectionSubmitPayload, DeletionSubmitPayload
@@ -18,7 +23,7 @@ def records(
limit: int = Query(200, ge=1, le=1000),
_user: str = Depends(verify_records_auth),
):
return query_records(load_records(), q, limit=limit)
return query_public_records(load_records(), load_teachers(), q, limit=limit, summaries_root=COURSE_SUMMARIES_ROOT)
@router.get("/api/student-account/{student}")
@@ -32,8 +37,10 @@ def record_student_account(student: str, _user: str = Depends(verify_records_aut
@router.post("/api/corrections")
def submit_corrections(payload: CorrectionSubmitPayload, _user: str = Depends(verify_records_auth)):
try:
result = submit_correction_tasks(
result = submit_public_correction_tasks(
ADMIN_TASKS_PATH,
load_records(),
load_teachers(),
[item.dict() for item in payload.items],
)
except ValueError as exc:
@@ -44,8 +51,9 @@ def submit_corrections(payload: CorrectionSubmitPayload, _user: str = Depends(ve
@router.post("/api/deletions")
def submit_deletions(payload: DeletionSubmitPayload, _user: str = Depends(verify_records_auth)):
try:
result = submit_deletion_tasks(
result = submit_public_deletion_tasks(
ADMIN_TASKS_PATH,
load_records(),
[item.dict() for item in payload.items],
)
except ValueError as exc: