Agrega backend FastAPI al proyecto

This commit is contained in:
Erick Cesar Mondragon Palacios
2026-05-22 23:15:56 -06:00
parent 4f2e099ea8
commit 7da903a0ab
18 changed files with 1502 additions and 0 deletions

View File

@@ -0,0 +1,110 @@
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