"""Modèles de données pour la comparaison d'agenda (diff).""" from __future__ import annotations from datetime import date from enum import StrEnum from pydantic import BaseModel, ConfigDict, Field, model_validator from pronote_sync.models.agenda import Lesson, TheoreticalLesson class AgendaChangeType(StrEnum): """Type de changement dans l'agenda.""" ADDED = "added" REMOVED = "removed" MODIFIED = "modified" class AgendaChange(BaseModel): """Représente un changement entre l'agenda réel et l'agenda théorique.""" model_config = ConfigDict(frozen=True) type: AgendaChangeType = Field(..., description="Type de changement") lesson: Lesson | None = Field(None, description="Cours concerné (pour ADDED/MODIFIED)") theoretical_lesson: TheoreticalLesson | None = Field( None, description="Cours théorique concerné (pour REMOVED/MODIFIED)" ) details: str = Field(default="", description="Détails du changement") @model_validator(mode="after") def _validate_payload_consistency(self) -> AgendaChange: """Valide la cohérence entre le type de changement et le payload. :return: L'instance validée. :rtype: AgendaChange :raises ValueError: Si le payload ne correspond pas au type de changement. """ if self.type in (AgendaChangeType.ADDED, AgendaChangeType.MODIFIED): if self.lesson is None: raise ValueError(f"lesson est requis pour le type {self.type!r}") if self.type == AgendaChangeType.REMOVED: if self.theoretical_lesson is None: raise ValueError(f"theoretical_lesson est requis pour le type {self.type!r}") return self class AgendaDiff(BaseModel): """Représente les différences entre l'agenda réel et l'agenda théorique.""" model_config = ConfigDict(frozen=True) target_date: date = Field(..., description="Date cible de la comparaison") changes: tuple[AgendaChange, ...] = Field(default=(), description="Liste des changements")