From a72a5dd8127cdf441d8e936d1a4b67662f1cc387 Mon Sep 17 00:00:00 2001 From: THOLOT DECHENE Matthieu Date: Wed, 3 Jun 2026 13:56:05 +0000 Subject: [PATCH] docs : refonte du README (dev local seed/no-seed, seed recette/prod, BDD de test) (#56) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Contexte Le README de `develop` ne distinguait pas clairement les parcours de dev avec/sans données de seed, ni la base de test dédiée. Refonte pour une doc projet complète et fidèle au `makefile` actuel. ## Contenu - **Dev local avec / sans données de seed** : `make install` (base vierge — schéma + RBAC structurel, aucun compte) vs `make db-reset` / `make fixtures` (comptes + données de démo). Explicite le piège : `install` ne charge pas les fixtures sur la base dev. - **Création de compte sans seed** : `app:create-user … --admin`. - **Bases de données dev vs test** : base `_test` dédiée et isolée (suffixe auto en `APP_ENV=test`), rôle détaillé de `make test-db-setup` (migrations, schema:update, column-comments, fixtures→sync→seed-rbac, index partiels uniques). - **Tests** : 3 suites (PHPUnit / Vitest / Playwright), prérequis et workflow E2E, règle d'or. - **Seed RBAC recette / prod** : `app:seed-rbac` (+ `--with-demo-users --password`), idempotent et non destructif, ordre de release. - Tableau des commandes `make`, sommaire, prérequis, correction du nom (Starseed) et des ports. Changement **docs uniquement**, aucun code touché. --------- Co-authored-by: admin malio Co-authored-by: Matthieu Reviewed-on: https://gitea.malio.fr/MALIO-DEV/Starseed/pulls/56 Co-authored-by: THOLOT DECHENE Matthieu Co-committed-by: THOLOT DECHENE Matthieu --- README.md | 456 ++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 309 insertions(+), 147 deletions(-) diff --git a/README.md b/README.md index 6663b9d..5388528 100644 --- a/README.md +++ b/README.md @@ -1,209 +1,362 @@ # Starseed -CRM/ERP — Symfony 8 (API Platform 4) + Nuxt 4 +CRM/ERP en architecture **modular monolith DDD** — Symfony 8 (API Platform 4) + Nuxt 4. + +Le backend est la **source de vérité unique** : il décide des modules actifs et de +l'organisation de la sidebar. Le frontend scanne `frontend/modules/*/` comme layers +Nuxt et consomme l'API pour la navigation. + +--- + +## Sommaire + +- [Stack](#stack) +- [Prérequis](#prérequis) +- [Démarrage rapide](#démarrage-rapide) +- [Dev local : avec ou sans données de seed](#dev-local--avec-ou-sans-données-de-seed) +- [Comptes (dev)](#comptes-dev) +- [Bases de données : dev et test](#bases-de-données--dev-et-test) +- [Tests](#tests) +- [Déploiement : seed RBAC en recette / prod](#déploiement--seed-rbac-en-recette--prod) +- [Commandes make](#commandes-make) +- [Architecture](#architecture) +- [Structure du dépôt](#structure-du-dépôt) +- [CI/CD](#cicd) +- [Conventions](#conventions) + +--- ## Stack - **Backend** : PHP 8.4, Symfony 8, API Platform 4, Doctrine ORM, PostgreSQL 16 -- **Frontend** : Nuxt 4 (SPA), Vue 3, Pinia, Tailwind CSS, @malio/layer-ui -- **Auth** : JWT HTTP-only cookie (Lexik) +- **Frontend** : Nuxt 4 (SPA, SSR off), Vue 3, Pinia, Tailwind CSS, @malio/layer-ui, @nuxtjs/i18n +- **Auth** : JWT HTTP-only cookie (Lexik), login sur `/login_check` - **Infra** : Docker Compose (dev + prod multi-stage) - **CI/CD** : Gitea Actions (auto-tag + build Docker) -## Quick Start +| Service | Port | +|---------------|------| +| API (Nginx) | 8083 | +| Frontend dev | 3004 | +| PostgreSQL | 5437 | + +--- + +## Prérequis + +- Docker + Docker Compose +- `make` +- `nvm` (la version de Node est fixée par `.nvmrc`, voir `make node-use`) + +Toutes les commandes `make` s'exécutent dans le container PHP (`php-starseed-fpm`) ; +rien n'est requis sur l'hôte hormis Docker — **sauf les tests E2E**, qui tournent sur +l'hôte (navigateur réel, voir [Tests](#tests)). + +--- + +## Démarrage rapide ```bash -make start # Demarrer les containers Docker -make install # Composer, migrations, fixtures, build Nuxt +make start # Démarre les containers Docker +make install # Composer + clés JWT + migrations + permissions + BDD de test +make dev-nuxt # Serveur Nuxt avec hot reload (http://localhost:3004) ``` -Dev frontend (hot reload) : +`make install` prépare une base de dev **vierge** (schéma + RBAC structurel, sans +données de démo) et la base de **test**. Pour obtenir des comptes et des données de +démo prêtes à l'emploi, lis la section suivante. + +> Override local possible : `make` lit `infra/dev/.env.docker`, surchargé par +> `infra/dev/.env.docker.local` s'il existe (créé automatiquement par `make env-init`). + +--- + +## Dev local : avec ou sans données de seed + +Le projet distingue deux états de base de données de dev. Les **fixtures Doctrine sont +en `require-dev`** : elles n'existent qu'en dev, jamais dans le build de prod. + +### Sans données de seed (base vierge) + +C'est ce que produit `make install`. La base contient : + +- le **schéma** complet (toutes les migrations jouées) ; +- les **rôles système** `admin` / `user` (seedés en SQL par la migration RBAC) ; +- le **catalogue de permissions** synchronisé (`app:sync-permissions`). + +Mais **aucun compte utilisateur ni donnée métier**. Pour pouvoir te connecter, +crée toi-même un compte : ```bash -make dev-nuxt # Port 3003 +make shell +php bin/console app:create-user admin monMotDePasse --admin # compte ROLE_ADMIN ``` -## Ports +Optionnel — provisionner les **rôles métier** (bureau / compta / commerciale / usine ++ matrice RBAC § 2.7) sans comptes de démo : -| Service | Port | -|------------|------| -| API (Nginx)| 8083 | -| Frontend | 3004 | -| PostgreSQL | 5437 | +```bash +php bin/console app:seed-rbac +``` -## Commandes +Cet état est utile pour repartir d'une base propre, reproduire un bug sur données +minimales, ou tester un parcours d'onboarding réel. -| Commande | Description | -|----------|-------------| -| `make start` | Demarrer les containers | -| `make stop` | Arreter les containers | -| `make restart` | Redemarrer les containers | -| `make install` | Install complet | -| `make reset` | Tout supprimer et reinstaller | -| `make dev-nuxt` | Serveur dev Nuxt (hot reload) | -| `make shell` | Shell dans le container PHP | -| `make cache-clear` | Vider le cache Symfony | -| `make migration-migrate` | Lancer les migrations | -| `make fixtures` | Charger les fixtures | -| `make db-reset` | Reset BDD + migrations + fixtures | -| `make test` | PHPUnit (tests back) | -| `make nuxt-test` | Vitest (tests unitaires front) | -| `make test-e2e` | Playwright (tests E2E front) | -| `make test-e2e-ui` | Playwright UI interactive (debug) | -| `make seed-e2e` | Seed les 6 personas E2E | -| `make install-e2e-deps` | One-time : Chromium + libs systeme (sudo) | -| `make php-cs-fixer-allow-risky` | Fix code style PHP | -| `make logs-dev` | Tail logs Symfony | +### Avec données de seed (base de démo) + +`make db-reset` (ou `make fixtures` après un `make install`) recharge la base de dev +avec un jeu complet de données de démonstration, **idempotent** : + +```bash +make db-reset # ATTENTION : drop + recrée la base de dev, puis charge tout le seed +``` + +Ce que les fixtures posent : + +- **3 utilisateurs système** : `admin` (ROLE_ADMIN), `alice`, `bob` (ROLE_USER), + rattachés à des sites distincts ; +- **3 sites** : Chatellerault, Saint-Jean, Pommevic ; +- **les comptes de démo RBAC métier** (`bureau`, `compta`, `commerciale`, `usine`, + mot de passe `demo`) avec la matrice § 2.7 attachée ; +- les **référentiels et données métier** des modules (catégories, clients de démo, + référentiels comptables…). + +Toutes les fixtures sont rejouables sans effet de bord (lookup par clé naturelle, +aucun doublon). + +> Différence avec `make install` : `install` ne charge **pas** les fixtures sur la base +> de dev (il alimente uniquement la base de test). Utilise `make db-reset` ou +> `make fixtures` quand tu veux des données de démo en dev. + +--- + +## Comptes (dev) + +Disponibles uniquement après `make db-reset` / `make fixtures` (état « avec seed ») : + +| Username | Password | Rôle | RBAC métier | +|---------------|----------|------------|---------------------------------------------------------------| +| `admin` | `admin` | ROLE_ADMIN | bypass complet (`is_admin`) | +| `alice` | `alice` | ROLE_USER | — | +| `bob` | `bob` | ROLE_USER | — | +| `bureau` | `demo` | ROLE_USER | clients : view + manage | +| `compta` | `demo` | ROLE_USER | clients : view + accounting.view / manage | +| `commerciale` | `demo` | ROLE_USER | clients : view + manage (Information obligatoire — RG-1.04) | +| `usine` | `demo` | ROLE_USER | aucun accès clients | + +--- + +## Bases de données : dev et test + +Deux bases distinctes vivent dans le **même container PostgreSQL** (port 5437) : + +| Base | Environnement | Construite par | Usage | +|------------|---------------|--------------------------------------|--------------------------------| +| `` | `dev` | `make install` / `make db-reset` | développement manuel, dev-nuxt | +| `_test` | `test` | `make test-db-setup` | PHPUnit (jamais touchée à la main) | + +Le suffixe `_test` est appliqué **automatiquement** par Doctrine quand `APP_ENV=test` +(config `when@test` dans `config/packages/doctrine.yaml`). La base de test est donc +totalement **isolée** de la base de dev : lancer `make test` ne touche jamais tes +données de dev. + +`make test-db-setup` fait davantage que jouer les migrations, car certaines structures +ne sont pas portées par des migrations « métier » : + +1. `doctrine:migrations:migrate` — schéma métier réel ; +2. `doctrine:schema:update --force` — crée les tables mappées en `when@test` + uniquement (entités de test) ; +3. `app:apply-column-comments` — réapplique les `COMMENT ON COLUMN` que + `schema:update` efface sur les tables managées par l'ORM (garde-fou + `ColumnsHaveSqlCommentTest`) ; +4. `fixtures:load` → `sync-permissions` → `seed-rbac` — dans cet ordre précis + (le purger des fixtures vide la table `permission`, donc la sync passe après) ; +5. recréation des **index partiels uniques** (`LOWER(...) WHERE ...`) non exprimables + en attributs ORM, indispensables aux tests d'unicité (RG-1.07, RG-1.16, RG-1.03/1.29). + +`make install` et `make db-reset` appellent déjà `test-db-setup` : tu n'as à le +relancer à la main que si la base de test diverge (nouvelle migration, nouvelle +permission) sans vouloir reseed la base de dev. + +--- ## Tests -- **Back** : `make test` (PHPUnit). Fixtures dediees sous `tests/Fixtures/`. -- **Front unitaire** : `make nuxt-test` (Vitest, happy-dom). Composables, utils, stores — rapide, <30s. -- **Front E2E** : `make test-e2e` (Playwright). Couvre login + matrice RBAC sidebar. Suite volontairement minimaliste (11 tests) — voir la regle d'or dans `CLAUDE.md`. +| Suite | Commande | Outil | Où | +|-------------------|------------------|----------------------|-----------------------------------| +| Back | `make test` | PHPUnit | container PHP, base `_test` | +| Front unitaire | `make nuxt-test` | Vitest (happy-dom) | container Node, < 30 s | +| Front E2E | `make test-e2e` | Playwright | **hôte** (navigateur réel requis) | +| Tout (back+front) | `make test-all` | PHPUnit + Vitest | — | + +### Tests back (PHPUnit) -**Bootstrap E2E (une fois par poste)** : ```bash -make install-e2e-deps # Telecharge Chromium + libs systeme via apt (sudo) +make test # toute la suite +make test FILES=tests/Module/Commercial # un dossier / fichier ciblé ``` -**Workflow E2E** : +PHPUnit force `APP_ENV=test` (`phpunit.dist.xml`) : les tests tournent **toujours** +sur la base `_test`, jamais sur la base de dev. Prérequis : que la base de test +existe — c'est le cas après `make install`. Si elle a divergé, rejoue +`make test-db-setup` (cf. [Bases de données](#bases-de-données--dev-et-test)). + +### Tests front unitaires (Vitest) + ```bash -# Terminal 1 : containers + dev server +make nuxt-test # composables, utils, stores — rapide et stable +``` + +C'est la **place par défaut** pour étendre la couverture (cf. règle d'or ci-dessous). + +### Tests E2E (Playwright) + +Suite volontairement minimaliste (login + matrice RBAC sidebar). **Règle d'or : un +nouveau test E2E ne s'ajoute que si un bug critique est passé en prod** — sinon, +préférer un test Vitest ou étendre un persona existant. + +Bootstrap (une fois par poste) : + +```bash +make install-e2e-deps # télécharge Chromium + libs système (apt/dnf, sudo) +``` + +Workflow : + +```bash +# Terminal 1 — containers, seed des personas, serveur dev make start && make seed-e2e && make dev-nuxt -# Terminal 2 : tests -make test-e2e +# Terminal 2 — tests +make test-e2e # headless +make test-e2e-ui # UI interactive (debug) ``` +> Toute permission testable touche **3 miroirs** à garder alignés : `config/sidebar.php`, +> `frontend/tests/e2e/_fixtures/personas.ts`, `SeedE2ECommand.php`. + +--- + +## Déploiement : seed RBAC en recette / prod + +Les fixtures Doctrine étant en `require-dev`, elles sont **absentes du build de prod**. +Le RBAC métier (rôles `bureau` / `compta` / `commerciale` / `usine` + matrice § 2.7) +est seedé par une **commande applicative idempotente**, jouée dans l'étape de release, +**après** les migrations et la synchronisation des permissions : + +```bash +php bin/console doctrine:migrations:migrate --no-interaction +php bin/console app:sync-permissions # pose les permissions (commercial.clients.*, …) +php bin/console app:seed-rbac # PROD : rôles + matrice § 2.7 (sans comptes démo) +``` + +En **recette / staging**, ajouter le flag pour disposer de logins de test. Le mot de +passe est fourni **explicitement** (jamais en dur, jamais committé) : + +```bash +php bin/console app:seed-rbac --with-demo-users --password='' +# ou via la variable d'environnement RBAC_DEMO_PASSWORD +``` + +La commande est rejouable sans effet de bord (aucun doublon de rôle, de lien ou de +compte). Pour créer un premier administrateur en prod : + +```bash +php bin/console app:create-user --admin +``` + +--- + +## Commandes make + +`make` (sans argument) ou `make help` affiche l'aide colorée. Les principales : + +| Commande | Description | +|--------------------------------|----------------------------------------------------------| +| `make start` / `stop` / `restart` | Cycle de vie des containers | +| `make install` | Install complet (base dev vierge + base de test) | +| `make reset` | Tout supprimer et réinstaller (**drop la BDD**) | +| `make dev-nuxt` | Serveur Nuxt hot reload (port 3004) | +| `make shell` / `shell-root` | Shell bash dans le container PHP | +| `make migration-migrate` | Jouer les migrations Doctrine | +| `make fixtures` | Charger les fixtures (données de démo dev) | +| `make sync-permissions` | Synchroniser le catalogue RBAC | +| `make seed-rbac` | Seed RBAC métier (rôles + matrice § 2.7) | +| `make db-reset` | Reset base dev : drop + migrate + fixtures + RBAC | +| `make test-db-setup` | (Re)construire la base de test | +| `make test` | PHPUnit (back) | +| `make nuxt-test` | Vitest (front unitaire) | +| `make test-all` | PHPUnit + Vitest | +| `make test-e2e` / `test-e2e-ui`| Playwright (E2E, sur l'hôte) | +| `make seed-e2e` | Seed des 6 personas E2E | +| `make php-cs-fixer-allow-risky`| Fix du code style PHP | +| `make php-cs-fixer-check` | Dry-run du fixer (CI / avant push) | +| `make logs-dev` | Tail des logs Symfony | + +--- + ## Architecture -**Modular Monolith DDD** : chaque module est un bounded context autonome, activable/desactivable par tenant. Le backend est la seule source de verite pour l'activation et l'organisation de la sidebar. +**Modular Monolith DDD** : chaque module est un bounded context autonome, +activable / désactivable par tenant. Le backend est la seule source de vérité pour +l'activation des modules et l'organisation de la sidebar. - `config/modules.php` — liste des modules actifs - `config/sidebar.php` — structure de la sidebar (sections + items avec module owner) -- `GET /api/sidebar` — retourne les sections filtrees par les modules actifs + les routes desactivees -- Frontend : chaque `frontend/modules/*/` est auto-detecte comme layer Nuxt, la sidebar est fetchee de l'API +- `GET /api/modules` — IDs des modules actifs (public) +- `GET /api/sidebar` — sections filtrées par modules actifs + routes désactivées (public) -Pour desactiver un module : commenter sa ligne dans `config/modules.php`, clear cache. Ses items de sidebar disparaissent et ses routes sont bloquees par le middleware front. +**Désactiver un module** : commenter sa ligne dans `config/modules.php`, vider le cache. +Ses items de sidebar disparaissent et ses routes sont bloquées par le middleware front. +Le code reste dans le bundle (layer auto-détecté) → réactivation instantanée. -Pour reorganiser la sidebar (ex: deplacer un item d'une section a l'autre) : editer `config/sidebar.php` uniquement, le code des modules n'est pas touche. +**Réorganiser la sidebar** : éditer `config/sidebar.php` uniquement — le code des +modules n'est pas touché. -## Structure +**Communication inter-modules** : jamais d'import direct d'un module à l'autre. Passer +par `Shared/Domain/Contract/` (interfaces) ou des domain events. + +--- + +## Structure du dépôt ``` src/ # Backend Symfony - Kernel.php - Shared/ # Noyau technique partage - Domain/ - ValueObject/ # Email, ... - Event/ # DomainEventInterface - Contract/ # Interfaces inter-modules - Application/ - Bus/ # CommandBusInterface, QueryBusInterface - Infrastructure/ - ApiPlatform/ - Resource/ # AppVersion, ModulesResource, SidebarResource - State/ # AppVersionProvider, ModulesProvider, SidebarProvider + Shared/ # Noyau technique partagé (Domain/, Application/Bus/, Infrastructure/ApiPlatform/) Module/ - Core/ # Module obligatoire (auth, users) - CoreModule.php # Declaration (ID, LABEL, REQUIRED) - Domain/ - Entity/ # User - Repository/ # UserRepositoryInterface - Event/ # UserCreated - Application/ - DTO/ # UserOutput - Infrastructure/ - Doctrine/ # DoctrineUserRepository, Migrations/ - ApiPlatform/State/ - Provider/ # MeProvider - Processor/ # UserPasswordHasherProcessor - Console/ # CreateUserCommand - DataFixtures/ # AppFixtures - Commercial/ # Autre module (exemple) - CommercialModule.php + Core/ # Module obligatoire (auth, users, RBAC) + CoreModule.php # Déclaration (ID, LABEL, REQUIRED, permissions()) + Domain/ Application/ Infrastructure/ + Commercial/ Catalog/ Sites/ # Modules métier config/ - modules.php # Source de verite activation - sidebar.php # Source de verite navigation - version.yaml - packages/ # Config Symfony - jwt/ # Cles JWT -migrations/ # Anciennes migrations + modules.php # Source de vérité : activation + sidebar.php # Source de vérité : navigation + packages/ # Config Symfony (doctrine, api_platform, security…) +migrations/ # Migrations d'initialisation (namespace racine : setup, RBAC, seed de base) frontend/ # App Nuxt 4 (SPA) - app/ - layouts/ # default.vue, auth.vue - middleware/ # auth.global.ts, modules.global.ts - shared/ # Code partage (hors modules) - composables/ # useApi, useAppVersion, useSidebar - components/ui/ # AppTopNav, ... - stores/ # auth, ui - services/ # auth - types/ # SidebarSection, UserData - utils/ # api (Hydra) - modules/ # Modules auto-detectes comme layers Nuxt - core/ - nuxt.config.ts # Marqueur layer - pages/ # index, login, logout - commercial/ - nuxt.config.ts - pages/ # commercial.vue - app.vue - nuxt.config.ts # Scanne modules/*/ automatiquement - i18n/locales/ # Traductions (sidebar.*, etc.) - assets/ # CSS, images - public/ # Fichiers statiques + app/ # Shell : layouts, middlewares (auth.global, modules.global) + shared/ # Code inter-modules (composables, stores, utils, types) + modules/ # Layers Nuxt auto-détectés (core/, commercial/…) + i18n/locales/ # Traductions (sidebar.*, audit.entity.*, …) infra/ - dev/ # Docker dev (Dockerfile, nginx, php.ini, xdebug) + dev/ # Docker dev (Dockerfile, nginx, php.ini, xdebug, .env.docker) prod/ # Docker prod (multi-stage, nginx, php-prod.ini) .gitea/workflows/ # CI Gitea (auto-tag, build Docker) -.claude/ - skills/create-module/ # Skill Claude Code pour scaffolder un module ``` +--- + ## CI/CD - **Auto Tag** : push sur `develop` → bump `config/version.yaml` → tag `vX.Y.Z` - **Build Docker** : push tag `v*` → build image multi-stage → push Gitea Registry Secrets requis dans Gitea : + - `RELEASE_TOKEN` — PAT avec droits `write:repository` - `REGISTRY_TOKEN` — token pour le registry Docker -## Déploiement — seed RBAC (recette / prod) - -Le RBAC métier (rôles `bureau` / `compta` / `commerciale` / `usine` + matrice § 2.7) -est seedé par une **commande applicative idempotente** (présente dans le build prod, -contrairement aux fixtures Doctrine en `require-dev`). À jouer dans l'étape de release, -**après** les migrations et la synchronisation des permissions : - -```bash -php bin/console doctrine:migrations:migrate --no-interaction -php bin/console app:sync-permissions # pose les permissions commercial.clients.* -php bin/console app:seed-rbac # PROD : rôles + matrice § 2.7 (sans comptes démo) -``` - -En **recette / staging**, ajouter le flag pour disposer de logins de test (mot de passe -fourni explicitement, jamais en dur) : - -```bash -php bin/console app:seed-rbac --with-demo-users --password='' -# ou via la variable d'env RBAC_DEMO_PASSWORD -``` - -La commande est rejouable sans effet de bord (aucun doublon de rôle, de lien ou de compte). -En dev, `make db-reset` produit le même résultat (rôles + matrice + comptes démo). - -## Credentials (dev) - -| Username | Password | Role | RBAC métier | -|----------|----------|------|-------------| -| admin | admin | ROLE_ADMIN | bypass (is_admin) | -| alice | alice | ROLE_USER | — | -| bob | bob | ROLE_USER | — | -| bureau | demo | ROLE_USER | clients : view + manage | -| compta | demo | ROLE_USER | clients : view + accounting.view/manage | -| commerciale | demo | ROLE_USER | clients : view + manage (Information obligatoire — RG-1.04) | -| usine | demo | ROLE_USER | aucun accès clients | +--- ## Conventions @@ -213,4 +366,13 @@ En dev, `make db-reset` produit le même résultat (rôles + matrice + comptes d () : ``` -Types : `build`, `chore`, `ci`, `docs`, `feat`, `fix`, `perf`, `refactor`, `revert`, `style`, `test` +Espaces obligatoires autour du `:`. Types : `build`, `chore`, `ci`, `docs`, `feat`, +`fix`, `perf`, `refactor`, `revert`, `style`, `test`. + +### Langue + +- UI et communication : **français** +- Code (classes, méthodes, variables) : **anglais** +- Commentaires (PHP, TS, Vue) : **français** + +> Règles détaillées : `CLAUDE.md` et `.claude/rules/`.