fix(review) : resout findings 3e passe review (HIGH frontend + MEDIUMs backend/frontend/E2E)

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>
This commit is contained in:
Matthieu
2026-04-23 10:31:03 +02:00
parent 25cd6a1ecc
commit b1255bb57a
12 changed files with 271 additions and 48 deletions

View File

@@ -153,7 +153,7 @@ import type { AuditLogEntry, AuditLogFilters } from '~/shared/types'
const { t } = useI18n()
const { can } = usePermissions()
const { fetchLogs, fetchEntityTypes } = useAuditLog()
const { fetchLogsCached, fetchEntityTypes } = useAuditLog()
// Protection cote UI : le middleware `modules.global.ts` filtre deja les
// routes desactivees, mais si quelqu'un atterit ici sans la permission on
@@ -275,7 +275,7 @@ async function loadEntries(): Promise<void> {
const token = ++requestToken
loading.value = true
try {
const data = await fetchLogs({
const data = await fetchLogsCached({
...filters,
// Convertit datetime-local (YYYY-MM-DDTHH:MM) en ISO pour l'API.
performedAtAfter: filters.performedAtAfter ? toIso(filters.performedAtAfter) : undefined,