ensureSystemRole() recopie desormais la description depuis la migration
RBAC pour que les chemins prod (migration) et dev (fixtures) produisent
un etat identique.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- AppFixtures : rattachement des users aux entites Role via
RoleRepositoryInterface. Re-seed idempotent des roles systeme dans
ensureSystemRole() pour compenser le purger Doctrine qui vide la table
role avant load(), afin que "make db-reset && make fixtures" reste un
workflow one-shot.
- CreateUserCommand : flag --admin attache au role systeme admin + is_admin,
sinon au role user. Gestion d'erreur explicite si les roles systeme sont
absents (FAILURE + message pointant vers la migration).
- CreateUserCommand devient final, descriptions traduites en francais.
Ticket #343 - 6/7 : fixtures et command alignes sur le RBAC relationnel.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Nouvelles tables permission, role, role_permission, user_role, user_permission
- Ajout user.is_admin (BOOLEAN, default false)
- Seed des roles systeme admin et user via SQL brut (autonome, pas besoin
de fixtures pour cette etape)
- Migration des donnees : is_admin reflete ROLE_ADMIN du JSON roles, puis
rattachement user_role selon admin/user
- Drop user.roles en dernier (apres la migration de donnees)
- down() recree la colonne roles et la rehydrate depuis is_admin
Ticket #343 - 5/7 : persistance + migration donnees safe.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- CoreModule declare 4 permissions initiales (users.view/manage, roles.manage,
permissions.view)
- Nouvelle commande app:sync-permissions :
* scan des *Module::permissions() via config/modules.php
* validation stricte : cles [code, label], prefixe module, non-vides
* upsert transactionnel non-destructif
* revival des permissions orphelines qui reapparaissent
* marquage orphan pour les permissions disparues du code
* un seul flush() final (evite le flush-par-save de la repo save())
Ticket #343 - 4/7 : scanner et synchroniseur de permissions RBAC.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Suppression de la colonne JSON roles (persiste jusqu'a la migration Task 5)
- Ajout is_admin bool (seul levier de bypass RBAC via getRoles())
- Ajout ManyToMany User-Role (EAGER, table user_role)
- Ajout ManyToMany User-Permission directes (EAGER, table user_permission)
- getEffectivePermissions() : union dedupliquee triee, utilisee par le
futur PermissionVoter (#345)
- getRbacRoles() pour ne pas shadow getRoles() de UserInterface Symfony
- Tests unitaires couvrant derivation getRoles, union, deduplication, tri
Ticket #343 - 3/7 : migration du User vers le modele RBAC relationnel.
Fetch EAGER documente : evite le lazy-load au refresh JWT.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- PermissionRepositoryInterface avec findByCode et findAllCodes (pour le sync
command et le futur PermissionVoter)
- RoleRepositoryInterface avec findByCode
- Implementations Doctrine alignees sur DoctrineUserRepository
- Alias DI dans config/services.yaml
- Rebranchement de repositoryClass sur les entites Permission et Role
Ticket #343 - 2/7 : couche persistence RBAC.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Permission : guards constructeur (code/label/module non vides, code avec point)
- Permission::revive() reutilise updateMetadata() pour eviter la duplication
- Suppression de SystemRolesTest (tautologique, ne capture aucun comportement)
- Role::permissions : commentaire explicite sur la raison du fetch EAGER
- Alignement des types de retour sur static (style User.php)
- Nouveau test Role::addPermission avec permissions distinctes
Ticket #343 - Task 1 polish (revue qualite).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Entite Permission avec methodes markOrphan/revive/updateMetadata
- Entite Role avec addPermission/removePermission/ensureDeletable
- Constantes SystemRoles (codes admin/user partages)
- Exception SystemRoleDeletionException pour la garde de suppression
- Tests unitaires couvrant le comportement domaine (pas de BDD)
Ticket #343 - 1/7 : fondations RBAC (domaine pur, sans persistence).
Les entites ne portent pas encore repositoryClass (ajoute en Task 2).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Spec detaillee des fondations RBAC backend (entites Role/Permission, sync
command, migration, fixtures, tests) dans docs/rbac/ticket-343-spec.md
- Ajout CLAUDE.md des regles projet : commentaires francais (PHP + TS/Vue)
et convention de nommage des permissions module.resource[.sub].action
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Persist var/log/ via named volume coltura_logs so logs survive
container restarts.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add ESLint with @nuxt/eslint-config enforcing 4-space indentation.
Add make nuxt-lint and nuxt-lint-fix targets.
Add ESLint check to pre-commit hook (lint only, no auto-fix).
Fix auth.vue indentation from 2 to 4 spaces.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Change UserOutput.id from int to ?int to match User::getId() return type.
Replace EntityManagerInterface with UserRepositoryInterface in CreateUserCommand.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add resetSidebar() to useSidebar composable and call it on logout
to prevent stale sidebar data after re-login.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Update CLAUDE.md to reflect actual ports (PG 5437, frontend 3004).
Fix CHANGELOG.md header from "Ferme" to "Coltura".
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Maintenance is handled by nginx-proxy on the host, not inside the
container. deploy.sh extracts maintenance.html from the container.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Single container with supervisord (Nginx + PHP-FPM), 3-stage
Dockerfile build, pre-built image from registry, port 8086.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Without APP_ENV=prod, Symfony defaults to dev and tries to load
DoctrineFixturesBundle which is excluded by --no-dev.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- tailwind.config.ts: full theme with primary/secondary/tertiary + m-* CSS vars
- infra/prod/maintenance.html: maintenance page
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>