Matthieu 617ee314b3 fix(users) : corrige l'affichage et l'ecrasement des sites sur le drawer RBAC
Le drawer RBAC de /admin/users initialisait l'etat des sites a partir du payload
/api/users (groupe user:list) qui n'expose pas la collection sites. Consequence :
la section "Sites autorises" affichait toujours 0 case cochee, et la sauvegarde
ecrasait silencieusement les sites existants en BDD.

- Ajout d'une operation GET /users/{id}/rbac (groupe user:rbac:read) dediee au
  chargement du detail pour l'edition : payload list reste leger, detail riche
  sur une URI symetrique au PATCH existant.
- Drawer charge desormais GET /users/{id}/rbac pour initialiser sites, roles
  et directPermissions ; UserListItem ne contient plus sites (inutilise).
- Colonne "Sites" retiree de la table /admin/users : l'info est consultee via
  le drawer, pas la liste (evite aussi la fuite cross-site pour les users avec
  core.users.view mais sans sites.bypass_scope).
- Garde anti-ecrasement dans UserRbacProcessor : respect de la semantique
  merge-patch+json (cle absente = preservee, cle = [] = vidage explicite).
  Restaure les collections ManyToMany absentes du payload a partir du snapshot
  Doctrine. Couvre roles, directPermissions et sites.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-22 11:17:40 +02:00
2026-04-07 10:56:57 +02:00
2026-04-20 15:31:58 +00: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
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 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%