""" Schemas Pydantic pour ClassGroup. """ from datetime import date from typing import Optional, List, Dict from pydantic import Field from schemas.common import BaseSchema class ClassGroupBase(BaseSchema): """Schema de base pour ClassGroup.""" name: str description: Optional[str] = None year: str class ClassGroupRead(ClassGroupBase): """Schema pour la lecture d'un ClassGroup.""" id: int students_count: int = 0 assessments_count: int = 0 class ClassGroupDetail(ClassGroupRead): """Schema détaillé avec statistiques.""" assessments_count: int = 0 class ClassGroupList(BaseSchema): """Schema pour la liste des classes.""" classes: List[ClassGroupRead] total: int # Schemas pour les statistiques de classe class TrimesterStats(BaseSchema): """Statistiques par trimestre.""" total: int completed: int in_progress: int not_started: int class ClassStatistics(BaseSchema): """Statistiques complètes d'une classe.""" class_id: int class_name: str students_count: int trimester_stats: TrimesterStats # Statistiques des résultats (optionnel) mean: Optional[float] = None median: Optional[float] = None min_score: Optional[float] = None max_score: Optional[float] = None class DomainAnalysis(BaseSchema): """Analyse par domaine.""" name: str color: str total_points: float elements_count: int class CompetenceAnalysis(BaseSchema): """Analyse par compétence.""" name: str color: str total_points: float elements_count: int # Schemas pour les opérations d'écriture (CRUD) class ClassGroupCreate(ClassGroupBase): """Schema pour créer une classe.""" pass class ClassGroupUpdate(BaseSchema): """Schema pour modifier une classe.""" name: Optional[str] = None description: Optional[str] = None year: Optional[str] = None class ClassGroupResponse(BaseSchema): """Schema de réponse après création/modification.""" id: int name: str description: Optional[str] = None year: str message: str = "" # Schemas pour le dashboard de statistiques complet class StudentAverage(BaseSchema): """Moyenne d'un élève pour un trimestre.""" student_id: int first_name: str last_name: str full_name: str average: Optional[float] = None assessment_count: int = 0 assessment_scores: Dict[int, "AssessmentScore"] = {} domain_stats: Dict[int, "DomainStudentStats"] = {} competence_stats: Dict[int, "CompetenceStudentStats"] = {} class HistogramBin(BaseSchema): """Bin pour l'histogramme des moyennes.""" range_start: float range_end: float label: str count: int class AssessmentScore(BaseSchema): """Score d'un élève pour une évaluation.""" assessment_id: int assessment_title: str score: Optional[float] = None max_points: float = 0.0 score_on_20: Optional[float] = None class DomainStudentStats(BaseSchema): """Statistiques d'un élève pour un domaine.""" domain_id: int evaluation_count: int = 0 total_points_obtained: float = 0.0 total_points_possible: float = 0.0 class CompetenceStudentStats(BaseSchema): """Statistiques d'un élève pour une compétence.""" competence_id: int evaluation_count: int = 0 total_points_obtained: float = 0.0 total_points_possible: float = 0.0 class DomainStats(BaseSchema): """Statistiques par domaine.""" id: int name: str color: str evaluation_count: int = 0 total_points_obtained: float = 0.0 total_points_possible: float = 0.0 class CompetenceStats(BaseSchema): """Statistiques par compétence.""" id: int name: str color: str evaluation_count: int = 0 total_points_obtained: float = 0.0 total_points_possible: float = 0.0 class ClassDashboardStats(BaseSchema): """Dashboard complet de statistiques de classe.""" class_id: int class_name: str trimester: int students_count: int # Statistiques globales mean: Optional[float] = None median: Optional[float] = None std_dev: Optional[float] = None min_score: Optional[float] = None max_score: Optional[float] = None # Évaluations assessments_total: int = 0 assessments_completed: int = 0 assessments_in_progress: int = 0 # Données détaillées student_averages: List[StudentAverage] = [] histogram: List[HistogramBin] = [] domains_stats: List[DomainStats] = [] competences_stats: List[CompetenceStats] = []