4ae8e34bc70d85455945a2e0ba43257d43d6b6cc
Expose les sous-ressources Contacts / Adresses / RIB du repertoire clients
(M1, spec § 4.5) :
- 3 Processors dedies (ClientContactProcessor, ClientAddressProcessor,
ClientRibProcessor) : normalisation serveur reutilisant ClientFieldNormalizer
(RG-1.19 capitalize, RG-1.20 telephones chiffres, RG-1.21 emails/billingEmail
lowercase) + regles metier.
- Operations API Platform :
- POST /api/clients/{id}/contacts|addresses, PATCH/DELETE /api/client_contacts|addresses/{id}
(security commercial.clients.manage)
- POST /api/clients/{id}/ribs, PATCH/DELETE /api/client_ribs/{id}
(security commercial.clients.accounting.manage)
- GET item par sous-ressource (lecture unitaire) ; pas de GET collection
autonome (lecture via le parent, non concernee par la pagination ERP-72).
- Regles de gestion :
- RG-1.13 : DELETE du dernier RIB d'un client en reglement LCR -> 409.
- RG-1.14 : DELETE du dernier contact d'un client -> 409 (completude front au M1).
- RG-1.05 : prenom OU nom du contact obligatoire -> 422.
- Validations deja portees par l'entite et desormais exercees : Assert\Count(min:1)
sur ClientAddress.sites (RG-1.10), Assert\Regex code postal (RG-1.09),
Assert\Iban / Assert\Bic sur ClientRib.
- SiteReferenceDenormalizer : resout les IRIs /api/sites vers SiteInterface
(meme pattern que CategoryReferenceDenormalizer, sans import cross-module).
- Ajout de symfony/intl, requis par Assert\Bic.
Tests : ClientSubResourceApiTest (13 cas) couvrant CRUD, normalisation,
RG-1.13/1.14, gating 403 sur client_ribs sans accounting.manage. Suite back
complete au vert (383 tests).
Starseed
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 soustests/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 dansCLAUDE.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 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
67.2%
TypeScript
17.5%
Vue
12.3%
Makefile
1.5%
Dockerfile
0.6%
Other
0.9%