# Bibliothèque Miaw

## Projet Symfony pour apprendre le framework

Une [ébauche du design de l'application](https://www.figma.com/design/TKLqcwaFFuuFLJY3fxNY6I/My-Book-Shelf--Community-?node-id=5-79&t=iPKj0kofnbIl6SJy-0) est disponible sous figma.

Cependant, certaines fonctionnalités décrites dans le design ne sont pas couvertes par ce projet.
D'autres fonctionnalités non designées pourront être ajoutées.

## Introduction
Ce document décrit un projet Symfony, où les étudiants développeront une application de gestion de bibliothèque.

Chaque étudiant participera à différents aspects techniques du projet sur plusieurs séances de 3 heures.

Les user stories sont formulées pour refléter les besoins fonctionnels des utilisateurs et des rôles, ainsi que les aspects techniques nécessaires au développement.

## Modèle de Participation Active
Pour garantir une participation active de chaque étudiant à toutes les séances, les rôles suivants sont définis pour chaque tâche :

-   **Responsable (Auteur)** : La personne ou le binôme qui code la fonctionnalité.
-   **Relecteur** : La personne ou le binôme qui effectue la revue de code de la tâche.
-   **Rôle de support (Tous les autres étudiants)** : Les autres membres de l'équipe participent activement à la séance en assistant les auteurs, en réalisant des tests exploratoires ou des POC, en recherchant des points techniques ou en préparant la documentation.

## Planification des Séances

### Configuration initiale d'un projet avec docker

- **US 1.1** : En tant que chef de projet, je veux que le projet Symfony et la base de données soient configurés afin que l'équipe puisse commencer le développement.
    - **Tâche** : Configuration initiale d'un projet Symfony de test en suivant [la documentation](https://gitlab.univ-lr.fr/ntrugeon/docker-symfony-wp-2024).
    - **Responsables** : Tous les étudiants (chacun sur son poste)
    - **Tests d'acceptation** :
        1.  **Étant donné que** le projet est issu de la stack technique docker, **quand** je lance la commande `make up`, **alors** le navigateur peut aller sur la page 404 de Symfony.
        2.  **Étant donné que** les dépendances de développement et de l'application sont installées, **quand** je lance le site, **alors** la page d'accueil de Symfony s'affiche avec le profiler visible.
        3.  **Étant donné que** la base de données est configurée, **quand** je lance `bin/console make:entity`, **alors** je n'ai pas d'erreur. `Ctrl+C`pour quitter.
    - **Tâche annexe** : Chaque étudiant crée un contrôleur, ajoute une variable contenant son nom à la méthode index et le passe à la vue.
    - **Responsables** : Tous les étudiants (chacun sur son poste)
    - **Tests d'acceptation** :
        1. On voit bien son nom apparaître dans le h1 de la page par défaut du site.
    - **Relecture** : Revue collective et aide mutuelle lors de la séance.

### Récupération du projet de départ

- **US 1.2** : En tant que développeur, je veux pouvoir récupérer le code du projet pour commencer à travailler dessus.
- **Tâche** : Cloner le projet dans le dossier devPhpLp/projets/ sous le nom biblio. En utilisant la commande `make existingProject`, je configure la stack pour l'intégrer à mon système.
    - **Responsables** : Tous les étudiants (chacun sur son poste)
    - **Tests d'acceptation** :
        1.  **Quand** je lance mon navigateur sur https://biblio.localhost:8443, **alors** le site se lance et je vois la page d'accueil du site.

### Modélisation des entités (Partie 1)

> Pour les étudiants non impliqués directement dans les US, vous pouvez/devez utiliser le projet initial pour créer les entités.
> Chaque étudiant ou binôme est responsable de la création d'une ou plusieurs entités, mais tous les étudiants participent activement à chaque séance.

- **US 2.1** : En tant que bibliothécaire, je veux pouvoir enregistrer les détails d'un éditeur.
    -   **Responsables** : Sylvain, Léa
    -   **Relecteurs** : Eliaz, Maxime Ch
    -   **Rôle de support (Tous les autres étudiants)** : Recherche sur les bonnes pratiques pour les contraintes de base de données (unique, nullable).
    -   **Champs de l'entité `Editeur`** :
        -   `nom` (string, 255, unique=true)
        -   `adresse` (string, 255, nullable=true)
        -   `site_web` (string, 255, nullable=true)
    -   **Tests d'acceptation** :
        1.  **Étant donné que** l'entité `Editeur` est créée, **quand** je génère et exécute une migration, **alors** la table `editeur` est correctement créée en base de données avec tous les champs et leurs contraintes.

- **US 2.2** : En tant que bibliothécaire, je veux pouvoir enregistrer les détails d'un auteur.
    -   **Responsables** : Gabriel, Tristan
    -   **Relecteurs** : Mathis, Elouan
    -   **Rôle de support (Tous les autres étudiants)** : Discussion sur les types de champs à utiliser (ex: `date` vs `datetime`).
    -   **Champs de l'entité `Auteur`** :
        -   `prenom` (string, 255, nullable=true)
        -   `nom` (string, 255)
        -   `date_naissance` (date, nullable=true)
        -   `nationalite` (string, 100, nullable=true)
    -   **Tests d'acceptation** :
        1.  **Étant donné que** l'entité `Auteur` est créée, **quand** je génère et exécute une migration, **alors** la table `auteur` est correctement créée en base de données avec tous les champs et leurs contraintes.

- **US 2.3** : En tant que bibliothécaire, je veux pouvoir classer les livres par catégorie.
    -   **Responsables** : Jules, Lisa
    -   **Relecteurs** : Yacine, Sean
    -   **Rôle de support (Tous les autres étudiants)** : Brainstorming sur les catégories pertinentes pour une bibliothèque.
    -   **Champs de l'entité `Categorie`** :
        -   `nom` (string, 100, unique=true)
        -   `description` (string, 255, nullable=true)
    -   **Tests d'acceptation** :
        1.  **Étant donné que** l'entité `Categorie` est créée, **quand** je génère et exécute une migration, **alors** la table `categorie` est correctement créée en base de données avec tous les champs et leurs contraintes.

- **US 2.4** : En tant que bibliothécaire, je veux pouvoir enregistrer les détails d'un livre.
    -   **Responsables** : Maxime Cu, Thomas
    -   **Relecteurs** : Sylvain, Léa
    -   **Rôle de support (Tous les autres étudiants)** : Discussion sur les relations (OneToMany, ManyToOne, etc.) à mettre en place avec les autres entités.
    -   **Champs de l'entité `Livre`** :
        -   `titre` (string, 255)
        -   `isbn` (string, 20, unique=true, nullable=true)
        -   `anneePublication` (integer, nullable=true)
        -   `nombrePages` (integer, nullable=true)
        -   `description` (text, nullable=true)
        -   `urlCouverture` (string, 255, nullable=true)
    -   **Relations de l'entité `Livre`** :
        -   `editeur` (ManyToOne vers `Editeur`)
        -   `auteurs` (ManyToMany vers `Auteur`)
        -   `categorie` (ManyToOne vers `Categorie`)
    -   **Tests d'acceptation** :
        1.  **Étant donné que** les entités `Editeur`, `Auteur` et `Categorie` sont définies, **quand** je crée l'entité `Livre` avec les relations appropriées et que je génère et exécute une migration, **alors** la table `livre` est correctement créée en base de données avec tous les champs et leurs contraintes, y compris les clés étrangères.

- **US 2.5** : En tant qu'administrateur, je veux pouvoir gérer les comptes utilisateurs et les profils emprunteurs associés.
    - **Responsables** : Yacine, Lisa
    - **Relecteurs** : Maxime Ch, Mathis
    - **Rôle de support (Tous les autres étudiants)** : Discussion sur les rôles et la liaison entre l'authentification (`User`) et les données métier (`Emprunteur`).
    - **Détail des entités `User` et `Emprunteur`** :
        -   L'entité `User` sera créée via `make:user` pour l'authentification. Elle contiendra `email`, `roles`, `password`.
        -   L'entité `Emprunteur` contiendra les informations métier : `nom`, `prenom`, `telephone`, `actif`, `date_creation`, `date_modification`.
        -   Une relation **OneToOne** sera établie entre `User` et `Emprunteur`. L'entité `User` sera propriétaire de la relation.
    - **Tests d'acceptation** :
        1.  **Étant donné que** les entités `User` et `Emprunteur` sont créées et liées, **quand** j'exécute les migrations, **alors** les tables `user` et `emprunteur` sont créées avec une relation `OneToOne`.

### Modélisation des entités et repositories (Partie 2)
- **US 3.1.1** : En tant que développeur, je veux un jeu de données cohérent pour tester l'application.
    - **Tâche** : Création de fixtures pour les entités de base (`Auteur`).
    - **Rôle de support (Tous les autres étudiants)** : Définition d'un jeu de données réaliste.
    - **Détail de l'implémentation** :
        -   Installer `doctrine/fixtures-bundle`.
        -   Créer une classe de fixtures pour `Auteur`.
    - **Tests d'acceptation** :
        1.  **Étant donné que** la base de données est vide, **quand** j'exécute la commande `php bin/console doctrine:fixtures:load`, **alors** la base de données est peuplée avec des auteurs.

- **US 3.1.2** : En tant que développeur, je veux un jeu de données cohérent pour tester l'application.
    - **Tâche** : Création de fixtures pour les entités de base (`Categorie`).
    - **Rôle de support (Tous les autres étudiants)** : Définition d'un jeu de données réaliste.
    - **Détail de l'implémentation** :
        -   Installer `doctrine/fixtures-bundle`.
        -   Créer une classe de fixtures pour `Categorie`.
    - **Tests d'acceptation** :
        1.  **Étant donné que** la base de données est vide, **quand** j'exécute la commande `php bin/console doctrine:fixtures:load`, **alors** la base de données est peuplée avec des catégories.

- **US 3.1.3** : En tant que développeur, je veux un jeu de données cohérent pour tester l'application.
    - **Tâche** : Création de fixtures pour les entités de base (`Editeur`).
    - **Rôle de support (Tous les autres étudiants)** : Définition d'un jeu de données réaliste.
    - **Détail de l'implémentation** :
        -   Installer `doctrine/fixtures-bundle`.
        -   Créer une classe de fixtures pour `Editeur`.
    - **Tests d'acceptation** :
        1.  **Étant donné que** la base de données est vide, **quand** j'exécute la commande `php bin/console doctrine:fixtures:load`, **alors** la base de données est peuplée avec des éditeurs.

- **US 3.1.4** : En tant que développeur, je veux un jeu de données cohérent pour tester l'application.
    - **Tâche** : Création de fixtures pour les entités de base (`Livre`).
    - **Rôle de support (Tous les autres étudiants)** : Définition d'un jeu de données réaliste.
    - **Détail de l'implémentation** :
        -   Installer `doctrine/fixtures-bundle`.
        -   Créer une classe de fixtures pour `Livre`.
        -   Utiliser des dépendances entre fixtures pour garantir l'ordre de création.
    - **Tests d'acceptation** :
        1.  **Étant donné que** la base de données est vide, **quand** j'exécute la commande `php bin/console doctrine:fixtures:load`, **alors** la base de données est peuplée avec des livres.

- **US 3.2** : En tant que bibliothécaire, je veux pouvoir gérer les exemplaires physiques de chaque livre.
    - **Responsables** : Yacine, Sean
    - **Relecteurs** : Maxime Cu, Thomas
    - **Rôle de support (Tous les autres étudiants)** : Discussion sur les états possibles d'un exemplaire.
    - **Détail de l'entité `Exemplaire`** :
        -   `code_barre` (string, 255, unique=true) : Identifiant unique de l'exemplaire.
        -   `statut` (string, Enum) : Utiliser un Enum PHP `StatutExemplaire` avec les cas `DISPONIBLE`, `EMPRUNTE`, `PERDU`, `ENDOMMAGE`.
        -   `date_acquisition` (date).
        -   **Relation** : `livre` (ManyToOne vers `Livre`).
    - **Tests d'acceptation** :
        1. **Étant donné que** l'entité `Exemplaire` est créée, **quand** je génère une migration, **alors** la table `exemplaire` est créée avec une relation vers `livre`.

- **US 3.3** : En tant que bibliothécaire, je veux pouvoir gérer les emprunts d'exemplaires.
    - **Responsables** : Maxime Cu, Thomas
    - **Relecteurs** : Sylvain, Léa
    - **Rôle de support (Tous les autres étudiants)** : Définition de la logique métier (ex: un exemplaire ne peut être emprunté qu'une fois à la fois).
    - **Détail de l'entité `Emprunt`** :
        -   `date_emprunt` (datetime)
        -   `date_retour_prevue` (datetime)
        -   `date_retour_reelle` (datetime, nullable=true) : Renseignée uniquement lorsque le livre est rendu.
        -   `statut` (string, Enum) : Utiliser un Enum PHP `StatutEmprunt` avec les cas `EN_COURS`, `RETOURNE`, `EN_RETARD`.
        -   **Relation** : `exemplaire` (ManyToOne vers `Exemplaire`).
        -   **Relation** : `emprunteur` (ManyToOne vers `Emprunteur`).
    - **Tests d'acceptation** :
        1. **Étant donné que** l'entité `Emprunt` est créée, **quand** je génère une migration, **alors** la table `emprunt` est créée avec des relations vers `exemplaire` et `emprunteur`.

- **US 3.4** : En tant que bibliothécaire, je veux pouvoir rechercher des livres par titre, auteur ou catégorie.
    - **Responsables** : Eliaz, Maxime Ch
    - **Relecteurs** : Gabriel, Tristan
    - **Rôle de support (Tous les autres étudiants)** : Préparation de jeux de données (fixtures) pour pouvoir tester la recherche.
    - **Détail du `LivreRepository`** :
      Implémenter les méthodes suivantes à l'aide du QueryBuilder de Doctrine.
    -   `findByTitre(string $motCle)`: Doit retourner les livres dont le titre contient le mot-clé (requête `LIKE`).
    -   `findByAuteur(Auteur $auteur)`: Doit retourner tous les livres associés à une instance d'un auteur (requête avec jointure).
    -   `findByCategorie(Categorie $categorie)`: Doit retourner tous les livres d'une catégorie.
    - **Tests d'acceptation** :
        1. **Étant donné** des livres en base, **quand** j'appelle la recherche par titre dans le `LivreRepository`, **alors** seuls les livres correspondants sont retournés.

- **US 3.5** : En tant que développeur, je veux compléter le jeu de données avec des exemplaires et des emprunts.
    - **Tâche** : Mise à jour des fixtures.
    - **Responsables** : Yacine, Lisa
    - **Relecteurs** : Jules, Sean
    - **Détail de l'implémentation** :
        -   Créer des fixtures pour `Exemplaire` et `Emprunt`.
        -   S'assurer que les fixtures génèrent des données variées (emprunts en cours, retournés, etc.).
    - **Tests d'acceptation** :
        1.  **Étant donné que** la base de données est vide, **quand** j'exécute la commande `php bin/console doctrine:fixtures:load`, **alors** la base de données est peuplée avec un jeu de données complet incluant des emprunts.

- **US 3.6** : En tant que développeur, je veux ajouter des contraintes de validation sur les entités pour garantir l'intégrité des données au niveau de l'application.
    - **Tâche** : Ajouter des attributs `Assert` sur les propriétés des entités.
    - **Responsables** : Gabriel, Mathis
    - **Relecteurs** : Tristan, Elouan
    - **Rôle de support (Tous les autres étudiants)** : Recherche sur les contraintes de validation disponibles dans la documentation de Symfony.
    - **Détail de l'implémentation** :
        -   Parcourir toutes les entités (`Livre`, `Auteur`, `Editeur`, `Categorie`, `Emprunteur`, etc.).
        -   Ajouter des contraintes pertinentes pour chaque propriété, par exemple :
            -   `@Assert\NotBlank` pour les champs obligatoires (ex: `Livre.titre`, `Auteur.nom`).
            -   `@Assert\Length(min=2, max=255)` pour les chaînes de caractères.
            -   `@Assert\Isbn` pour le champ `isbn` de l'entité `Livre`.
            -   `@Assert\Url` pour les champs `site_web`.
            -   `@Assert\Positive` pour les champs numériques comme `nombrePages`.
    - **Tests d'acceptation** :
        1.  **Étant donné** une entité avec des contraintes de validation, **quand** j'essaie de la valider avec des données invalides (ex: un titre vide) en utilisant le service `validator`, **alors** j'obtiens une liste d'erreurs de validation.
        2.  **Étant donné** la même entité, **quand** je la valide avec des données valides, **alors** la liste d'erreurs est vide.

**US 3.7** : En tant que développeur, je veux mettre en production l'application sur le serveur lpmiaw.
- **Tâche** : Déployer l'application Symfony en utilisant Git.
- **Responsables** : Tous les étudiants (chacun sur son poste)
- **Détail de l'implémentation** :
  - [Partie du cours sur la mise en production](https://gitlab.univ-lr.fr/lpmiaw-2025-2026/Symfony-2025-2026/cours-et-fiches-techniques/-/blob/main/Cours.md?ref_type=heads#mise-en-production-dun-site-symfony)
  - Mettre en place un script de déploiement pour automatiser les tâches post-déploiement.
- **Point de vigilance** : 
  - Assurer que les variables d'environnement sont correctement configurées sur le serveur de production.
  - Vérifier que les migrations de la base de données sont exécutées lors du déploiement.
  - Comment récupérer les données de l'application ?
- **Tests d'acceptation** :
1.  **Étant donné que** des modifications ont été poussées sur la branche principale, **quand** je me connecte au serveur de production, **alors** le code source est à jour.
2.  **Étant donné qu'une** nouvelle migration a été ajoutée, **quand** le déploiement est terminé, **alors** la structure de la base de données de production est à jour.
3.  **Étant donné que** le déploiement est réussi, **quand** j'accède à l'URL de production, **alors** l'application fonctionne sans erreurs avec toutes les données à jour.


### Contrôleurs et Vues avec Twig (Partie 1)
- **US 4.1** : En tant qu'emprunteur, je veux pouvoir consulter la liste des livres afin de visualiser le catalogue disponible.
    - **Tâche** : Création du contrôleur et de la vue liste pour les Livres.
    - **Responsables** : Sylvain, Eliaz
    - **Relecteurs** : Léa, Maxime Ch
    - **Tests d'acceptation** :
        1.  **Étant donné que** je suis sur la page des livres, **quand** la page se charge, **alors** je vois une liste de livres avec leur titre, auteur principal et catégorie.

- **US 4.2** : En tant qu'emprunteur, je veux pouvoir voir les détails d'un livre et la disponibilité de ses exemplaires.
    - **Tâche** : Création de la vue détail pour un livre.
    - **Responsables** : Gabriel, Mathis
    - **Tests d'acceptation** :
        1.  **Étant donné que** je suis sur la liste des livres, **quand** je clique sur un titre, **alors** je suis redirigé vers la page de détails du livre qui affiche toutes ses informations ainsi que la liste de ses exemplaires et leur statut.
    - **Relecture** : Tristan, Elouan

### Contrôleurs et Vues avec Twig (Partie 2)
- **US 5.1** : En tant qu'emprunteur, je veux pouvoir consulter la liste des auteurs et des catégories.
    - **Tâche** : Création des contrôleurs et vues pour Auteur et Catégorie.
    - **Responsables** : Jules, Yacine
    - **Relecteurs** : Yacine, Lisa
    - **Tests d'acceptation** :
        1. **Étant donné que** je navigue vers la page des auteurs, **quand** la page s'affiche, **alors** je vois la liste de tous les auteurs.
        2. **Étant donné que** je navigue vers la page des catégories, **quand** la page s'affiche, **alors** je vois la liste de toutes les catégories.

- **US 5.2** : En tant qu'emprunteur, je veux pouvoir consulter mon profil et mon historique d'emprunts.
    - **Tâche** : Amélioration de la page de profil utilisateur.
    - **Responsables** : Maxime Cu, Thomas
    - **Relecteurs** : Sylvain, Eliaz
    - **Tests d'acceptation** :
        1. **Étant donné que** je suis connecté, **quand** j'accède à la page "Mon Profil", **alors** je vois mes informations personnelles ainsi que la liste de mes emprunts en cours et mon historique d'emprunts passés.

### Événements et Logique Métier
- **US 6.1** : En tant que bibliothécaire, je veux recevoir une notification lorsqu'un livre est rendu en retard afin de pouvoir contacter l'emprunteur.
    - **Tâche** : Implémentation de l'événement de retard
    - **Responsables** : Sylvain, Maxime Ch
    - **Relecteurs** : Léa, Tristan
    - **Tests d'acceptation** :
        1. **Étant donné qu'un** emprunt est en retard, **quand** la tâche de vérification s'exécute, **alors** un événement de retard est déclenché.

- **US 6.2** : En tant que bibliothécaire, je veux pouvoir gérer les emprunts et les retours de livres afin de maintenir un suivi précis des livres.
    - **Tâche** : Implémentation de la logique des emprunts
    - **Responsables** : Eliaz, Elouan
    - **Relecteurs** : Gabriel, Yacine
    - **Tests d'acceptation** :
        1. **Étant donné que** je suis sur la page d'un livre, **quand** je clique sur "Emprunter", **alors** un nouvel emprunt est créé.

- **US 6.3** : En tant que système, je veux contacter automatiquement par email les emprunteurs qui ont des livres en retard.
    - **Tâche** : Création d'un écouteur d'événement (Event Listener) pour l'envoi d'emails de relance.
    - **Responsables** : Mathis, Sean
    - **Relecteurs** : Jules, Thomas
    - **Détail de l'implémentation** :
        -   Créer un `LoanLateListener` qui écoute l'événement `App\Event\LoanLateEvent`.
        -   Dans l'écouteur, utiliser le composant `Mailer` de Symfony pour envoyer un email à l'emprunteur concerné.
        -   L'email doit contenir les détails du livre en retard et la date de retour prévue.
    - **Tests d'acceptation** :
        1.  **Étant donné** qu'un événement `LoanLateEvent` est distribué pour un emprunt, **quand** l'écouteur traite l'événement, **alors** un email est ajouté au `spool` du Mailer (ou visible dans Mailtrap) à destination de l'emprunteur.

- **US 6.4** : En tant que système, je veux vérifier quotidiennement les emprunts en retard pour déclencher les notifications.
    - **Tâche** : Création d'une commande Symfony pour vérifier les retards.
    - **Responsables** : Yacine, Maxime Cu
    - **Relecteurs** : Sylvain, Maxime Ch
    - **Détail de l'implémentation** :
        -   Créer une commande `app:check-late-loans` via `make:command`.
        -   La commande récupère tous les emprunts avec le statut `EN_COURS` dont la `date_retour_prevue` est dépassée.
        -   Pour chaque emprunt en retard, la commande met à jour son statut à `EN_RETARD` et distribue un événement `App\Event\LoanLateEvent` avec les détails de l'emprunt.
        -   Cette commande sera à exécuter via un cron job sur le serveur de production.
    - **Tests d'acceptation** :
        1.  **Étant donné** un emprunt dont la date de retour est passée, **quand** j'exécute la commande `app:check-late-loans`, **alors** le statut de l'emprunt passe à `EN_RETARD` et un événement est distribué.

### Intégration d'une API Externe
- **US 7.1** : En tant que bibliothécaire, je veux pouvoir enrichir les informations des livres avec des données externes afin de fournir des détails supplémentaires.
    - **Tâche** : Appel à l'API Google Books et intégration
    - **Responsables** : Léa, Tristan
    - **Relecteurs** : Eliaz, Elouan
    - **Tests d'acceptation** :
        1. **Étant donné que** je suis sur la page de détail, **quand** elle se charge, **alors** des infos de l'API externe sont affichées.

- **US 7.2** : En tant qu'emprunteur, je veux voir des informations supplémentaires sur les livres obtenues via une API externe.
    - **Tâche** : Mise à jour des vues pour afficher les informations supplémentaires
    - **Responsables** : Gabriel, Lisa
    - **Relecteurs** : Mathis, Sean
    - **Tests d'acceptation** :
        1. **Étant donné que** l'API externe ne répond pas, **quand** la page de détail s'affiche, **alors** un message l'indique sans erreur.

### API Platform (Partie 1)
- **US 8.1** : En tant qu'administrateur, je veux que les données des livres soient accessibles via une API.
    - **Tâche** : Configuration de API Platform pour l'entité Livre
    - **Responsables** : Jules, Thomas
    - **Relecteurs** : Yacine, Maxime Cu
    - **Tests d'acceptation** :
        1. **Étant donné que** l'API est déployée, **quand** j'envoie une requête `GET` à `/api/livres`, **alors** je reçois un JSON 200 avec la liste des livres.

- **US 8.2** : En tant qu'administrateur, je veux tester l'API pour m'assurer que les données des livres sont correctement exposées.
    - **Tâche** : Tests de l'API pour les livres
    - **Responsables** : Sylvain, Gabriel
    - **Relecteurs** : Léa Mathis
    - **Tests d'acceptation** :
        1. **Étant donné que** l'API est déployée, **quand** j'envoie une requête `GET` à `/api/livres/{id}`, **alors** je reçois un JSON 200 avec les détails du livre.

### API Platform (Partie 2)
- **US 9.1** : En tant qu'administrateur, je veux que les données des auteurs soient accessibles via une API.
    - **Tâche** : Configuration de API Platform pour l'entité Auteur
    - **Responsables** : Eliaz, Jules
    - **Relecteurs** : Maxime Ch, Lisa
    - **Tests d'acceptation** :
        1. **Étant donné que** l'API est déployée, **quand** j'envoie une requête `GET` à `/api/auteurs`, **alors** je reçois un JSON 200 avec la liste des auteurs.

- **US 9.2** : En tant qu'administrateur, je veux tester l'API pour m'assurer que les données des auteurs sont correctement exposées.
    - **Tâche** : Tests de l'API pour les auteurs
    - **Responsables** : Tristan, Yacine
    - **Relecteurs** : Elouan, Sean
    - **Tests d'acceptation** :
        1. **Étant donné que** l'API est déployée, **quand** j'envoie une requête `GET` à `/api/auteurs/{id}`, **alors** je reçois un JSON 200 avec les détails de l'auteur.

### Tests et Déploiement
- **US 10.1 & 10.2** : Écrire des tests unitaires pour les contrôleurs et fonctionnels pour les vues.
    - **Tâche** : Écriture des tests unitaires et fonctionnels
    - **Responsables** : Maxime Cu, Thomas (Unitaires) & Sylvain, Gabriel (Fonctionnels)
    - **Relecteurs** : Léa, Mathis (pour Unitaires) & Eliaz, Jules (pour Fonctionnels)
    - **Tests d'acceptation** :
        1. **Quand** je lance la commande `php bin/phpunit`, **alors** tous les tests passent avec succès.

- **US 10.3 & 10.4** : Préparer le déploiement de l'application et le documenter.
    - **Tâche** : Configuration du déploiement avec Docker et documentation
    - **Responsables** : Léa, Mathis (Docker) & Eliaz, Jules (Documentation)
    - **Relecteurs** : Maxime Cu, Thomas (pour Docker) & Sylvain, Gabriel (pour Documentation)
    - **Tests d'acceptation** :
        1. **Quand** je lance `docker-compose up -d`, **alors** l'application est accessible en local.
        2. **Quand** un autre développeur suit la documentation, **alors** il peut déployer l'application sans aide.


### Fonctionnalités Supplémentaires

- **US 11.1** : En tant qu'administrateur, je veux pouvoir gérer les entités via EasyAdmin de manière sécurisée.
    - **Tâche** : Configuration et intégration d'EasyAdmin pour la gestion des entités.
    - **Responsables** : Maxime Ch, Lisa
    - **Relecteurs** : Tristan, Yacine
    - **Rôle de support (Tous les autres étudiants)** : Test de l'interface d'administration au fur et à mesure de sa création, suggestions sur l'ergonomie.
    - **Tests d'acceptation** :
        1. **Étant donné que** je suis connecté en tant qu'administrateur (`ROLE_ADMIN`), **quand** j'accède au dashboard EasyAdmin, **alors** je vois les options pour gérer les entités `Livre`, `Auteur`, etc.
        2. **Étant donné que** je suis connecté en tant que simple utilisateur (`ROLE_USER`), **quand** j'essaie d'accéder au dashboard, **alors** l'accès m'est refusé.

- **US 11.2** : En tant qu'administrateur système, je veux sécuriser l'API afin de protéger les données.
    - **Tâche** : Implémentation de la sécurité pour l'API (authentification par token).
    - **Responsables** : Elouan, Sean
    - **Relecteurs** : Maxime Cu, Thomas
    - **Rôle de support (Tous les autres étudiants)** : Utilisation d'outils comme Postman ou l'interface d'API Platform pour tester les endpoints sécurisés et non sécurisés.
    - **Tests d'acceptation** :
        1. **Étant donné que** je ne suis pas authentifié, **quand** j'essaie d'accéder à un endpoint d'API protégé, **alors** je reçois une réponse 401 (Unauthorized).
        2. **Étant donné que** je suis authentifié avec un token valide, **quand** j'accède au même endpoint, **alors** je reçois une réponse 200 avec les données.

- **US 11.3** : En tant que bibliothécaire, je veux pouvoir consulter les livres les plus empruntés du mois dernier.
    - **Tâche** : Ajout de routes API pour récupérer les livres les plus empruntés du mois dernier.
    - **Responsables** : Sylvain, Gabriel
    - **Relecteurs** : Léa, Mathis
    - **Rôle de support (Tous les autres étudiants)** : Création d'un jeu de données (fixtures) complexe avec de nombreux emprunts pour valider la pertinence des résultats de la statistique.
    - **Tests d'acceptation** :
        1. **Étant donné que** des emprunts ont été enregistrés, **quand** j'appelle l'endpoint `/api/livres/les-plus-empruntes`, **alors** je reçois une liste de livres ordonnée par le nombre d'emprunts.

- **US 11.4** : En tant qu'emprunteur, je veux pouvoir consulter et modifier mes informations personnelles.
    - **Tâche** : Création d'une page de profil utilisateur.
    - **Responsables** : Léa, Yacine
    - **Relecteurs** : Maxime Ch, Thomas
    - **Rôle de support (Tous les autres étudiants)** : Test du formulaire de modification du profil et suggestions d'améliorations.
    - **Tests d'acceptation** :
        1. **Étant donné que** je suis connecté, **quand** j'accède à la page "Mon Profil", **alors** je vois mes informations (nom, prénom, email, téléphone).
        2. **Étant donné que** je suis sur ma page de profil, **quand** je modifie mon numéro de téléphone et que je valide, **alors** mes informations sont mises à jour.

- **US 11.5** : En tant que développeur, je veux sécuriser les actions sur les emprunts à l'aide d'un Voter.
    - **Tâche** : Création d'un `EmpruntVoter` pour gérer les permissions d'emprunt et de retour.
    - **Responsables** : Maxime Cu, Lisa
    - **Relecteurs** : Tristan, Yacine
    - **Détail de l'implémentation** :
        -   Créer une classe `EmpruntVoter` via `make:voter`.
        -   Le voter doit gérer les permissions `EMPRUNTER` et `RETOURNER` sur un objet `Exemplaire`.
        -   Pour `EMPRUNTER` : vérifier que l'utilisateur est connecté et que le statut de l'exemplaire est `DISPONIBLE`.
        -   Pour `RETOURNER` : vérifier que l'utilisateur a le rôle `ROLE_LIBRARIAN` ou `ROLE_ADMIN` et que le statut de l'exemplaire est `EMPRUNTE`.
        -   Utiliser ce voter dans les contrôleurs avec `$this->denyAccessUnlessGranted('EMPRUNTER', $exemplaire);` avant d'effectuer l'action.
    - **Tests d'acceptation** :
        1. **Étant donné** un exemplaire disponible et un utilisateur connecté, **quand** l'utilisateur tente d'emprunter, **alors** l'accès est autorisé.
        2. **Étant donné** un exemplaire déjà emprunté, **quand** un utilisateur tente de l'emprunter, **alors** l'accès est refusé.
        3. **Étant donné** un utilisateur non bibliothécaire, **quand** il tente de marquer un livre comme retourné, **alors** l'accès est refusé.

## Partie 4 : Refactoring et Améliorations Avancées

Cette phase vise à améliorer la robustesse et la maintenabilité du code en introduisant des composants avancés de Symfony.

- **US 12.1** : En tant que développeur, je veux refactoriser la gestion des statuts des emprunts et des exemplaires en utilisant le composant Workflow.
    - **Tâche** : Remplacer la logique de changement de statut manuelle par des workflows définis.
    - **Responsables** : Sylvain, Gabriel
    - **Relecteurs** : Léa, Mathis
    - **Détail de l'implémentation** :
        -   Installer le composant `symfony/workflow`.
        -   Définir un workflow `emprunt_status` pour l'entité `Emprunt` avec les états `EN_COURS`, `RETOURNE`, `EN_RETARD` et les transitions associées (`retourner`, `marquer_en_retard`).
        -   Définir un workflow `exemplaire_status` pour l'entité `Exemplaire` avec les états `DISPONIBLE`, `EMPRUNTE`, `PERDU` et les transitions (`emprunter`, `retourner`, `declarer_perdu`).
        -   Refactoriser le code des contrôleurs et des commandes (ex: `US 6.2`, `US 6.4`) pour utiliser le service de workflow (`$workflow->apply()`) au lieu de modifier le statut manuellement.
    - **Tests d'acceptation** :
        1. **Étant donné** un exemplaire avec le statut `DISPONIBLE`, **quand** j'essaie d'appliquer la transition `retourner`, **alors** le workflow lève une exception.
        2. **Étant donné** un emprunt, **quand** l'action d'emprunt est effectuée, **alors** le statut de l'emprunt et de l'exemplaire sont mis à jour via le service de workflow.

- **US 12.2** : En tant que développeur, je veux améliorer le Voter pour qu'il utilise le workflow pour vérifier les permissions.
    - **Tâche** : Refactoriser `EmpruntVoter` pour qu'il s'appuie sur la logique du workflow.
    - **Responsables** : Eliaz, Jules
    - **Relecteurs** : Maxime Ch, Lisa
    - **Détail de l'implémentation** :
        -   Injecter le registre des workflows (`WorkflowRegistry`) dans le `EmpruntVoter`.
        -   Pour la permission `EMPRUNTER`, utiliser `$workflow->can($exemplaire, 'emprunter')` pour vérifier si la transition est possible, en plus des autres vérifications (utilisateur connecté).
        -   Pour la permission `RETOURNER`, utiliser `$workflow->can($exemplaire, 'retourner')` en plus de la vérification du rôle.
    - **Tests d'acceptation** :
        1. **Étant donné** un exemplaire déjà emprunté, **quand** le `EmpruntVoter` vérifie la permission `EMPRUNTER`, **alors** il retourne `false` car la transition n'est pas autorisée par le workflow.

## Répartition des Tâches et Planning sur 12 semaines

Pour assurer une charge de travail équilibrée et une collaboration variée, le projet est divisé en 3 phases de 4 semaines. Les binômes sont recomposés à chaque phase. Le planning est ajusté pour refléter la nouvelle structure des US et une meilleure progressivité.

| Tâche Principale                                     |               Phase 1 (Semaines 1-4) : Modélisation & Données                | Phase 2 (Semaines 5-8) : Interfaces & Logique simple | Phase 3 (Semaines 9-12) : Logique avancée, API & Finalisation |
|------------------------------------------------------|:----------------------------------------------------------------------------:|:----------------------------------------------------:|:-------------------------------------------------------------:|
| **Binômes**                                          |                                                                              |                                                      |                                                               |
| **US 2.1 à 2.4** : Entités `Livre`, `Auteur`, `Editeur`, `Categorie` | **Sylvain,Léa** & **Eliaz,Maxime Ch** & **Gabriel,Tristan** & **Jules,Lisa** |                     (Relecture)                      |                          (Relecture)                          |
| **US 2.5** : Entités `User`, `Emprunteur`              |                     **Mathis,Elouan** & **Yacine,Lisa**                      |                     (Relecture)                      |                          (Relecture)                          |
| **US 3.1 à 3.3** : Fixtures (p1), Entités `Exemplaire`, `Emprunt` |           **Jules,Lisa** & **Yacine,Sean** & **Maxime Cu,Thomas**            |                     (Relecture)                      |                          (Relecture)                          |
| **US 3.4, 3.5, 3.6** : Repositories, Fixtures (p2), Validation |                                 (Relecture)                                  |       **Eliaz,Maxime Ch** & **Yanis,Lisa** & **Gabriel,Mathis** & **Tristan,Elouan**          |                          (Relecture)                          |
| **US 4.1, 4.2, 5.1, 5.2** : Contrôleurs & Vues         |                                 (Relecture)                                  |      **Sylvain,Eliaz** & **Gabriel,Mathis** & **Jules,Yacine** & **Maxime Cu,Thomas**                |                          (Relecture)                          |
| **US 6.1 & 6.2** : Logique métier (Emprunt/Retour)     |                                 (Relecture)                                  |                     (Relecture)                      |                  **Sylvain,Maxime Ch** & **Eliaz,Elouan**                          |
| **US 6.3 & 6.4** : Logique système (Commande, Listener) |                                 (Relecture)                                  |                     (Relecture)                      |                  **Mathis,Sean** & **Yacine,Maxime Cu**                         |
| **US 7.1 & 7.2** : API Externe (Google Books)          |                                 (Relecture)                                  |                     (Relecture)                      |                      **Léa,Tristan** & **Gabriel,Lisa**                             |
| **US 8.1 à 9.2** : API Platform (Livre, Auteur)        |                                 (Relecture)                                  |                     (Relecture)                      |                      **Jules,Thomas** & **Sylvain,Gabriel** & **Eliaz,Jules** & **Tristan,Yacine**                             |
| **US 10.1 à 11.5** : Tests, Déploiement, Admin, Sécurité |                                 (Relecture)                                  |                     (Relecture)                      |                     **Maxime Cu,Thomas** & **Sylvain,Gabriel** & **Léa,Mathis** & **Eliaz,Jules** & **Maxime Ch,Lisa** & **Elouan,Sean** & **Léa,Yanis** & **Maxime Cu,Lisa**                             |
| **US 12.1 & 12.2** : Refactoring (Workflow & Voter)    |                                 (Relecture)                                  |                     (Relecture)                      | **Sylvain,Gabriel** & **Eliaz,Jules** (en parallèle ou après) |

**Légende :**
-   Les binômes en **gras** sont les **responsables** de la tâche pour la phase donnée.
-   Les autres binômes agissent en tant que **relecteurs** ou **support** sur les autres tâches de la phase.

Ce planning structuré par phases et avec rotation des binômes permet à chaque étudiant de se concentrer sur des tâches de complexité variable tout au long du projet, de collaborer avec différents partenaires et d'avoir une vision globale du code base.

## Conclusion
J'espère que ce projet vous permettra de mettre en pratique vos compétences en Symfony tout en travaillant en équipe.

N'hésitez pas à poser des questions ou à demander de l'aide si nécessaire.

Bon courage à tous !
