""" Schémas Pydantic pour validation des requêtes/réponses. """ from pydantic import BaseModel, EmailStr, Field from datetime import datetime from typing import Optional, List class VoterRegister(BaseModel): """Enregistrement d'un électeur""" email: str password: str = Field(..., min_length=8) first_name: str last_name: str citizen_id: str # Identifiant unique (CNI) class VoterLogin(BaseModel): """Authentification""" email: str password: str class TokenResponse(BaseModel): """Réponse d'authentification""" access_token: str token_type: str = "bearer" expires_in: int class LoginResponse(BaseModel): """Réponse de connexion - retourne le profile et le token""" access_token: str token_type: str = "bearer" expires_in: int id: int email: str first_name: str last_name: str class RegisterResponse(BaseModel): """Réponse d'enregistrement - retourne le profile et le token""" access_token: str token_type: str = "bearer" expires_in: int id: int email: str first_name: str last_name: str class VoterProfile(BaseModel): """Profil d'un électeur""" id: int email: str first_name: str last_name: str has_voted: bool created_at: datetime class Config: from_attributes = True class CandidateResponse(BaseModel): """Candidat""" id: int name: str description: Optional[str] order: int class ElectionResponse(BaseModel): """Élection avec candidats""" id: int name: str description: Optional[str] start_date: datetime end_date: datetime is_active: bool results_published: bool candidates: List[CandidateResponse] class Config: from_attributes = True class VoteBulletin(BaseModel): """Bulletin de vote à soumettre""" election_id: int candidate_id: int encrypted_vote: str # Base64 du Ciphertext ElGamal zero_knowledge_proof: Optional[str] = None # Base64 de la preuve ZK class VoteResponse(BaseModel): """Confirmaction de vote""" id: int ballot_hash: str timestamp: datetime class Config: from_attributes = True class ResultResponse(BaseModel): """Résultat de l'élection""" candidate_name: str vote_count: int percentage: float class ElectionResultResponse(BaseModel): """Résultats complets d'une élection""" election_id: int election_name: str total_votes: int results: List[ResultResponse]