Backend :
- AuditLogWriter::stripSensitive rendu reellement recursif (matche doc).
- Tests GET /api/permissions/{id} non-admin pour chaque branche OR (gap Codex).
- Gardes non-regression UserRbacProcessor : PATCH /rbac sans clef sites ne
doit ni auto-selectionner currentSite ni exiger sites.manage.
Frontend :
- useAuditLog : renomme export trompeur fetchLogs -> fetchLogsCached, le
nom reflete desormais le comportement (cache pollue sinon).
- RoleDrawer / UserRbacDrawer : catch explicite + message d'erreur +
bouton save disabled si le chargement des referentiels a echoue (evite
un ecrasement silencieux des droits).
- AuditTimeline / AuditLogDetail : `oui`/`non` passent par common.yes/no.
- AuditTimeline : Intl.RelativeTimeFormat et toLocaleString suivent la
locale i18n courante (plus de hardcode 'fr').
E2E :
- sidebar-visibility.spec : remplace waitForLoadState('networkidle')
fragile par attente semantique sur accountDashboardLink (stable en CI).
Tests : 237/237 green, eslint clean, php-cs-fixer clean.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
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>