Files
Coltura/CLAUDE.md
Matthieu 2fe1062106
Some checks failed
Auto Tag Develop / tag (push) Has been cancelled
docs : add DDD architecture guidelines to CLAUDE.md
Backend: Domain/Application/Infrastructure/Api layers per bounded context.
Frontend: domains/{context}/ modules with isolated components/services/stores.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-07 11:32:42 +02:00

8.8 KiB

Coltura

CRM/ERP. Monorepo Symfony 8 (API Platform 4) + Nuxt 4. Architecture DDD (Domain-Driven Design).

Architecture DDD

Le projet suit une architecture DDD cote backend ET frontend. Le code est organise par domaine metier (Bounded Context), pas par type technique.

Backend — Organisation par domaine

src/
  Domain/                        # Couche domaine (logique metier pure, aucune dependance framework)
    {BoundedContext}/             # Ex: Customer, Sales, Catalog, Invoice...
      Entity/                    # Entites et Aggregates du domaine
      ValueObject/               # Value Objects (Money, Address, Email...)
      Repository/                # Interfaces des repositories (ports)
      Service/                   # Services domaine (logique metier)
      Event/                     # Domain Events
      Exception/                 # Exceptions metier
  Application/                   # Couche application (cas d'usage, orchestration)
    {BoundedContext}/
      Command/                   # Commands (write) + Handlers
      Query/                     # Queries (read) + Handlers
      DTO/                       # Data Transfer Objects
  Infrastructure/                # Couche infrastructure (implementations techniques)
    {BoundedContext}/
      Repository/                # Implementations Doctrine des repositories
      Persistence/               # Mapping Doctrine (si XML/YAML)
    Shared/                      # Services techniques partages (mail, storage, etc.)
  Api/                           # Couche API (exposition HTTP)
    {BoundedContext}/
      Resource/                  # ApiResource API Platform
      State/                     # Providers & Processors API Platform

Regles DDD backend :

  • Le domaine (Domain/) ne depend de RIEN (pas de Doctrine, pas de Symfony, pas d'API Platform)
  • Les repositories dans Domain/ sont des interfaces ; les implementations Doctrine sont dans Infrastructure/
  • Les entites API Platform (Api/Resource/) sont decouples des entites domaine si necessaire
  • Chaque Bounded Context est autonome — pas d'import croise entre contextes (communiquer via events ou services application)
  • User et Auth restent dans src/ (hors DDD) car c'est du framework pur (Security Bundle)

Frontend — Organisation par domaine

frontend/
  domains/                       # Modules metier
    {bounded-context}/           # Ex: customer, sales, catalog, invoice...
      components/                # Composants Vue specifiques au domaine
      composables/               # Composables specifiques au domaine
      services/                  # Services API du domaine
      dto/                       # Types TypeScript du domaine
      pages/                     # Pages du domaine (optionnel, ou dans pages/)
      stores/                    # Store Pinia du domaine (si necessaire)
  components/                    # Composants UI partages (non lies a un domaine)
  composables/                   # Composables partages (useApi, useAppVersion)
  stores/                        # Stores globaux (auth, ui)
  services/                      # Services partages

Regles DDD frontend :

  • Chaque domaine est un dossier autonome dans frontend/domains/
  • Un domaine ne doit pas importer depuis un autre domaine — utiliser les composables/stores partages
  • Les composants, services et types partages restent a la racine (components/, composables/, etc.)
  • Les pages peuvent etre dans frontend/pages/ (routing Nuxt) et importer les composants du domaine

Stack

  • Backend : PHP 8.4, Symfony 8.0, API Platform 4, Doctrine ORM, PostgreSQL 16
  • Frontend : Nuxt 4 (SSR off / SPA), Vue 3, Pinia, Tailwind CSS, @malio/layer-ui, nuxt-toast, @nuxtjs/i18n, @nuxt/icon
  • Auth : JWT HTTP-only cookie (lexik/jwt-authentication-bundle), login a /login_check, cookie BEARER
  • Docker : PHP-FPM + Node 24, Nginx (port 8083), PostgreSQL (port 5436)

Structure

src/
  Domain/{Context}/Entity/       # Entites domaine
  Domain/{Context}/ValueObject/  # Value Objects
  Domain/{Context}/Repository/   # Interfaces repositories
  Domain/{Context}/Service/      # Services domaine
  Domain/{Context}/Event/        # Domain Events
  Application/{Context}/Command/ # Commands + Handlers
  Application/{Context}/Query/   # Queries + Handlers
  Application/{Context}/DTO/     # Data Transfer Objects
  Infrastructure/{Context}/Repository/ # Implementations Doctrine
  Api/{Context}/Resource/        # ApiResource API Platform
  Api/{Context}/State/           # Providers & Processors
  Entity/                        # Entites framework (User)
  DataFixtures/                  # Fixtures
config/                          # Config Symfony
config/jwt/                      # Cles JWT
migrations/                      # Migrations Doctrine
infra/dev/                       # Docker dev
infra/prod/                      # Docker prod (multi-stage)
frontend/
  domains/{context}/components/  # Composants du domaine
  domains/{context}/composables/ # Composables du domaine
  domains/{context}/services/    # Services API du domaine
  domains/{context}/dto/         # Types TS du domaine
  domains/{context}/stores/      # Store Pinia du domaine
  components/                    # Composants UI partages
  composables/                   # Composables partages (useApi, useAppVersion)
  stores/                        # Stores globaux (auth, ui)
  pages/                         # Pages (routing Nuxt)
  layouts/                       # Layouts
  i18n/locales/                  # Traductions

Commandes

make start           # Demarrer les containers
make stop            # Arreter les containers
make restart         # Redemarrer les containers
make install         # Install complet (composer, migrations, fixtures, build Nuxt)
make reset           # Tout supprimer et reinstaller (supprime la BDD)
make dev-nuxt        # Dev server Nuxt (hot reload, port 3003)
make shell           # Shell dans le container PHP
make shell-root      # Shell root 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
make php-cs-fixer-allow-risky # Fix code style PHP
make logs-dev        # Tail logs Symfony

Conventions

Commits

Format : <type>(<scope optionnel>) : <message> (espace avant et apres :)

Types autorises (minuscules) : build, chore, ci, docs, feat, fix, perf, refactor, revert, style, test

Exemples : feat : add login page, fix(auth) : prevent null token crash

Tags & Versioning

  • La version de l'app est dans config/version.yaml (parametre app.version)
  • A chaque creation de tag, toujours mettre a jour config/version.yaml avec la meme version
  • Faire un commit separe de bump : chore : bump version to v<X.Y.Z>
  • Puis creer le tag et pusher : git tag v<X.Y.Z> && git push origin develop --tags

Backend

  • Toujours declare(strict_types=1) en haut des fichiers PHP
  • API Platform : utiliser ApiResource, Providers (src/State/), Processors — pas de controllers
  • Routes API prefixees /api (via config/routes/api_platform.yaml)
  • Le login (/login_check) est hors prefix /api, nginx reecrit REQUEST_URI vers /login_check
  • PHP CS Fixer : regles Symfony + PSR-12 + strict types
  • Roles : ROLE_ADMIN, ROLE_USER — hierarchie dans security.yaml
  • PostgreSQL : noms de colonnes toujours en minuscules dans le SQL brut
  • Controllers custom sous /api/ : ajouter priority: 1 sur #[Route] pour eviter le conflit avec API Platform {id}
  • Serialization : pour embarquer une relation (pas IRI), ajouter le groupe du parent aux proprietes de l'entite cible
  • Upload fichiers : utiliser $file->getMimeType() (pas getClientMimeType()) pour valider cote serveur

Frontend

  • TypeScript strict
  • Composable useApi() pour tous les appels API (gere cookies, erreurs, toasts, i18n)
  • Stores Pinia : useAuthStore (auth), useUiStore (ui)
  • Middleware global auth.global.ts protege les routes
  • Traductions dans frontend/i18n/locales/
  • 4 espaces d'indentation

Nginx

  • /api/* -> Symfony (via try_files + index.php)
  • /api/login_check -> location exact match, fastcgi direct avec REQUEST_URI reecrit en /login_check
  • / -> SPA frontend (frontend/dist/)

Docker

  • Container PHP : php-coltura-fpm
  • Container Nginx : nginx-coltura
  • Container DB : PostgreSQL sur port 5436 (interne et externe)
  • Config Docker dev : infra/dev/.env.docker (override local : infra/dev/.env.docker.local)
  • Config Docker prod : infra/prod/ (Dockerfile multi-stage, docker-compose.prod.yml)
  • Apres modif nginx : docker restart nginx-coltura

Fixtures

  • User admin : admin / admin (ROLE_ADMIN)
  • Users internes : alice / alice, bob / bob (ROLE_USER)