""" Modèles de données du stock IT. Principe volontairement simple, demandé par le département IT : on ne suit PAS des exemplaires individuels (pas de numéro de série, pas d'historique détaillé par unité). On suit juste, pour chaque *type* de matériel, une quantité en stock. Ex: "PC Dell XPS 13 modèle 9310" -> quantite=5, "Câble RJ45 2m" -> quantite=42. Hiérarchie : Categorie -> SousCategorie -> Materiel. """ from typing import Optional from sqlmodel import Field, Relationship, SQLModel class Categorie(SQLModel, table=True): """Catégorie de haut niveau (ex: 'Ordinateurs', 'Réseau', 'Périphériques').""" id: Optional[int] = Field(default=None, primary_key=True) nom: str = Field(index=True, unique=True) sous_categories: list["SousCategorie"] = Relationship(back_populates="categorie") class SousCategorie(SQLModel, table=True): """Sous-catégorie rattachée à une catégorie (ex: 'Portables', 'Câbles').""" id: Optional[int] = Field(default=None, primary_key=True) nom: str categorie_id: int = Field(foreign_key="categorie.id") categorie: Optional[Categorie] = Relationship(back_populates="sous_categories") materiels: list["Materiel"] = Relationship(back_populates="sous_categorie") class Materiel(SQLModel, table=True): """Un type de matériel suivi en stock. code_barre identifie le *type* de matériel (le "SKU"), pas un exemplaire précis : scanner deux PC XPS 13 identiques renvoie le même matériel, et chaque scan ajuste juste la quantité globale. """ id: Optional[int] = Field(default=None, primary_key=True) nom: str code_barre: Optional[str] = Field(default=None, index=True, unique=True) quantite: int = Field(default=0) # En dessous de ce seuil, une alerte email est envoyée (voir email_alerts.py). # None = pas d'alerte configurée pour ce matériel. seuil_alerte: Optional[int] = Field(default=None) sous_categorie_id: int = Field(foreign_key="souscategorie.id") sous_categorie: Optional[SousCategorie] = Relationship(back_populates="materiels") class DestinataireAlerte(SQLModel, table=True): """Adresse email qui reçoit les alertes de stock bas. Liste globale simple (pas de destinataires par matériel/catégorie) : c'est suffisant pour une petite équipe IT et ça reste facile à gérer. """ id: Optional[int] = Field(default=None, primary_key=True) email: str = Field(unique=True)