# Schéma de Base de Données Détaillé - Portail d'Authentification

*   **Version :** 1.4
*   **Date :** 1er novembre 2025
*   **Auteur :** Yoann

## 1. Principes d'Architecture

*   **Préfixe :** Toutes les tables liées au portail d'authentification utilisent le préfixe `auth_` pour une identification et une maintenance claires.
*   **Moteur :** InnoDB est recommandé pour la gestion des clés étrangères et des transactions.
*   **Interclassement :** `utf8mb4_unicode_ci` est recommandé pour une prise en charge complète des caractères internationaux.

---

## 2. Schéma des Tables

### Table `auth_users`
Stocke les informations fondamentales de chaque utilisateur.

| Champ | Type | Contraintes | Description |
| :--- | :--- | :--- | :--- |
| `id` | INT | AUTO_INCREMENT PRIMARY KEY | Identifiant numérique unique pour chaque utilisateur. |
| `username` | VARCHAR(50) | UNIQUE NOT NULL | Nom d'utilisateur unique, utilisé pour la connexion. |
| `email` | VARCHAR(100) | UNIQUE NOT NULL | Adresse email de l'utilisateur, unique dans le système. |
| `password_hash` | VARCHAR(255) | NOT NULL | Mot de passe de l'utilisateur, stocké sous forme de hash sécurisé (Argon2id). **Ne jamais stocker en clair.** |
| `is_active` | BOOLEAN | DEFAULT FALSE | Passe à `TRUE` uniquement après que l'utilisateur a vérifié son email. Un compte inactif ne peut pas se connecter. |
| `created_at` | TIMESTAMP | DEFAULT CURRENT_TIMESTAMP | Horodatage de la création du compte. |
| `updated_at` | TIMESTAMP | DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP | Horodatage de la dernière modification de l'enregistrement. |

```sql
CREATE TABLE auth_users (
    id INT AUTO_INCREMENT PRIMARY KEY,
    username VARCHAR(50) NOT NULL UNIQUE,
    email VARCHAR(100) NOT NULL UNIQUE,
    password_hash VARCHAR(255) NOT NULL,
    is_active BOOLEAN DEFAULT FALSE,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
);
```

### Tables de Support à l'Authentification

#### `auth_email_verifications`
Stocke les tokens temporaires pour la vérification des adresses email à l'inscription.

| Champ | Type | Contraintes | Description |
| :--- | :--- | :--- | :--- |
| `user_id` | INT | NOT NULL, FOREIGN KEY | Lien vers l'utilisateur concerné (`auth_users.id`). |
| `token` | VARCHAR(255) | NOT NULL UNIQUE | Le token unique et sécurisé envoyé par email. |
| `expires_at` | TIMESTAMP | NOT NULL | Date et heure d'expiration du token (ex: 24h après création). |

```sql
CREATE TABLE auth_email_verifications (
    user_id INT NOT NULL,
    token VARCHAR(255) NOT NULL UNIQUE,
    expires_at TIMESTAMP NOT NULL,
    PRIMARY KEY (user_id),
    FOREIGN KEY (user_id) REFERENCES auth_users(id) ON DELETE CASCADE
);
```

#### `auth_password_resets`
Stocke les tokens temporaires pour la réinitialisation des mots de passe.

| Champ | Type | Contraintes | Description |
| :--- | :--- | :--- | :--- |
| `email` | VARCHAR(100) | NOT NULL | L'email de l'utilisateur ayant fait la demande. |
| `token` | VARCHAR(255) | NOT NULL UNIQUE | Le token unique et sécurisé envoyé par email. |
| `expires_at` | TIMESTAMP | NOT NULL | Date et heure d'expiration du token (ex: 1h après création). |

```sql
CREATE TABLE auth_password_resets (
    email VARCHAR(100) NOT NULL,
    token VARCHAR(255) NOT NULL UNIQUE,
    expires_at TIMESTAMP NOT NULL,
    PRIMARY KEY (email)
);
```

### Tables pour l'Authentification à Deux Facteurs (2FA)

#### `auth_users_2fa`
Stocke le secret 2FA de chaque utilisateur l'ayant activé.

| Champ | Type | Contraintes | Description |
| :--- | :--- | :--- | :--- |
| `user_id` | INT | NOT NULL PRIMARY KEY, FOREIGN KEY | Lien vers l'utilisateur (`auth_users.id`). |
| `secret_key_encrypted`| VARCHAR(255) | NOT NULL | Le secret partagé (utilisé par l'app d'authentification), **chiffré** avec une clé stockée hors BDD. |
| `is_enabled` | BOOLEAN | DEFAULT FALSE | Passe à `TRUE` uniquement après que l'utilisateur a activé le 2fa. |

```sql
CREATE TABLE auth_users_2fa (
    user_id INT NOT NULL PRIMARY KEY,
    secret_key_encrypted VARCHAR(255) NOT NULL,
    FOREIGN KEY (user_id) REFERENCES auth_users(id) ON DELETE CASCADE
);
```

#### `auth_users_2fa_backup_codes`
Stocke les codes de secours à usage unique.

| Champ | Type | Contraintes | Description |
| :--- | :--- | :--- | :--- |
| `id` | INT | AUTO_INCREMENT PRIMARY KEY | Identifiant unique du code de secours. |
| `user_id` | INT | NOT NULL, FOREIGN KEY | Lien vers l'utilisateur (`auth_users.id`). |
| `code_hash` | VARCHAR(255) | NOT NULL | Le code de secours, stocké sous forme de hash sécurisé. |
| `used_at` | TIMESTAMP | NULL | Reste `NULL` tant que le code n'est pas utilisé. Prend la date d'utilisation ensuite. |

```sql
CREATE TABLE auth_users_2fa_backup_codes (
    id INT AUTO_INCREMENT PRIMARY KEY,
    user_id INT NOT NULL,
    code_hash VARCHAR(255) NOT NULL,
    used_at TIMESTAMP NULL,
    FOREIGN KEY (user_id) REFERENCES auth_users(id) ON DELETE CASCADE
);
```

### Tables de Gestion des Droits (RBAC)

#### `auth_roles`
Définit les rôles disponibles dans le système.

| Champ | Type | Contraintes | Description |
| :--- | :--- | :--- | :--- |
| `id` | INT | AUTO_INCREMENT PRIMARY KEY | Identifiant unique du rôle. |
| `name` | VARCHAR(50) | NOT NULL UNIQUE | Nom court du rôle (ex: `admin`, `app_compta_viewer`). |
| `description` | VARCHAR(255)| NULL | Description lisible du rôle (ex: "Peut voir les factures"). |

```sql
CREATE TABLE auth_roles (
    id INT AUTO_INCREMENT PRIMARY KEY,
    name VARCHAR(50) NOT NULL UNIQUE,
    description VARCHAR(255) NULL
);
```

#### `auth_user_roles`
Table de liaison (pivot) qui assigne des rôles aux utilisateurs (relation N-N).

| Champ | Type | Contraintes | Description |
| :--- | :--- | :--- | :--- |
| `user_id` | INT | NOT NULL, FOREIGN KEY | Lien vers l'utilisateur (`auth_users.id`). |
| `role_id` | INT | NOT NULL, FOREIGN KEY | Lien vers le rôle (`auth_roles.id`). |

```sql
CREATE TABLE auth_user_roles (
    user_id INT NOT NULL,
    role_id INT NOT NULL,
    PRIMARY KEY (user_id, role_id),
    FOREIGN KEY (user_id) REFERENCES auth_users(id) ON DELETE CASCADE,
    FOREIGN KEY (role_id) REFERENCES auth_roles(id) ON DELETE CASCADE
);
```

---

## 3. Schéma des Relations

Ce diagramme illustre comment les tables interagissent entre elles.

```mermaid
erDiagram
    auth_users {
        int id PK
        varchar username
        varchar email
        varchar password_hash
        bool is_active
    }

    auth_email_verifications {
        int user_id PK
        varchar token
        timestamp expires_at
    }

    auth_password_resets {
        varchar email PK
        varchar token
        timestamp expires_at
    }

    auth_users_2fa {
        int user_id PK
        varchar secret_key_encrypted
        bool is_enabled
    }

    auth_users_2fa_backup_codes {
        int id PK
        int user_id FK
        varchar code_hash
        timestamp used_at
    }

    auth_roles {
        int id PK
        varchar name
        varchar description
    }

    auth_user_roles {
        int user_id PK
        int role_id PK
    }

    auth_users ||--|| auth_email_verifications : "valide son email via"
    auth_users ||--o{ auth_password_resets : "peut réinitialiser via"
    auth_users ||--|| auth_users_2fa : "configure"
    auth_users ||--|{ auth_users_2fa_backup_codes : "possède"
    auth_users }o--o{ auth_user_roles : "a"
    auth_roles }o--o{ auth_user_roles : "est assigné dans"
```
### Légende du Schéma

*   **`PK`** : Clé Primaire (Primary Key) - Identifiant unique de la ligne.
*   **`FK`** : Clé Étrangère (Foreign Key) - Lien vers une autre table.

**Signification des relations (lignes et symboles) :**

*   `||--||` : Relation **Un-à-Un** (One-to-One). Exemple : Un utilisateur (`auth_users`) a exactement une entrée 2FA (`auth_users_2fa`).
*   `||--|{` : Relation **Un-à-Plusieurs** (One-to-Many). Exemple : Un utilisateur (`auth_users`) peut avoir plusieurs codes de secours (`auth_users_2fa_backup_codes`).
*   `}o--o{` : Relation **Plusieurs-à-Plusieurs** (Many-to-Many). Exemple : Un utilisateur peut avoir plusieurs rôles, et un rôle peut être assigné à plusieurs utilisateurs.