- 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>
28 lines
1.2 KiB
Python
28 lines
1.2 KiB
Python
"""Audit events API — now uses real AuditLog table."""
|
|
from fastapi import APIRouter, Depends, Query
|
|
from sqlalchemy.orm import Session
|
|
|
|
from app.api.deps import get_current_user, require_roles
|
|
from app.api.helpers import is_authority, paginate_query
|
|
from app.api.deps import get_db
|
|
from app.models.audit_log import AuditLog
|
|
|
|
router = APIRouter(tags=["audit"])
|
|
|
|
|
|
@router.get("/audit/events", dependencies=[Depends(require_roles("admin", "authority_inspector"))])
|
|
def list_audit_events(
|
|
entity_type: str | None = Query(None), entity_id: str | None = Query(None),
|
|
user_id: str | None = Query(None), action: str | 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(AuditLog)
|
|
if entity_type: q = q.filter(AuditLog.entity_type == entity_type)
|
|
if entity_id: q = q.filter(AuditLog.entity_id == entity_id)
|
|
if user_id: q = q.filter(AuditLog.user_id == user_id)
|
|
if action: q = q.filter(AuditLog.action == action)
|
|
if not is_authority(user): q = q.filter(AuditLog.organization_id == user.organization_id)
|
|
q = q.order_by(AuditLog.created_at.desc())
|
|
return paginate_query(q, page, per_page)
|