matthieu e0624eace0 fix(audit-log) : reset pendingLogs sur onFlush + valide filtres + documente contrat rollback
Trois corrections issues du code review multi-agent sur la PR audit-log :

- AuditListener : reset defensif de pendingLogs en debut de onFlush. Si
  un flush precedent a leve une exception avant postFlush (qui n'est
  jamais appele sur un flush rate), le state listener gardait des
  changements jamais committes, ecrits a tort par le prochain postFlush
  reussi — audit_log pouvait donc contenir des lignes decrivant des
  evenements qui n'ont pas eu lieu en DB. Test de regression via
  Reflection pour injecter un log orphelin et verifier qu'il n'arrive
  pas dans audit_log.

- AuditLogProvider : validation explicite des filtres performed_at[after]
  et performed_at[before] (strtotime) + whitelist stricte sur `action`
  (create|update|delete). Avant, un input malforme remontait jusqu'a
  Postgres et faisait un 500 (SQLSTATE[22007]). Desormais 400 explicite,
  pas de log pollue.

- doc/audit-log.md : ajoute une section "Contrat" qui explicite ce que
  audit_log garantit (journal des intentions appliquees par l'ORM) et ne
  garantit PAS (reflet exact du commit outermost — une ligne audit peut
  persister si une transaction outermost rollback apres un flush inner
  reussi, parce que l'audit ecrit sur une connexion DBAL dediee).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-02 14:21:49 +02:00
2026-04-07 10:56:57 +02:00
2026-04-07 10:56:57 +02:00
2026-04-07 11:42:56 +02:00

Coltura

CRM/ERP — Symfony 8 (API Platform 4) + Nuxt 4

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)
  • Infra : Docker Compose (dev + prod multi-stage)
  • CI/CD : Gitea Actions (auto-tag + build Docker)

Quick Start

make start           # Demarrer les containers Docker
make install         # Composer, migrations, fixtures, build Nuxt

Dev frontend (hot reload) :

make dev-nuxt        # Port 3003

Ports

Service Port
API (Nginx) 8083
Frontend 3004
PostgreSQL 5437

Commandes

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

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.

Bootstrap E2E (une fois par poste) :

make install-e2e-deps   # Telecharge Chromium + libs systeme via apt (sudo)

Workflow E2E :

# Terminal 1 : containers + dev server
make start && make seed-e2e && make dev-nuxt

# Terminal 2 : tests
make test-e2e

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.

  • 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

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.

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.

Structure

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
  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
config/
  modules.php                     # Source de verite activation
  sidebar.php                     # Source de verite navigation
  version.yaml
  packages/                       # Config Symfony
  jwt/                            # Cles JWT
migrations/                       # Anciennes migrations
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
infra/
  dev/                            # Docker dev (Dockerfile, nginx, php.ini, xdebug)
  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

Credentials (dev)

Username Password Role
admin admin ROLE_ADMIN
alice alice ROLE_USER
bob bob ROLE_USER

Conventions

Commits

<type>(<scope optionnel>) : <message>

Types : build, chore, ci, docs, feat, fix, perf, refactor, revert, style, test

Description
No description provided
Readme 2.8 MiB
Languages
PHP 69.7%
Vue 14.1%
TypeScript 12.4%
Makefile 1.8%
Dockerfile 0.8%
Other 1.2%