groupe-meditation/backend/app/schemas/phase4.py
Daniel Allaire 6677b0f57b Ajouter historique métier et protection concurrente
Ajoute modifie_le aux objets sensibles et fait transmettre la version affichée par le frontend pour refuser les écritures périmées avec un message HTTP 409.

Ajoute une table historique_modifications et un service d'historique métier afin de journaliser automatiquement les raisons des changements importants sans intervention de l'utilisateur.

Expose l'historique métier dans le module Journal, distinct du journal technique, et documente les processus utilisateurs ainsi qu'une présentation sobre aux membres.
2026-05-31 10:59:41 -04:00

99 lines
2.2 KiB
Python

"""Schémas Phase 4 — PV, Présences, Rapport RSG."""
from pydantic import BaseModel
from datetime import date, datetime
from uuid import UUID
from typing import Optional
# ── M2 Présences (réunion d'affaires) ──
class PresenceItem(BaseModel):
membre_id: UUID
present: bool = True
class PresencesBatch(BaseModel):
reunion_id: UUID
presences: list[PresenceItem]
class PresenceOut(BaseModel):
membre_id: UUID
membre_prenom: str
present: bool
class ReunionAffairesCreate(BaseModel):
"""Créer une réunion d'affaires (pour les présences et le PV)."""
date_reunion: datetime
note: Optional[str] = None
class ReunionAffairesOut(BaseModel):
id: UUID
date_reunion: datetime
note: Optional[str] = None
modifie_le: Optional[datetime] = None
presences: list[PresenceOut] = []
model_config = {"from_attributes": True}
# ── M1 Procès-verbal ──
class DecisionPV(BaseModel):
sujet: str
decision: str
proposeur: Optional[str] = None
secondeur: Optional[str] = None
statut: str = "en_attente"
class PvCreate(BaseModel):
reunion_id: UUID
contenu: str
decisions: Optional[list[DecisionPV]] = None
class PvOut(BaseModel):
id: UUID
reunion_id: UUID
redacteur_prenom: str
contenu: str
decisions: Optional[list[dict]] = None
approuve: bool
cree_le: datetime
modifie_le: datetime
date_reunion: Optional[datetime] = None
model_config = {"from_attributes": True}
class PvUpdate(BaseModel):
contenu: Optional[str] = None
decisions: Optional[list[DecisionPV]] = None
approuve: Optional[bool] = None
class PvAdoption(BaseModel):
proposeur_id: UUID
secondeur_id: UUID
contenu: Optional[str] = None
# ── M3 Rapport RSG ──
class RapportRsgCreate(BaseModel):
reunion_dist: date
decisions: Optional[list[str]] = None
infos_region: Optional[str] = None
sujets_groupe: Optional[str] = None
class RapportRsgOut(BaseModel):
id: UUID
reunion_dist: date
redacteur_prenom: str
decisions: Optional[list[str]] = None
infos_region: Optional[str] = None
sujets_groupe: Optional[str] = None
cree_le: datetime
model_config = {"from_attributes": True}