Spaces:
Sleeping
Sleeping
| from fastapi import APIRouter, HTTPException, Query, Depends | |
| from typing import Optional | |
| from pydantic import BaseModel | |
| import database as db | |
| router = APIRouter(prefix="/admin", tags=["admin"]) | |
| import time | |
| _admin_cache = {} | |
| def verify_admin(email: str = Query(...)): | |
| """Dependency to check if user is admin.""" | |
| now = time.time() | |
| if email in _admin_cache and now - _admin_cache[email] < 3600: | |
| return email | |
| with db.db_cursor() as cur: | |
| cur.execute('SELECT role FROM "user" WHERE email = %s', (email,)) | |
| row = cur.fetchone() | |
| if not row or row["role"] != "admin": | |
| raise HTTPException(status_code=403, detail="Admin privileges required") | |
| _admin_cache[email] = now | |
| return email | |
| class SchoolCreate(BaseModel): | |
| school_name: str | |
| class ProgramCreate(BaseModel): | |
| school_id: int | |
| program_name: str | |
| credit_weightage: float | |
| total_eligible_students: int | |
| class OfficerUpdate(BaseModel): | |
| name: str | |
| phone: Optional[str] = None | |
| class StudentCreate(BaseModel): | |
| name: str | |
| usn: str | |
| school_id: int | |
| program_id: int | |
| batch: str | |
| is_active: bool = True | |
| # --- Schools --- | |
| def get_schools(email: str = Depends(verify_admin)): | |
| return db.get_all_schools() | |
| def create_school(body: SchoolCreate, email: str = Depends(verify_admin)): | |
| return db.create_school(body.school_name) | |
| def delete_school(school_id: int, email: str = Depends(verify_admin)): | |
| success = db.delete_school(school_id) | |
| if not success: | |
| raise HTTPException(status_code=404, detail="School not found") | |
| return {"status": "ok"} | |
| # --- Programs --- | |
| def get_programs(email: str = Depends(verify_admin)): | |
| return db.get_all_programs() | |
| def create_program(body: ProgramCreate, email: str = Depends(verify_admin)): | |
| return db.create_program(body.school_id, body.program_name, body.credit_weightage, body.total_eligible_students) | |
| def delete_program(program_id: int, email: str = Depends(verify_admin)): | |
| success = db.delete_program(program_id) | |
| if not success: | |
| raise HTTPException(status_code=404, detail="Program not found") | |
| return {"status": "ok"} | |
| # --- Officers --- | |
| def get_officers(email: str = Depends(verify_admin)): | |
| return db.get_all_officers() | |
| def get_officer_history_admin(officer_id: int, year: int = Query(...), email: str = Depends(verify_admin)): | |
| import datetime | |
| now = datetime.datetime.now() | |
| # 1. Fetch history first (1 query) | |
| rows = db.get_officer_history(officer_id, year) | |
| # 2. Check if current month is missing | |
| if year == now.year: | |
| has_current = any(r["month"] == now.month for r in rows) | |
| if not has_current: | |
| from main import recalculate_and_save_snapshot | |
| snapshot = recalculate_and_save_snapshot(officer_id, now.month, now.year) | |
| rows.append({ | |
| "month": now.month, | |
| "starting_pool": snapshot["starting_pool"], | |
| "target": snapshot["target"], | |
| "placed": snapshot["placed"], | |
| "prism_credits": snapshot["prism_credits"], | |
| "prism_score": snapshot["prism_score"] | |
| }) | |
| rows.sort(key=lambda x: x["month"]) | |
| return [ | |
| { | |
| "month": r["month"], | |
| "starting_pool": r["starting_pool"], | |
| "target": r["target"], | |
| "placed": r["placed"], | |
| "prism_credits": r["prism_credits"], | |
| "score": r["prism_score"], | |
| } | |
| for r in rows | |
| ] | |
| def update_officer(officer_id: int, body: OfficerUpdate, email: str = Depends(verify_admin)): | |
| res = db.update_officer(officer_id, body.name, body.phone) | |
| if not res: | |
| raise HTTPException(status_code=404, detail="Officer not found") | |
| return res | |
| def delete_officer(officer_id: int, email: str = Depends(verify_admin)): | |
| success = db.delete_officer(officer_id) | |
| if not success: | |
| raise HTTPException(status_code=404, detail="Officer not found") | |
| return {"status": "ok"} | |
| # --- Officer-Program Assignments --- | |
| def assign_program(officer_id: int, program_id: int, email: str = Depends(verify_admin)): | |
| db.assign_officer_to_program(officer_id, program_id) | |
| return {"status": "assigned"} | |
| def unassign_program(officer_id: int, program_id: int, email: str = Depends(verify_admin)): | |
| db.unassign_officer_from_program(officer_id, program_id) | |
| return {"status": "unassigned"} | |
| def get_officer_programs(officer_id: int, email: str = Depends(verify_admin)): | |
| return db.get_officer_programs(officer_id) | |
| # --- Students --- | |
| def get_students(email: str = Depends(verify_admin)): | |
| return db.get_all_students(active_only=False) | |
| def create_student(body: StudentCreate, email: str = Depends(verify_admin)): | |
| return db.create_student(body.name, body.usn, body.school_id, body.program_id, body.batch, body.is_active) | |
| def delete_student(student_id: int, email: str = Depends(verify_admin)): | |
| success = db.delete_student(student_id) | |
| if not success: | |
| raise HTTPException(status_code=404, detail="Student not found") | |
| return {"status": "ok"} | |