111 lines
4.0 KiB
Python
111 lines
4.0 KiB
Python
from sqlalchemy import func
|
|
from fastapi import APIRouter, Depends, HTTPException
|
|
from sqlalchemy.orm import Session
|
|
|
|
from app.database import get_db
|
|
from app.models import Alert, Rating, Report, Route, User
|
|
from app.schemas import (
|
|
AlertOut,
|
|
AssignOperatorIn,
|
|
DashboardOut,
|
|
ReportOut,
|
|
ReportStatusUpdate,
|
|
RouteOut,
|
|
UserOut,
|
|
)
|
|
from app.security import require_role
|
|
|
|
router = APIRouter(prefix="/admin", tags=["Admin"])
|
|
|
|
|
|
@router.get("/dashboard", response_model=DashboardOut)
|
|
def dashboard(db: Session = Depends(get_db), admin: User = Depends(require_role("admin"))):
|
|
routes_total = db.query(Route).count()
|
|
active_routes = db.query(Route).filter(Route.status.in_(["EN_RUTA", "RETRASO", "AVERIA", "INCIDENCIA"])).count()
|
|
trucks_total = db.query(func.count(func.distinct(Route.truck_id))).scalar() or 0
|
|
operators_total = db.query(User).filter(User.role == "operador").count()
|
|
alerts_open = db.query(Alert).filter(Alert.status != "CERRADA").count()
|
|
reports_open = db.query(Report).filter(Report.status.in_(["NUEVO", "EN_REVISION"])).count()
|
|
avg = db.query(func.avg(Rating.stars)).scalar()
|
|
|
|
return DashboardOut(
|
|
routes_total=routes_total,
|
|
active_routes=active_routes,
|
|
trucks_total=trucks_total,
|
|
operators_total=operators_total,
|
|
alerts_open=alerts_open,
|
|
reports_open=reports_open,
|
|
average_rating=round(float(avg or 0), 2),
|
|
)
|
|
|
|
|
|
@router.get("/users", response_model=list[UserOut])
|
|
def users(db: Session = Depends(get_db), admin: User = Depends(require_role("admin"))):
|
|
return db.query(User).order_by(User.role.asc(), User.name.asc()).all()
|
|
|
|
|
|
@router.get("/operators", response_model=list[UserOut])
|
|
def operators(db: Session = Depends(get_db), admin: User = Depends(require_role("admin"))):
|
|
return db.query(User).filter(User.role == "operador").order_by(User.name.asc()).all()
|
|
|
|
|
|
@router.get("/routes", response_model=list[RouteOut])
|
|
def routes(db: Session = Depends(get_db), admin: User = Depends(require_role("admin"))):
|
|
return db.query(Route).order_by(Route.route_id.asc()).all()
|
|
|
|
|
|
@router.post("/routes/{route_id}/assign-operator", response_model=RouteOut)
|
|
def assign_operator(
|
|
route_id: str,
|
|
payload: AssignOperatorIn,
|
|
db: Session = Depends(get_db),
|
|
admin: User = Depends(require_role("admin")),
|
|
):
|
|
route = db.get(Route, route_id)
|
|
if not route:
|
|
raise HTTPException(status_code=404, detail="Ruta no encontrada")
|
|
operator = db.get(User, payload.operator_id)
|
|
if not operator or operator.role != "operador":
|
|
raise HTTPException(status_code=422, detail="Operador inválido")
|
|
route.assigned_operator_id = operator.id
|
|
db.commit()
|
|
db.refresh(route)
|
|
return route
|
|
|
|
|
|
@router.get("/alerts", response_model=list[AlertOut])
|
|
def alerts(db: Session = Depends(get_db), admin: User = Depends(require_role("admin"))):
|
|
return db.query(Alert).order_by(Alert.created_at.desc()).limit(100).all()
|
|
|
|
|
|
@router.patch("/alerts/{alert_id}/close", response_model=AlertOut)
|
|
def close_alert(alert_id: int, db: Session = Depends(get_db), admin: User = Depends(require_role("admin"))):
|
|
alert = db.get(Alert, alert_id)
|
|
if not alert:
|
|
raise HTTPException(status_code=404, detail="Alerta no encontrada")
|
|
alert.status = "CERRADA"
|
|
db.commit()
|
|
db.refresh(alert)
|
|
return alert
|
|
|
|
|
|
@router.get("/reports", response_model=list[ReportOut])
|
|
def reports(db: Session = Depends(get_db), admin: User = Depends(require_role("admin"))):
|
|
return db.query(Report).order_by(Report.created_at.desc()).limit(100).all()
|
|
|
|
|
|
@router.patch("/reports/{report_id}/status", response_model=ReportOut)
|
|
def update_report_status(
|
|
report_id: int,
|
|
payload: ReportStatusUpdate,
|
|
db: Session = Depends(get_db),
|
|
admin: User = Depends(require_role("admin")),
|
|
):
|
|
report = db.get(Report, report_id)
|
|
if not report:
|
|
raise HTTPException(status_code=404, detail="Reporte no encontrado")
|
|
report.status = payload.status
|
|
db.commit()
|
|
db.refresh(report)
|
|
return report
|