klg-asutk-app/backend/app/api/routes/risk_alerts.py
Yuriy a7da43be0e apply recommendations: security, get_db, exceptions, eslint, api-client
- session: set_tenant use bound param (SQL injection fix)
- health: text('SELECT 1'), REDIS_URL from config
- deps: re-export get_db from session, use settings.ENABLE_DEV_AUTH (default False)
- routes: all get_db from app.api.deps; conftest overrides deps.get_db
- main: register exception handlers from app.api.exceptions
- next.config: enable ESLint and TypeScript checks
- .eslintrc: drop @typescript-eslint/recommended; fix no-console (logger, ws-client, regulations)
- backend/.env.example added
- frontend: export apiFetch; dashboard, profile, settings, risks use api-client
- docs/ANALYSIS_AND_RECOMMENDATIONS.md

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-14 21:48:58 +03:00

51 lines
2.2 KiB
Python

"""Risk alerts API — refactored: pagination, audit, DRY."""
from datetime import datetime, timezone
from fastapi import APIRouter, Depends, HTTPException, Query
from sqlalchemy.orm import Session
from app.api.deps import get_current_user, require_roles
from app.services.email_service import email_service
from app.api.helpers import audit, filter_by_org, paginate_query
from app.api.deps import get_db
from app.models import RiskAlert, Aircraft
from app.schemas.risk_alert import RiskAlertOut
from app.services.risk_scanner import scan_risks
router = APIRouter(tags=["risk-alerts"])
@router.get("/risk-alerts")
def list_risk_alerts(
aircraft_id: str | None = Query(None), severity: str | None = Query(None),
resolved: bool | None = Query(None),
page: int = Query(1, ge=1), per_page: int = Query(50, ge=1, le=100),
db: Session = Depends(get_db), user=Depends(get_current_user),
):
q = db.query(RiskAlert)
if aircraft_id: q = q.filter(RiskAlert.aircraft_id == aircraft_id)
if severity: q = q.filter(RiskAlert.severity == severity)
if resolved is not None: q = q.filter(RiskAlert.is_resolved == resolved)
q = filter_by_org(q.join(Aircraft), Aircraft, user)
q = q.order_by(RiskAlert.due_at.asc(), RiskAlert.severity.desc())
result = paginate_query(q, page, per_page)
result["items"] = [RiskAlertOut.model_validate(a) for a in result["items"]]
return result
@router.post("/risk-alerts/scan", dependencies=[Depends(require_roles("admin", "authority_inspector"))])
def trigger_risk_scan(db: Session = Depends(get_db), user=Depends(get_current_user)):
created = scan_risks(db)
audit(db, user, "create", "risk_alert", description=f"Risk scan: {created} alerts")
db.commit()
return {"created": created}
@router.patch("/risk-alerts/{alert_id}/resolve")
def resolve_alert(alert_id: str, db: Session = Depends(get_db), user=Depends(get_current_user)):
alert = db.query(RiskAlert).filter(RiskAlert.id == alert_id).first()
if not alert: raise HTTPException(404, "Not found")
alert.is_resolved = True; alert.resolved_at = datetime.now(timezone.utc)
audit(db, user, "update", "risk_alert", alert_id, description="Resolved")
db.commit(); db.refresh(alert)
return RiskAlertOut.model_validate(alert)