155 lines
3.3 KiB
Python
155 lines
3.3 KiB
Python
"""Schémas Pydantic pour validation et sérialisation."""
|
|
from pydantic import BaseModel
|
|
from datetime import date, datetime
|
|
from uuid import UUID
|
|
from typing import Optional
|
|
|
|
|
|
# ── Auth ──
|
|
class ConnexionRequest(BaseModel):
|
|
courriel: str
|
|
pin: str
|
|
groupe_id: UUID
|
|
se_souvenir: bool = False
|
|
|
|
|
|
class InscriptionRequest(BaseModel):
|
|
prenom: str
|
|
nom: Optional[str] = None
|
|
pin: str
|
|
code_invitation: str
|
|
telephone: str
|
|
courriel: str
|
|
date_abstinence: Optional[date] = None
|
|
|
|
|
|
class TokenResponse(BaseModel):
|
|
access_token: str
|
|
token_type: str = "bearer"
|
|
membre: "MembrePublic"
|
|
|
|
|
|
# ── Membre ──
|
|
class MembrePublic(BaseModel):
|
|
id: UUID
|
|
prenom: str
|
|
courriel: str
|
|
groupe_id: UUID
|
|
date_abstinence: Optional[date] = None
|
|
is_sysadmin: bool = False
|
|
|
|
model_config = {"from_attributes": True}
|
|
|
|
|
|
class MembreComplet(MembrePublic):
|
|
nom: Optional[str] = None
|
|
telephone: str
|
|
actif: bool
|
|
cree_le: datetime
|
|
|
|
model_config = {"from_attributes": True}
|
|
|
|
|
|
class MembreUpdate(BaseModel):
|
|
prenom: Optional[str] = None
|
|
nom: Optional[str] = None
|
|
telephone: Optional[str] = None
|
|
courriel: Optional[str] = None
|
|
date_abstinence: Optional[date] = None
|
|
|
|
|
|
class ChangerPinRequest(BaseModel):
|
|
ancien_pin: str
|
|
nouveau_pin: str
|
|
|
|
|
|
# ── Poste / Affectation ──
|
|
class PosteCreate(BaseModel):
|
|
nom: str
|
|
categorie: str # executif, service, physique
|
|
description: Optional[str] = None
|
|
prerequis: Optional[str] = None
|
|
informations: Optional[str] = None
|
|
ordre_affichage: Optional[int] = None
|
|
|
|
|
|
class PosteOut(BaseModel):
|
|
id: UUID
|
|
nom: str
|
|
categorie: str
|
|
description: Optional[str] = None
|
|
prerequis: Optional[str] = None
|
|
informations: Optional[str] = None
|
|
ordre_affichage: Optional[int] = None
|
|
actif: bool = True
|
|
|
|
model_config = {"from_attributes": True}
|
|
|
|
|
|
class AffectationOut(BaseModel):
|
|
id: UUID
|
|
membre_id: UUID
|
|
poste_id: UUID
|
|
poste_nom: Optional[str] = None
|
|
poste_categorie: Optional[str] = None
|
|
date_debut: date
|
|
date_fin: Optional[date] = None
|
|
statut: str
|
|
|
|
model_config = {"from_attributes": True}
|
|
|
|
|
|
class AffectationCreate(BaseModel):
|
|
membre_id: UUID
|
|
poste_id: UUID
|
|
date_debut: date
|
|
proposeur_id: UUID
|
|
secondeur_id: UUID
|
|
|
|
|
|
class TerminerMandatRequest(BaseModel):
|
|
note_transition: Optional[str] = None
|
|
successeur_id: Optional[UUID] = None
|
|
|
|
|
|
# ── Accueil ──
|
|
class ModuleTuile(BaseModel):
|
|
code: str
|
|
nom: str
|
|
description: str
|
|
icone: str
|
|
couleur: str
|
|
|
|
|
|
class AccueilResponse(BaseModel):
|
|
membre: MembrePublic
|
|
postes: list[str]
|
|
est_executif: bool = False
|
|
modules_consultation: list[ModuleTuile]
|
|
modules_saisie: list[ModuleTuile]
|
|
modules_gestion: list[ModuleTuile]
|
|
groupe: Optional[dict] = None
|
|
|
|
|
|
# ── Invitation ──
|
|
class InvitationCreate(BaseModel):
|
|
pass # groupe_id vient du token
|
|
|
|
|
|
class InvitationOut(BaseModel):
|
|
code: str
|
|
expire_le: datetime
|
|
|
|
model_config = {"from_attributes": True}
|
|
|
|
|
|
# ── Groupe ──
|
|
class GroupeOut(BaseModel):
|
|
id: UUID
|
|
nom: str
|
|
district: str
|
|
region: str
|
|
jour_reunion: Optional[str] = None
|
|
assemblee_affaires_ordre: Optional[str] = "premiere"
|
|
|
|
model_config = {"from_attributes": True}
|