Permet de filtrer l'historique métier par période, membre, domaine, action et recherche texte. Ajoute les contrôles correspondants dans l'onglet Historique du module Journal.
102 lines
3.7 KiB
Python
102 lines
3.7 KiB
Python
"""Consultation du journal d'audit."""
|
|
from datetime import date, datetime, time, timezone
|
|
|
|
from fastapi import APIRouter, Depends
|
|
from sqlalchemy import or_, select
|
|
from sqlalchemy.ext.asyncio import AsyncSession
|
|
|
|
from app.core.database import get_db
|
|
from app.core.security import require_executif
|
|
from app.models.journal_action import JournalAction
|
|
from app.models.historique_modification import HistoriqueModification
|
|
from app.models.membre import Membre
|
|
|
|
router = APIRouter(prefix="/journal", tags=["Journal"])
|
|
|
|
|
|
@router.get("/actions")
|
|
async def journal_actions(
|
|
limite: int = 100,
|
|
executif=Depends(require_executif),
|
|
db: AsyncSession = Depends(get_db),
|
|
):
|
|
limite = max(1, min(limite, 500))
|
|
result = await db.execute(
|
|
select(JournalAction)
|
|
.where(JournalAction.groupe_id == executif.groupe_id)
|
|
.order_by(JournalAction.cree_le.desc())
|
|
.limit(limite)
|
|
)
|
|
return [
|
|
{
|
|
"id": str(item.id),
|
|
"groupe_id": str(item.groupe_id) if item.groupe_id else None,
|
|
"membre_id": str(item.membre_id) if item.membre_id else None,
|
|
"admin_id": str(item.admin_id) if item.admin_id else None,
|
|
"methode": item.methode,
|
|
"chemin": item.chemin,
|
|
"statut_http": item.statut_http,
|
|
"adresse_ip": item.adresse_ip,
|
|
"user_agent": item.user_agent,
|
|
"details": item.details,
|
|
"cree_le": item.cree_le.isoformat(),
|
|
}
|
|
for item in result.scalars().all()
|
|
]
|
|
|
|
|
|
@router.get("/historique")
|
|
async def historique_modifications(
|
|
limite: int = 100,
|
|
date_debut: date | None = None,
|
|
date_fin: date | None = None,
|
|
membre_id: str | None = None,
|
|
table_cible: str | None = None,
|
|
action: str | None = None,
|
|
q: str | None = None,
|
|
executif=Depends(require_executif),
|
|
db: AsyncSession = Depends(get_db),
|
|
):
|
|
limite = max(1, min(limite, 500))
|
|
query = select(HistoriqueModification).where(HistoriqueModification.groupe_id == executif.groupe_id)
|
|
if date_debut:
|
|
query = query.where(HistoriqueModification.cree_le >= datetime.combine(date_debut, time.min, tzinfo=timezone.utc))
|
|
if date_fin:
|
|
query = query.where(HistoriqueModification.cree_le <= datetime.combine(date_fin, time.max, tzinfo=timezone.utc))
|
|
if membre_id:
|
|
query = query.where(HistoriqueModification.membre_id == membre_id)
|
|
if table_cible:
|
|
query = query.where(HistoriqueModification.table_cible == table_cible)
|
|
if action:
|
|
query = query.where(HistoriqueModification.action == action)
|
|
if q:
|
|
terme = f"%{q.strip()}%"
|
|
query = query.where(or_(
|
|
HistoriqueModification.raison.ilike(terme),
|
|
HistoriqueModification.action.ilike(terme),
|
|
HistoriqueModification.table_cible.ilike(terme),
|
|
))
|
|
result = await db.execute(
|
|
query
|
|
.order_by(HistoriqueModification.cree_le.desc())
|
|
.limit(limite)
|
|
)
|
|
items = result.scalars().all()
|
|
lignes = []
|
|
for item in items:
|
|
membre = await db.get(Membre, item.membre_id) if item.membre_id else None
|
|
lignes.append({
|
|
"id": str(item.id),
|
|
"table_cible": item.table_cible,
|
|
"objet_id": str(item.objet_id),
|
|
"action": item.action,
|
|
"raison": item.raison,
|
|
"membre_id": str(item.membre_id) if item.membre_id else None,
|
|
"membre_prenom": membre.prenom if membre else None,
|
|
"admin_id": str(item.admin_id) if item.admin_id else None,
|
|
"chemin_api": item.chemin_api,
|
|
"avant": item.avant,
|
|
"apres": item.apres,
|
|
"cree_le": item.cree_le.isoformat(),
|
|
})
|
|
return lignes
|