From c3621071f0dedc77441ebc724a57a511f32ffc13 Mon Sep 17 00:00:00 2001 From: Matthieu Date: Wed, 27 May 2026 15:46:54 +0200 Subject: [PATCH 1/3] ci(frontend) : accelere le job PR (nuxt build + cache node_modules & build Nuxt/Vite) - remplace build:dist (nuxt generate + prerender inutile en SPA) par nuxt build - cache node_modules sur hash du lockfile, npm ci uniquement en cache miss - regenere les types Nuxt (postinstall) en cache hit - cache des artefacts .nuxt / Vite avec restore-keys pour eviter le build a froid --- .gitea/workflows/pull-request.yml | 32 +++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/.gitea/workflows/pull-request.yml b/.gitea/workflows/pull-request.yml index c161627..681f0a5 100644 --- a/.gitea/workflows/pull-request.yml +++ b/.gitea/workflows/pull-request.yml @@ -104,9 +104,41 @@ jobs: with: node-version: '22' + # Cache de node_modules entier (pas seulement le cache de download npm). + # Cle = hash du lockfile : tant qu'il ne bouge pas, on saute l'extraction + # des ~1300 paquets (369 Mo) et le postinstall. + - name: Cache node_modules + id: node-modules-cache + uses: actions/cache@v4 + with: + path: frontend/node_modules + key: node-modules-${{ hashFiles('frontend/package-lock.json') }} + + # npm ci uniquement en cache miss (il efface node_modules de toute facon). - name: Install Node dependencies + if: steps.node-modules-cache.outputs.cache-hit != 'true' run: npm ci + # En cache hit, node_modules est restaure tel quel : le postinstall + # (nuxt prepare) n'a pas tourne. On regenere les types .nuxt a la main + # pour que lint/vitest/build disposent du contexte Nuxt. + - name: Prepare Nuxt (cache hit) + if: steps.node-modules-cache.outputs.cache-hit == 'true' + run: npm run postinstall + + # Cache des artefacts de build Nuxt/Vite pour eviter un build a froid a + # chaque PR. Cle par commit + restore-keys pour repartir du build le plus + # recent ; Vite invalide ses entrees obsoletes par hash de contenu. + - name: Cache Nuxt/Vite build + uses: actions/cache@v4 + with: + path: | + frontend/.nuxt + frontend/node_modules/.cache + key: nuxt-build-${{ github.sha }} + restore-keys: | + nuxt-build- + - name: ESLint run: npm run lint -- 2.39.5 From 8c64414568a7e9f84da46ad7e9933e2a31872a73 Mon Sep 17 00:00:00 2001 From: Matthieu Date: Wed, 27 May 2026 16:21:27 +0200 Subject: [PATCH 2/3] ci : retire tout le caching (backend de cache runner injoignable, timeout 4m30) Les logs montrent que chaque operation actions/cache attend ~4m30 avant ETIMEDOUT sur le serveur de cache du runner Gitea (51.91.78.99:39531) : - cache: npm de setup-node = tout le 'Setup Node 22' (271s) - cache node_modules et cache .nuxt : timeouts additionnels - cache Composer cote backend : meme risque Node 22 est deja dans le tool-cache (install instantane), npm ci a froid ~30s, build ~20s : le caching n'apportait rien ici. A re-activer si le serveur de cache du runner est repare. --- .gitea/workflows/pull-request.yml | 32 ------------------------------- 1 file changed, 32 deletions(-) diff --git a/.gitea/workflows/pull-request.yml b/.gitea/workflows/pull-request.yml index 681f0a5..c161627 100644 --- a/.gitea/workflows/pull-request.yml +++ b/.gitea/workflows/pull-request.yml @@ -104,41 +104,9 @@ jobs: with: node-version: '22' - # Cache de node_modules entier (pas seulement le cache de download npm). - # Cle = hash du lockfile : tant qu'il ne bouge pas, on saute l'extraction - # des ~1300 paquets (369 Mo) et le postinstall. - - name: Cache node_modules - id: node-modules-cache - uses: actions/cache@v4 - with: - path: frontend/node_modules - key: node-modules-${{ hashFiles('frontend/package-lock.json') }} - - # npm ci uniquement en cache miss (il efface node_modules de toute facon). - name: Install Node dependencies - if: steps.node-modules-cache.outputs.cache-hit != 'true' run: npm ci - # En cache hit, node_modules est restaure tel quel : le postinstall - # (nuxt prepare) n'a pas tourne. On regenere les types .nuxt a la main - # pour que lint/vitest/build disposent du contexte Nuxt. - - name: Prepare Nuxt (cache hit) - if: steps.node-modules-cache.outputs.cache-hit == 'true' - run: npm run postinstall - - # Cache des artefacts de build Nuxt/Vite pour eviter un build a froid a - # chaque PR. Cle par commit + restore-keys pour repartir du build le plus - # recent ; Vite invalide ses entrees obsoletes par hash de contenu. - - name: Cache Nuxt/Vite build - uses: actions/cache@v4 - with: - path: | - frontend/.nuxt - frontend/node_modules/.cache - key: nuxt-build-${{ github.sha }} - restore-keys: | - nuxt-build- - - name: ESLint run: npm run lint -- 2.39.5 From 1d3b1c2881154035f9288e0838dab6a9d8ad5dcb Mon Sep 17 00:00:00 2001 From: Matthieu Date: Thu, 28 May 2026 09:48:58 +0200 Subject: [PATCH 3/3] feat(catalog) : declare CatalogModule with RBAC permissions and sync 3 RBAC sources - CatalogModule.php (REQUIRED=true) expose 2 permissions : catalog.categories.view + catalog.categories.manage - modules.php : wire CatalogModule - sidebar.php : item "Gestion des categories" dans la section Administration (gate sur catalog.categories.view) - fr.json : cle sidebar.catalog.categories - personas.ts : user-full recoit les 2 permissions, super-admin + ALL_ADMIN_LINKS etendus avec 'categories' - SeedE2ECommand.php : miroir back, user-full recoit les 2 permissions RG-1.01 verifiee manuellement (admin 200, bob 403, anonyme 401) sur /api/categories et /api/category_types. --- config/modules.php | 2 + config/sidebar.php | 7 +++ frontend/i18n/locales/fr.json | 3 ++ frontend/tests/e2e/_fixtures/personas.ts | 10 +++-- src/Module/Catalog/CatalogModule.php | 43 +++++++++++++++++++ .../Infrastructure/Console/SeedE2ECommand.php | 2 + 6 files changed, 63 insertions(+), 4 deletions(-) create mode 100644 src/Module/Catalog/CatalogModule.php diff --git a/config/modules.php b/config/modules.php index 449543e..c4f8f54 100644 --- a/config/modules.php +++ b/config/modules.php @@ -1,6 +1,7 @@ 'sites', 'permission' => 'sites.view', ], + [ + 'label' => 'sidebar.catalog.categories', + 'to' => '/admin/categories', + 'icon' => 'mdi:tag-multiple-outline', + 'module' => 'catalog', + 'permission' => 'catalog.categories.view', + ], [ 'label' => 'sidebar.core.audit_log', 'to' => '/admin/audit-log', diff --git a/frontend/i18n/locales/fr.json b/frontend/i18n/locales/fr.json index 4d08443..1c9e5cd 100644 --- a/frontend/i18n/locales/fr.json +++ b/frontend/i18n/locales/fr.json @@ -32,6 +32,9 @@ }, "sites": { "admin": "Sites" + }, + "catalog": { + "categories": "Gestion des catégories" } }, "dashboard": { diff --git a/frontend/tests/e2e/_fixtures/personas.ts b/frontend/tests/e2e/_fixtures/personas.ts index 22cd8a4..43d4bba 100644 --- a/frontend/tests/e2e/_fixtures/personas.ts +++ b/frontend/tests/e2e/_fixtures/personas.ts @@ -35,7 +35,7 @@ export interface Persona { // sidebar-visibility pour driver la matrice. Les valeurs correspondent // aux slugs de route (`/admin/`), volontairement stables quand // la copie/i18n change. - expectedAdminLinks: Array<'users' | 'roles' | 'sites' | 'audit-log'> + expectedAdminLinks: Array<'users' | 'roles' | 'sites' | 'audit-log' | 'categories'> } const SHARED_PASSWORD = 'e2e-secret' @@ -47,7 +47,7 @@ export const personas: Record = { password: SHARED_PASSWORD, isAdmin: true, permissions: [], - expectedAdminLinks: ['users', 'roles', 'sites', 'audit-log'], + expectedAdminLinks: ['users', 'roles', 'sites', 'categories', 'audit-log'], }, 'user-full': { key: 'user-full', @@ -63,8 +63,10 @@ export const personas: Record = { 'sites.view', 'sites.manage', 'sites.bypass_scope', + 'catalog.categories.view', + 'catalog.categories.manage', ], - expectedAdminLinks: ['users', 'roles', 'sites', 'audit-log'], + expectedAdminLinks: ['users', 'roles', 'sites', 'categories', 'audit-log'], }, 'user-readonly': { key: 'user-readonly', @@ -109,4 +111,4 @@ export function getPersona(key: PersonaKey): Persona { return personas[key] } -export const ALL_ADMIN_LINKS = ['users', 'roles', 'sites', 'audit-log'] as const +export const ALL_ADMIN_LINKS = ['users', 'roles', 'sites', 'categories', 'audit-log'] as const diff --git a/src/Module/Catalog/CatalogModule.php b/src/Module/Catalog/CatalogModule.php new file mode 100644 index 0000000..1bae95f --- /dev/null +++ b/src/Module/Catalog/CatalogModule.php @@ -0,0 +1,43 @@ + + */ + public static function permissions(): array + { + return [ + ['code' => 'catalog.categories.view', 'label' => 'Voir les categories'], + ['code' => 'catalog.categories.manage', 'label' => 'Gerer les categories (creer, editer, supprimer)'], + ]; + } +} diff --git a/src/Module/Core/Infrastructure/Console/SeedE2ECommand.php b/src/Module/Core/Infrastructure/Console/SeedE2ECommand.php index c9bcbb9..115f5d6 100644 --- a/src/Module/Core/Infrastructure/Console/SeedE2ECommand.php +++ b/src/Module/Core/Infrastructure/Console/SeedE2ECommand.php @@ -184,6 +184,8 @@ final class SeedE2ECommand extends Command 'sites.view', 'sites.manage', 'sites.bypass_scope', + 'catalog.categories.view', + 'catalog.categories.manage', ], ], [ -- 2.39.5