Compare commits

...

2 Commits

Author SHA1 Message Date
68f072ef46 fix(audit-log) : exclut audit_log du schema_filter Doctrine
La table audit_log n'a pas d'entite ORM (ecriture DBAL brut via
AuditLogWriter pour eviter la recursion du listener). doctrine:schema:update
la considerait donc comme orpheline et la droppait systematiquement, ce qui
cassait la base de test apres chaque make test-db-setup (DROP TABLE audit_log
genere par schema:update --force, apres les migrations qui l'avaient creee).

Un schema_filter en negative lookahead sur la connexion default exclut la
table de toute comparaison de schema (schema:update, schema:validate, diff
de migrations). La creation / suppression reste pilotee exclusivement par
la migration Version20260420202749.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-22 15:51:32 +02:00
e2fbf51e19 refactor(sidebar) : deplace Tableau de bord dans Mon compte + documente la convention admin
- Dashboard ("/") sort de la section Administration et rejoint "Mon compte" (accessible a tout user authentifie, comme Deconnexion).
- Cle i18n migree : sidebar.general.dashboard -> sidebar.account.dashboard. Le namespace "general" devenu vide est supprime.
- Documentation inline dans config/sidebar.php : formalise la convention "etre admin = detenir au moins une permission admin-scoped (core.* ou equivalent sites.view)". Le gate implicite via filtrage d'items rend inutile un gate section-level tant que chaque item porte sa permission.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-22 15:40:53 +02:00
3 changed files with 36 additions and 13 deletions

View File

@@ -8,6 +8,16 @@ doctrine:
default:
url: '%env(resolve:DATABASE_URL)%'
profiling_collect_backtrace: '%kernel.debug%'
# Exclut `audit_log` de toute operation de comparaison de schema
# (doctrine:schema:update, schema:validate, diff de migrations...).
# Cette table n'a volontairement aucune entite mappee : elle est
# append-only via DBAL brut (AuditLogWriter) pour eviter la
# recursion du listener Doctrine. Sans ce filtre, schema:update
# la considere comme "orpheline" et genere un `DROP TABLE
# audit_log` qui casse la base de test apres chaque
# `make test-db-setup`. La creation / suppression de la table
# reste pilotee par les migrations (cf. Version20260420202749).
schema_filter: '~^(?!audit_log$).+~'
audit:
url: '%env(resolve:DATABASE_URL)%'
orm:

View File

@@ -39,20 +39,29 @@ declare(strict_types=1);
return [
// Section "Administration" : regroupe toutes les pages de configuration
// applicative (RBAC, users, sites, audit log). Gate implicite : si l'user
// n'a aucune des permissions item, la section se vide et disparait.
// Pour imposer un gate explicite (ex: "seuls les membres du groupe support
// voient l'administration"), ajouter ici : 'permission' => 'core.admin.access'.
// applicative (RBAC, users, sites, audit log).
//
// CONVENTION : "etre admin" = detenir au moins une permission admin-scoped.
// En pratique, le groupe `core.*` represente l'administration applicative
// (users, roles, audit_log) ; les autres permissions admin-scoped proviennent
// des modules qui exposent leur propre page d'admin dans cette section
// (ex: `sites.view`). Un user qui n'a AUCUNE de ces permissions n'a pas
// acces a l'administration.
//
// Gate implicite : tous les items de cette section declarent une `permission`.
// Sans aucune permission correspondante, tous les items sont filtres, la
// section devient vide et est automatiquement masquee par SidebarProvider
// (cf. la boucle de filtrage : section vide => `continue`). Inutile donc
// d'ajouter un gate explicite au niveau section tant que chaque item porte
// sa propre permission.
//
// Pour imposer un gate explicite supplementaire (ex: "seuls les membres du
// groupe support voient l'administration, meme s'ils ont des permissions
// individuelles"), ajouter : 'permission' => 'core.admin.access'.
[
'label' => 'sidebar.administration.section',
'icon' => 'mdi:cog-outline',
'items' => [
[
'label' => 'sidebar.general.dashboard',
'to' => '/',
'icon' => 'mdi:view-dashboard-outline',
'module' => 'core',
],
[
'label' => 'sidebar.core.roles',
'to' => '/admin/roles',
@@ -102,6 +111,12 @@ return [
'label' => 'sidebar.account.section',
'icon' => 'mdi:account-circle-outline',
'items' => [
[
'label' => 'sidebar.account.dashboard',
'to' => '/',
'icon' => 'mdi:view-dashboard-outline',
'module' => 'core',
],
[
'label' => 'sidebar.account.logout',
'to' => '/logout',

View File

@@ -18,11 +18,9 @@
},
"account": {
"section": "Mon compte",
"dashboard": "Tableau de bord",
"logout": "Déconnexion"
},
"general": {
"dashboard": "Tableau de bord"
},
"commercial": {
"section": "Commercial",
"suppliers": "Répertoire fournisseurs"