""" Schémas Pydantic pour la validation et la sérialisation des données """ from typing import Optional, Dict, Any, List from pydantic import BaseModel, Field from enum import Enum from datetime import datetime class ConversionStatus(str, Enum): """Statuts possibles pour une conversion de fichier""" SUCCESS = "success" FAILED = "failed" class ConversionResponse(BaseModel): """Réponse à une demande de conversion de fichier""" original_filename: str = Field(..., description="Nom du fichier original") original_format: str = Field(..., description="Format du fichier original") converted_filename: Optional[str] = Field(None, description="Nom du fichier converti") converted_format: Optional[str] = Field(None, description="Format du fichier converti") converted_path: Optional[str] = Field(None, description="Chemin vers le fichier converti") status: ConversionStatus = Field(..., description="Statut de la conversion") message: str = Field(..., description="Message d'information ou d'erreur") class JobStatus(str, Enum): """Statuts possibles pour une tâche d'extraction""" PENDING = "pending" PROCESSING = "processing" COMPLETED = "completed" FAILED = "failed" class UploadResponse(BaseModel): """Réponse à une demande d'upload d'image""" job_id: str = Field(..., description="Identifiant unique de la tâche") status: JobStatus = Field(default=JobStatus.PENDING, description="Statut de la tâche") message: str = Field(default="Image en file d'attente pour traitement", description="Message d'information") created_at: datetime = Field(default_factory=datetime.now, description="Date de création de la tâche") class JobStatusResponse(BaseModel): """Réponse à une demande de statut de tâche""" job_id: str = Field(..., description="Identifiant unique de la tâche") status: JobStatus = Field(..., description="Statut de la tâche") message: str = Field(..., description="Message d'information") created_at: datetime = Field(..., description="Date de création de la tâche") updated_at: Optional[datetime] = Field(None, description="Date de dernière mise à jour") progress: Optional[int] = Field(None, description="Progression en pourcentage (0-100)") queue_position: Optional[int] = Field(None, description="Position dans la file d'attente") class ExtractionResult(BaseModel): """Résultat de l'extraction d'informations d'un chèque""" # Champs standards montant: Optional[str] = Field(None, description="Montant du chèque en chiffres") date: Optional[str] = Field(None, description="Date du chèque") beneficiaire: Optional[str] = Field(None, description="Bénéficiaire du chèque") numero_cheque: Optional[str] = Field(None, description="Numéro du chèque") qualite_extraction: Optional[str] = Field(None, description="Qualité de l'extraction (échec, faible, moyenne, bonne)") image_zones: Optional[str] = Field(None, description="Chemin vers l'image avec les zones identifiées") # Champs MICR (CMC-7) code_banque: Optional[str] = Field(None, description="Code banque (MICR CMC-7)") code_guichet: Optional[str] = Field(None, description="Code guichet (MICR CMC-7)") numero_compte: Optional[str] = Field(None, description="Numéro de compte (MICR CMC-7)") cle_rib: Optional[str] = Field(None, description="Clé RIB (MICR CMC-7)") sequence_micr: Optional[str] = Field(None, description="Séquence MICR complète") # Champs avancés montant_lettres: Optional[str] = Field(None, description="Montant du chèque en lettres") coherence_montants: Optional[bool] = Field(None, description="Cohérence entre montant en chiffres et en lettres") class JobResult(BaseModel): """Résultat complet d'une tâche d'extraction""" job_id: str = Field(..., description="Identifiant unique de la tâche") status: JobStatus = Field(..., description="Statut de la tâche") created_at: datetime = Field(..., description="Date de création de la tâche") completed_at: Optional[datetime] = Field(None, description="Date de complétion de la tâche") image_path: str = Field(..., description="Chemin de l'image originale") result: Optional[ExtractionResult] = Field(None, description="Résultats de l'extraction") texte_brut: Optional[str] = Field(None, description="Texte brut extrait (si disponible)") methode: str = Field(..., description="Méthode utilisée (ocr ou cv)") erreur: Optional[str] = Field(None, description="Message d'erreur (si échec)") class HealthCheck(BaseModel): """Réponse du health check""" status: str = Field(default="ok", description="Statut du service") version: str = Field(..., description="Version de l'API") timestamp: datetime = Field(default_factory=datetime.now, description="Horodatage de la vérification") redis_status: str = Field(..., description="Statut de la connexion Redis") worker_count: int = Field(..., description="Nombre de workers disponibles") queue_size: int = Field(..., description="Nombre de tâches en attente") uptime: str = Field(..., description="Temps de fonctionnement du service") class ErrorResponse(BaseModel): """Réponse en cas d'erreur""" status: str = Field(default="error", description="Statut de la réponse") message: str = Field(..., description="Message d'erreur") error_code: Optional[str] = Field(None, description="Code d'erreur") details: Optional[Dict[str, Any]] = Field(None, description="Détails supplémentaires")