docs: regrouper la documentation dans docs/ (hors README)

This commit is contained in:
devcodetools committed 2026-09-22 09:21:18 +02:00
1 parent 087945472a
commit 8ff530bf99
4 files changed
+1 -1

No files matched your search

+36
View File
@@ -0,0 +1,36 @@
# Application web Flashcards
Flashcards est application web SPA PWA permet d'afficher des cartes sur des sujets de code, de développement ou de culture tech.
## Principe du jeu
Le jeu consiste à afficher une carte au hasard.
une question ou un terme apparaît. La réponse est cachée. Si l'utilisateur souhaite consuletr la réponse, il peut faire dérouler la réponse.
Il est néanmoins possible de sélectionner une carte au hasard sur un thème plus précis : code, langage, etc...
L'utilisateur peut créer, modifier ou supprimer une carte (CRUD).
L'utilisatuer peut afficher la liste des cartes ou consulter une carte spécifique.
## Stack technique
- Framework : Next Js
- Typescript
- Tailwind
- Eslint, Prettier
- Test unitaires : Vitest avec coverage
### Base de données
Bien qu'il n'y ait réellement pas besoin de 2 SGBD, dans un but pédagogique, il faudra gérer les 2 bases de données simultanément.
Les composants d'accès aux données devront être le plus génériques possibles.
- Mysql (conteneur Docker)
- Mongo Db (conteneur Docker)
### Déploiement
- Docker via docker-compose
- Volumes managés
+91
View File
@@ -0,0 +1,91 @@
# MOD_OP — Mode opératoire (lancement et exploitation)
Procédure pas à pas pour lancer, vérifier, développer et arrêter l'application flashcards (web + MySQL + MongoDB en conteneurs Docker).
## 1. Prérequis
- Docker + Docker Compose installés et démarrés.
- Node.js >= 20.19.0 et pnpm >= 9 (uniquement pour le mode dev local, étape 5).
## 2. Démarrage complet (production-like)
Depuis la racine du projet :
```bash
docker compose up -d --build
```
- `--build` : construit l'image du service web (nécessaire à la première exécution).
- Le service `web` attend que `mysql` et `mongo` soient **healthy** (`depends_on` + healthchecks).
Résultat attendu (3 conteneurs up) :
| Service | Conteneur | Image | Port hôte | Port interne |
| ------- | ---------------- | --------- | --------- | ------------ |
| web | flashcards-web | (build .) | **4000** | 3000 |
| mysql | flashcards-mysql | mysql:8.4 | 13306 | 3306 |
| mongo | flashcards-mongo | mongo:8.2 | 27018 | 27017 |
> **Attention** : le port hôte 4000 a été retenu car 3000/3001 sont souvent occupés par d'autres processus. Le web écoute donc sur **http://localhost:4000**.
## 3. Vérifications
```bash
docker compose ps # 3 services "running" (mysql/mongo "healthy")
curl http://localhost:4000/api/themes
curl http://localhost:4000/api/cards
```
- La liste des thèmes doit répondre `["docker","git","javascript","react","typescript"]` (seed).
- Ouvrir **http://localhost:4000** : accueil, puis `/play` (tirage de cartes), `/cards` et `/cards/new` (CRUD).
## 4. Choisir l'implémentation SGBD (`DB_IMPL`)
L'application est branchée sur une couche générique : MySQL (`mysql`, défaut) ou MongoDB (`mongo`).
```bash
docker compose stop web
DB_IMPL=mongo docker compose up -d web # bascule sur MongoDB
DB_IMPL=mysql docker compose up -d web # retour sur MySQL (défaut)
```
## 5. Mode développement local (hot reload)
Les bases restent en Docker, l'appli tourne en local :
```bash
cp .env.example .env
docker compose up -d mysql mongo # bases seules
pnpm install
pnpm dev # http://localhost:3000
```
Le `.env` pointe vers les ports exposés des conteneurs (`localhost:13306`, `localhost:27018`) et `DB_IMPL=mysql` par défaut.
## 6. Ré-initialiser le seed
Les scripts `docker/init/*` ne s'exécutent **qu'à la première création des volumes** (y compris l'encodage UTF-8 forcé par `02-seed.sh`). Pour repartir d'un état vierge :
```bash
docker compose down -v # ⚠️ supprime les données des volumes nommés
docker compose up -d
```
## 7. Arrêt / redémarrage / nettoyage
```bash
docker compose stop # arrêt (données conservées)
docker compose start # redémarrage
docker compose restart web # redémarrage du web seul
docker compose down # arrêt + suppression des conteneurs (volumes conservés)
docker compose down -v # arrêt + suppression des conteneurs ET des volumes
```
## 8. Dépannage rapide
| Symptôme | Action |
| --------------------------------------- | ----------------------------------------------------------------------- |
| Le web ne démarre pas | `docker compose logs web` (il attend le healthy des bases) |
| `Authentication failed` (Mongo) | Vérifier `?authSource=admin` dans `MONGODB_URI` |
| Caractères accentués illisibles (MySQL) | Seed importé sans utf8mb4 → réinitialiser via l'étape 6 |
| Port déjà utilisé | Le web est sur le port hôte 4000 (modifiable dans `docker-compose.yml`) |
+209
View File
@@ -0,0 +1,209 @@
# 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 :
- [x] Les tests unitaires (Vitest) passent, **coverage** généré et au-dessus du seuil défini
- [x] `lint` (ESLint) et `format` (Prettier — check) sans erreur
- [x] TypeScript strict compile sans erreur
- [x] L'implémentation est branchée sur la **couche générique d'accès aux données**
- [x] Les **deux SGBD** (MySQL + MongoDB) fonctionnent simultanément en local
- [x] Le comportement correspond aux critères d'acceptation de la section 2
- [x] 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
- [x] Page/vue **liste des cartes** (F-08)
- [x] Page/vue **détail d'une carte** (F-09)
- [x] Formulaire **création** (F-05)
- [x] Formulaire **édition** (F-06)
- [x] **Suppression** avec confirmation (F-07)
- [x] Vue **jeu** : tirage aléatoire global + sélecteur de thème (F-01, F-02, F-03, F-04, F-10)
- [x] Navigation/flux SPA cohérent (routes Next.js)
- [x] DoD : phases précédentes + parcours utilisateur complet fonctionnel
### Phase 4 — Tests
- [x] Tests des composants UI (composants critiques)
- [x] Couverture des critères F-01 à F-10
- [x] Coverage au seuil défini (Phase 0)
- [x] 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
- [x] Manifest PWA + service worker (installable, hors-ligne) — la stack SPA le permet
- [x] `docker-compose.yml` : `web`, `mysql`, `mongo`
- [x] Volumes nommés pour l'ensemble des données
- [x] Variables/env de connexion aux 2 SGBD selon l'implémentation sélectionnée (`DB_IMPL`, `MYSQL_*`, `MONGODB_URI`)
- [x] Construction de l'image web et démarrage complet via `docker compose up`
- [x] Test de persistance après redémarrage des conteneurs (MySQL + Mongo)
- [x] 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
- [x] Couverture : seuil de coverage exact (>= 80 % imposé, effectif ~95 % stmts)
- [ ] Selon cas : `Theme` en table dédiée vs dérivation des `theme` distincts
- [x] 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)