Files
flashcards/TODO.md
T
devcodetools f165168608 feat(deploy): image web Docker et docker-compose complet (P5)
- Dockerfile multi-étapes (node:22-alpine, pnpm, output standalone), .dockerignore
- docker-compose : service web (hôte 4000) + mysql + mongo avec volumes nommés
- Env de connexion selon DB_IMPL (MYSQL_*, MONGODB_URI) ; mongo ?authSource=admin
- Seed MySQL via 02-seed.sh (--default-character-set=utf8mb4) pour un UTF-8 propre
- fix(api): parseTags gère les colonnes JSON déjà parsées par mysql2
- TODO : phase 5 et DoD cochées
2026-09-22 09:00:07 +02:00

12 KiB

TODO — Application web Flashcards (développement assisté par IA)

Document de spécifications et checklist destiné à guider un agent IA dans le développement complet de l'application. Il complète le GOAL.md en le rendant actionnable.


1. Contexte produit

Application web SPA + PWA : Flashcards affiche des cartes (questions/réponses) sur des sujets de code, de développement ou de culture tech.

Principe du jeu

  • Affichage d'une carte au hasard : une question ou un terme apparaît, la réponse est cachée.
  • L'utilisateur peut révéler la réponse à la demande.
  • Possibilité de tirer une carte au hasard sur un thème précis (code, langage, etc.).

Gestion des cartes

  • L'utilisateur peut créer, modifier ou supprimer une carte (CRUD complet).
  • L'utilisateur peut afficher la liste des cartes ou consulter une carte spécifique.

2. Exigences fonctionnelles

Chaque exigence doit être satisfaite avant de considérer la feature terminée.

Ref Exigence Critère d'acceptation
F-01 Afficher une carte au hasard Un clic sur « Jouer » affiche UNE carte tirée aléatoirement de l'ensemble des cartes
F-02 Dans un tirage aléatoire, la question est visible et la réponse cachée Le terme/question s'affiche ; la réponse ne s'affiche pas
F-03 Révéler la réponse Un clic (ou action) déroule/affiche la réponse cachée ; un second clic la masque
F-04 Tirer une carte au hasard par thème L'utilisateur choisit un thème ; le tirage se fait uniquement parmi les cartes de ce thème
F-05 Créer une carte Formulaire de création avec question, réponse et thème ; la carte est persistée
F-06 Modifier une carte Formulaire pré-rempli ; la modification est persistée
F-07 Supprimer une carte Confirmation avant suppression ; la carte disparaît de la liste
F-08 Lister les cartes La liste complète des cartes s'affiche (avec au minimum question + thème)
F-09 Consulter une carte spécifique L'accès direct à une carte (via sa route/id) affiche son détail complet
F-10 Thèmes L'utilisateur peut choisir un thème reflétant les cartes existantes

3. Modélisation de données (proposition à valider)

Entité Card

Champ Type Contrainte Description
id string/INT unique (PK) Identifiant stable de la carte
question string requis Terme ou question affiché
response string requis Réponse cachée puis révélée
theme string requis Thème/catégorie (ex. « code », « javascript »)
tags string[] optionnel Mots-clés additionnels
createdAt datetime auto Date de création
updatedAt datetime auto Date de dernière modification

La liste des thèmes peut être dérivée dynamiquement des valeurs theme distinctes présentes en base (simplicité) ou gérée en entité Theme dédiée (robustesse). Choix à figer en phase de conception.

Représentation duale SGBD

  • MySQL : table cards
  • MongoDB : collection cards

Le même id doit permettre de retrouver une carte dans les deux SGBD (l'id métier n'est pas nécessairement l'id technique Mongo).


4. Exigences techniques et architecture

Stack

  • Framework : Next.js
  • Langage : TypeScript (strict)
  • Styles : Tailwind
  • Qualité : ESLint, Prettier
  • Tests unitaires : Vitest avec coverage

Base de données — double SGBD simultané (contrainte pédagogique)

Bien qu'il n'y ait pas réellement besoin de 2 SGBD, dans un but pédagogique les deux bases doivent être gérées simultanément :

  • MySQL (conteneur Docker)
  • MongoDB (conteneur Docker)

Exigence architecturale majeure : couche d'accès aux données GÉNÉRIQUE

Les composants d'accès aux données doivent être le plus générique possible. Concrètement :

  • Définir une abstraction commune (interface/repository générique, ex. CardRepository) exposant les opérations : findAll, findById, create, update, delete, findRandom, findRandomByTheme, findThemes.
  • Fournir deux implémentations de cette abstraction : une pour MySQL, une pour MongoDB.
  • Aucun composant métier (service, route, UI) ne doit dépendre d'un SGBD précis : il consomme uniquement l'abstraction.
  • Les deux implémentations doivent être utilisables et activables (par config/DI/injection), et les tests doivent couvrir les deux.

Déploiement

  • Docker via docker-compose
  • Volumes nommés pour la persistance des données des 2 SGBD
  • Services au minimum : web (Next.js), mysql, mongo

5. Définition de fait (Definition of Done)

Une feature est « faite » si et seulement si :

  • Les tests unitaires (Vitest) passent, coverage généré et au-dessus du seuil défini
  • lint (ESLint) et format (Prettier — check) sans erreur
  • TypeScript strict compile sans erreur
  • L'implémentation est branchée sur la couche générique d'accès aux données
  • Les deux SGBD (MySQL + MongoDB) fonctionnent simultanément en local
  • Le comportement correspond aux critères d'acceptation de la section 2
  • Construit et lançable via docker-compose avec volumes persistants

6. Checklist de développement par phases

Ordre d'exécution recommandé. Passer à la phase suivante uniquement si la DoD de la phase courante est remplie.

Phase 0 — Scaffolding

  • Initialiser le projet Next.js + TypeScript (strict)
  • Configurer Tailwind
  • Configurer ESLint + Prettier
  • Configurer Vitest + rapport de coverage
  • Fixer le seuil de coverage (à définir, ex. 80%)
  • DoD : lint, format, typecheck, test s'exécutent sans erreur sur un squelette

Phase 1 — Données et couche d'accès générique

  • Schéma MySQL (table cards) + migration/seed
  • Schéma MongoDB (collection cards) + seed
  • Interface générique CardRepository (contrat complet)
  • Implémentation MysqlCardRepository
  • Implémentation MongoCardRepository
  • Mécanisme d'activation/sélection de l'implémentation (config)
  • Tests unitaires des deux implémentations
  • DoD : phase 0 + les 2 repositories testés et interchangeables

Phase 2 — API / services métier

  • Service métier CardService reposant uniquement sur l'abstraction repository
  • Routes API : liste, détail, création, modification, suppression
  • Routes API : tirage aléatoire simple + tirage aléatoire par thème + liste des thèmes
  • Validation des entrées (contrats TypeScript / schémas)
  • Gestion d'erreurs cohérente (404 carte inconnue, 400 payload invalide…)
  • Tests unitaires du service (mock du repository)
  • DoD : phases précédentes + contexte de MCP de l'API

Phase 3 — Interface utilisateur

  • Page/vue liste des cartes (F-08)
  • Page/vue détail d'une carte (F-09)
  • Formulaire création (F-05)
  • Formulaire édition (F-06)
  • Suppression avec confirmation (F-07)
  • Vue jeu : tirage aléatoire global + sélecteur de thème (F-01, F-02, F-03, F-04, F-10)
  • Navigation/flux SPA cohérent (routes Next.js)
  • DoD : phases précédentes + parcours utilisateur complet fonctionnel

Phase 4 — Tests

  • Tests des composants UI (composants critiques)
  • Couverture des critères F-01 à F-10
  • Coverage au seuil défini (Phase 0)
  • DoD : toutes phases précédentes vertes + coverage ok

Traceabilité F-01 à F-10 (tests unitaires) :

Ref Critère Couverture
F-01 Carte au hasard play-view.test.tsx, app/play/page.test.tsx, API random, card-service.test
F-02 Question visible, réponse cachée play-view.test.tsx
F-03 Révéler / masquer la réponse play-view.test.tsx
F-04 Tirage par thème play-view.test.tsx, API random, card-service.test
F-05 Créer une carte cards/new/page.test.tsx, card-form.test.tsx, cards/page.test.tsx, API POST
F-06 Modifier une carte (pré-remplie) cards/[id]/edit/page.test.tsx, card-form.test.tsx, API PUT
F-07 Supprimer avec confirmation card-delete.test.tsx, API DELETE
F-08 Lister les cartes cards/page.test.tsx, card-list.test.tsx, API GET
F-09 Consulter une carte spécifique cards/[id]/page.test.tsx, card-detail.test.tsx, API GET [id]
F-10 Thèmes issues des cartes existantes play-view.test.tsx, app/play/page.test.tsx, API themes

Phase 5 — PWA, déploiement

  • Manifest PWA + service worker (installable, hors-ligne) — la stack SPA le permet
  • docker-compose.yml : web, mysql, mongo
  • Volumes nommés pour l'ensemble des données
  • Variables/env de connexion aux 2 SGBD selon l'implémentation sélectionnée (DB_IMPL, MYSQL_*, MONGODB_URI)
  • Construction de l'image web et démarrage complet via docker compose up
  • Test de persistance après redémarrage des conteneurs (MySQL + Mongo)
  • DoD finale pleinement vérifiée

Notes Phase 5 :

  • Image web multi-étapes (node:22-alpine, pnpm, output: 'standalone'), port hôte 4000 (3000/3001 occupés par l'hôte).
  • Correction UTF-8 du seed MySQL : 02-seed.sh avec mysql --default-character-set=utf8mb4 (le .sql brut importait en double-encodage) ; lignes seed réparées en base via CONVERT(BINARY(CONVERT(... USING latin1)) USING utf8mb4).
  • Correction parseTags() dans le repository MySQL (mysql2 auto-parse les colonnes JSON en tableaux).
  • Mongo : URI avec ?authSource=admin (l'utilisateur root est créé dans admin).

7. Points à trancher / en attente de décision

  • Couverture : seuil de coverage exact (>= 80 % imposé, effectif ~95 % stmts)
  • Selon cas : Theme en table dédiée vs dérivation des theme distincts
  • Choix par défaut de l'implémentation repository pour la prod (MySQL par défaut via DB_IMPL)
  • Authentification éventuelle (hors périmètre README, à confirmer si nécessaire)

22/09: phase 3 terminée (jeu + navigation intégrés), pnpm check vert 22/09: phase 4 terminée (tests UI composants + pages, traceabilité F-01 à F-10, coverage ok)