```mermaid
erDiagram

    CAMPUS {
        int id PK
        string nom
        string adresse
        string ville
        string code_postal
        boolean actif
        datetime created_at
        datetime updated_at
    }

    SALLE_PRET {
        int id PK
        string nom
        string localisation
        int campus_id FK
        boolean actif
        datetime created_at
        datetime updated_at
    }

    POSTE_EMPRUNT {
        int id PK
        string nom
        string identifiant_poste
        int salle_pret_id FK
        boolean actif
        datetime created_at
        datetime updated_at
    }

    ROLE {
        int id PK
        string code UK
        string libelle
        string description
    }

    UTILISATEUR {
        int id PK
        string microsoft_id UK
        string nom
        string prenom
        string email UK
        string classe "nullable"
        int role_id FK
        int campus_id FK
        boolean actif
        datetime created_at
        datetime updated_at
    }

    CARTE_ETUDIANTE {
        int id PK
        int utilisateur_id FK
        string qr_code
        datetime date_activation
        datetime date_expiration
        boolean actif
        datetime created_at
        datetime updated_at
    }

    CATEGORIE_MATERIEL {
        int id PK
        string nom
        string description
        boolean actif
        datetime created_at
        datetime updated_at
    }

    MATERIEL {
        int id PK
        string nom
        string marque
        string modele
        string reference
        string numero_inventaire
        string numero_serie
        string statut
        string etat_general
        int categorie_id FK
        int campus_id FK
        boolean actif
        datetime created_at
        datetime updated_at
    }

    ACCESSOIRE {
        int id PK
        string nom
        string description
        boolean actif
        datetime created_at
        datetime updated_at
    }

    MATERIEL_ACCESSOIRE {
        int id PK
        int materiel_id FK
        int accessoire_id FK
        int quantite_attendue
        boolean obligatoire
    }

    EMPRUNT {
        int id PK
        int utilisateur_id FK
        int materiel_id FK
        int campus_id FK
        int salle_pret_id FK
        int poste_emprunt_id FK
        datetime date_emprunt
        datetime date_retour_prevue
        datetime date_retour_reelle "nullable"
        string statut
        string mode_identification_emprunt
        string mode_identification_retour "nullable"
        string commentaire_depart "nullable"
        string commentaire_retour "nullable"
        datetime created_at
        datetime updated_at
    }

    CHECKLIST {
        int id PK
        int emprunt_id FK
        int utilisateur_id FK
        string type
        datetime date_verification
        string commentaire "nullable"
        datetime created_at
        datetime updated_at
    }

    CHECKLIST_ELEMENT {
        int id PK
        int checklist_id FK
        int accessoire_id FK "nullable"
        string nom_element
        string etat
        int quantite_constatee
        string commentaire "nullable"
        datetime created_at
        datetime updated_at
    }

    ANOMALIE {
        int id PK
        int emprunt_id FK
        int materiel_id FK
        int utilisateur_id FK
        int traitee_par_id FK "nullable"
        string type
        string description
        string statut
        boolean detectee_automatiquement
        string observation "nullable"
        datetime date_detection
        datetime date_resolution "nullable"
        datetime created_at
        datetime updated_at
    }

    HISTORIQUE {
        int id PK
        int utilisateur_id FK
        int emprunt_id FK "nullable"
        int materiel_id FK "nullable"
        int campus_id FK "nullable"
        int salle_pret_id FK "nullable"
        int poste_emprunt_id FK "nullable"
        string action
        string description
        datetime date_action
        datetime created_at
    }

    NOTIFICATION {
        int id PK
        int utilisateur_id FK
        int anomalie_id FK "nullable"
        string titre
        string message
        string type
        boolean lu
        datetime date_creation
    }

    CAMPUS ||--o{ SALLE_PRET : "contient"
    CAMPUS ||--o{ UTILISATEUR : "rattache"
    CAMPUS ||--o{ MATERIEL : "possede"
    CAMPUS ||--o{ EMPRUNT : "localise"
    CAMPUS ||--o{ HISTORIQUE : "concerne"

    SALLE_PRET ||--o{ POSTE_EMPRUNT : "possede"
    SALLE_PRET ||--o{ EMPRUNT : "concerne"
    SALLE_PRET ||--o{ HISTORIQUE : "localise"

    POSTE_EMPRUNT ||--o{ EMPRUNT : "enregistre"
    POSTE_EMPRUNT ||--o{ HISTORIQUE : "trace_optionnelle"

    ROLE ||--o{ UTILISATEUR : "attribue"

    UTILISATEUR ||--o{ CARTE_ETUDIANTE : "possede"
    UTILISATEUR ||--o{ EMPRUNT : "effectue"
    UTILISATEUR ||--o{ CHECKLIST : "renseigne"
    UTILISATEUR ||--o{ ANOMALIE : "concerne"
    UTILISATEUR ||--o{ ANOMALIE : "traite"
    UTILISATEUR ||--o{ HISTORIQUE : "declenche"
    UTILISATEUR ||--o{ NOTIFICATION : "recoit"

    CATEGORIE_MATERIEL ||--o{ MATERIEL : "classe"

    MATERIEL ||--o{ MATERIEL_ACCESSOIRE : "possede"
    ACCESSOIRE ||--o{ MATERIEL_ACCESSOIRE : "compose"

    MATERIEL ||--o{ EMPRUNT : "concerne"

    EMPRUNT ||--o{ CHECKLIST : "possede"
    CHECKLIST ||--o{ CHECKLIST_ELEMENT : "contient"
    ACCESSOIRE ||--o{ CHECKLIST_ELEMENT : "verifie"

    EMPRUNT ||--o{ ANOMALIE : "genere"
    MATERIEL ||--o{ ANOMALIE : "concerne"

    EMPRUNT ||--o{ HISTORIQUE : "trace"
    MATERIEL ||--o{ HISTORIQUE : "concerne"

    ANOMALIE ||--o{ NOTIFICATION : "genere"
```