Files
MobilityOps/backend/app/api/routers/audit.py
T
NuklearRabbit 03c5b60235 M1: implement operational core
Demo auth, seed import/reset, dashboard, vehicle/booking list+detail, audit trail. Backend: 19 tests passing, ruff clean. Frontend: React Router shell, typed API client, responsive pages. Verified end-to-end via curl and browser.
2026-08-01 21:20:53 +02:00

48 lines
1.6 KiB
Python

from __future__ import annotations
from fastapi import APIRouter, Depends, Query
from sqlalchemy import select
from sqlalchemy.orm import Session
from app.api.deps import get_current_user, get_db
from app.models.audit import AuditEvent
from app.schemas import AuditEventOut, CurrentUser
router = APIRouter(prefix="/api/v1/audit", tags=["audit"])
@router.get("", response_model=list[AuditEventOut])
def list_audit_events(
actor_label: str | None = Query(default=None),
action: str | None = Query(default=None),
entity_type: str | None = Query(default=None),
correlation_id: str | None = Query(default=None),
limit: int = Query(default=100, le=500),
db: Session = Depends(get_db),
_user: CurrentUser = Depends(get_current_user),
) -> list[AuditEventOut]:
stmt = select(AuditEvent).order_by(AuditEvent.occurred_at.desc()).limit(limit)
if actor_label:
stmt = stmt.where(AuditEvent.actor_label == actor_label)
if action:
stmt = stmt.where(AuditEvent.action == action)
if entity_type:
stmt = stmt.where(AuditEvent.entity_type == entity_type)
if correlation_id:
stmt = stmt.where(AuditEvent.correlation_id == correlation_id)
events = db.scalars(stmt).all()
return [
AuditEventOut(
id=str(e.id),
actor_type=e.actor_type,
actor_label=e.actor_label,
action=e.action,
entity_type=e.entity_type,
entity_id=str(e.entity_id) if e.entity_id else None,
correlation_id=str(e.correlation_id),
occurred_at=e.occurred_at,
metadata=e.metadata_json,
)
for e in events
]