eb0b49a7ef2e3f0fa5e4373c95915830df703989
Bug decouvert a l'execution de 'make db-reset' sur base vide : Doctrine Migrations 3.x avec plusieurs 'migrations_paths' execute les migrations dans l'ordre (namespace, version) et non (version, namespace). Le Version20260414150034 sous 'App\Module\Core\...' passait donc avant Version20260407095546 sous 'DoctrineMigrations', provoquant un "relation user does not exist". Deplacement du fichier vers 'migrations/' (namespace DoctrineMigrations). Le chemin modulaire reste configure pour les futurs modules, mais la migration RBAC d'initialisation vit a la racine pour que 'make db-reset' fonctionne en one-shot. Smoke test end-to-end valide : - db-reset + fixtures : admin (is_admin=t, role admin), alice/bob (is_admin=f, role user) - app:sync-permissions : 4 permissions Core ajoutees, idempotent au 2e run - User::getRoles() : ['ROLE_USER', 'ROLE_ADMIN'] pour admin, ['ROLE_USER'] pour alice/bob - User::getEffectivePermissions() : union triee des permissions via roles Ticket #343 - 7/7 : smoke test end-to-end OK. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
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 |
make php-cs-fixer-allow-risky |
Fix code style PHP |
make logs-dev |
Tail 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.
config/modules.php— liste des modules actifsconfig/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→ bumpconfig/version.yaml→ tagvX.Y.Z - Build Docker : push tag
v*→ build image multi-stage → push Gitea Registry
Secrets requis dans Gitea :
RELEASE_TOKEN— PAT avec droitswrite:repositoryREGISTRY_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
Languages
PHP
69.7%
Vue
14.1%
TypeScript
12.4%
Makefile
1.8%
Dockerfile
0.8%
Other
1.2%