feat(catalog) : ERP-197 — permissions catalog.products.* + sidebar + 3 miroirs RBAC #148

Closed
matthieu wants to merge 1 commits from feat/erp-197-permissions-catalog-products into develop
Owner

ERP-197 (M6 · 1.1) — Permissions produit + sidebar + 3 miroirs RBAC

Premier ticket back du module M6 (Catalogue produit). Le produit vit dans le module Catalog existant — aucun nouveau module.

Changements

  • CatalogModule::permissions() : ajout de catalog.products.view et catalog.products.manage (admin-only, décision C7 de la spec).
  • config/sidebar.php : item « Catalogue produit » (/admin/products, icône mdi:package-variant-closed) placé sous « Répertoire transporteurs » dans la section Administration.
  • 3 miroirs RBAC (règle ABSOLUE n°8) alignés :
    • config/sidebar.php (item + permission)
    • frontend/tests/e2e/_fixtures/personas.ts (personas admin gagnent view/manage + lien products dans expectedAdminLinks / ALL_ADMIN_LINKS ; personas non-admin inchangés)
    • SeedE2ECommand.php (miroir back du persona user-full)
  • i18n : clé sidebar.catalog.products.

Vérifications

  • make test : 873/873
  • make nuxt-test : 667/667
  • make php-cs-fixer-allow-risky : 0 fix
  • app:sync-permissions : 2 permissions ajoutées

Branche rebasée sur develop à jour (#147).

## ERP-197 (M6 · 1.1) — Permissions produit + sidebar + 3 miroirs RBAC Premier ticket back du module M6 (Catalogue produit). Le produit vit dans le module **Catalog** existant — aucun nouveau module. ### Changements - **CatalogModule::permissions()** : ajout de `catalog.products.view` et `catalog.products.manage` (admin-only, décision C7 de la spec). - **config/sidebar.php** : item « Catalogue produit » (`/admin/products`, icône `mdi:package-variant-closed`) placé sous « Répertoire transporteurs » dans la section Administration. - **3 miroirs RBAC (règle ABSOLUE n°8)** alignés : - `config/sidebar.php` (item + permission) - `frontend/tests/e2e/_fixtures/personas.ts` (personas admin gagnent view/manage + lien `products` dans `expectedAdminLinks` / `ALL_ADMIN_LINKS` ; personas non-admin inchangés) - `SeedE2ECommand.php` (miroir back du persona user-full) - **i18n** : clé `sidebar.catalog.products`. ### Vérifications - `make test` : **873/873** ✅ - `make nuxt-test` : **667/667** ✅ - `make php-cs-fixer-allow-risky` : 0 fix - `app:sync-permissions` : 2 permissions ajoutées Branche rebasée sur `develop` à jour (#147).
matthieu added 1 commit 2026-06-25 07:57:17 +00:00
feat(catalog) : ERP-197 — permissions catalog.products.* + item sidebar + 3 miroirs RBAC
Pull Request — Quality gate / Frontend (lint + Vitest + build) (pull_request) Successful in 1m53s
Pull Request — Quality gate / Backend (PHP CS + PHPUnit) (pull_request) Successful in 3m31s
e9f8b0bc45
- CatalogModule::permissions() : ajout catalog.products.view / .manage (admin-only, C7)
- config/sidebar.php : item « Catalogue produit » (/admin/products) sous « Repertoire transporteurs » (section Administration)
- personas.ts + SeedE2ECommand.php : persona admin gagne view/manage + lien products (3 miroirs RBAC alignes)
- i18n : cle sidebar.catalog.products
matthieu added the backtype/feat labels 2026-06-25 07:57:40 +00:00
matthieu added the M6-Produit label 2026-06-25 08:03:20 +00:00
Author
Owner

Review back — ERP-197 (RBAC / sidebar), read-only.

Périmètre : permissions catalog.products.view / catalog.products.manage + item sidebar + 3 miroirs RBAC.

Vérifié conforme :

  • Format des permissions module.resource.action snake_case (CatalogModule::permissions()).
  • 3 miroirs RBAC alignés : config/sidebar.php, frontend/tests/e2e/_fixtures/personas.ts (Admin only + expectedAdminLinks), SeedE2ECommand.php. Aucun drift.
  • Catalogue admin-only (matrice § 5.2) : Bureau/Compta/Commerciale/Usine ne gagnent rien. Item placé sous « Répertoire transporteurs » (décision spec § 5.3).

Verdict : aucun retour obligatoire.

**Review back — ERP-197 (RBAC / sidebar), read-only.** Périmètre : permissions `catalog.products.view` / `catalog.products.manage` + item sidebar + 3 miroirs RBAC. Vérifié conforme : - Format des permissions `module.resource.action` snake_case (`CatalogModule::permissions()`). - 3 miroirs RBAC alignés : `config/sidebar.php`, `frontend/tests/e2e/_fixtures/personas.ts` (Admin only + `expectedAdminLinks`), `SeedE2ECommand.php`. Aucun drift. - Catalogue admin-only (matrice § 5.2) : Bureau/Compta/Commerciale/Usine ne gagnent rien. Item placé sous « Répertoire transporteurs » (décision spec § 5.3). Verdict : ✅ aucun retour obligatoire.
Author
Owner

Review M6 « Produit » — relecture croisée (couche données + couche application) sur le diff cumulé develop…HEAD.

Verdict : 0 bloquant, 0 important.

  • Garde-fous archi verts : COMMENT ON COLUMN, Timestampable/Blamable, Auditable + i18n, pagination (règle absolue n°13), contraintes Assert\* en FR.
  • RBAC 3 miroirs alignés (sidebar / personas / SeedE2ECommand).
  • Export : priority:1 + #[IsGranted('catalog.products.view')], mêmes filtres que la liste — conforme.
  • 119 tests Catalog + garde-fous archi verts en isolation (BDD fraîche).

Nits relevés (non bloquants) :

  • product.states : DEFAULT '[]'::jsonb contredisait le CHECK (jsonb_array_length(states) >= 1) (default mort, jamais atteignable) → corrigé (commit 30e7839).
  • ProductExportControllerTest : le tearDown réutilisait la constante des category-types (TEST_CATEGORY_TYPE_PREFIX) pour purger des storage-types → constante dédiée TEST_STORAGE_PREFIX (commit 30e7839).
  • Import Site (cross-module) du controller utilisé seulement dans un commentaire @var ; DQL p.id != :id au lieu de <> : cosmétiques, laissés tels quels.
  • Provider ?pagination=false renvoyant un array : conforme (pattern établi ClientProvider/SupplierProvider, échappatoire documentée pour alimenter les selects).
**Review M6 « Produit »** — relecture croisée (couche données + couche application) sur le diff cumulé `develop…HEAD`. **Verdict : 0 bloquant, 0 important.** - Garde-fous archi verts : COMMENT ON COLUMN, Timestampable/Blamable, Auditable + i18n, pagination (règle absolue n°13), contraintes `Assert\*` en FR. - RBAC 3 miroirs alignés (sidebar / personas / SeedE2ECommand). - Export : `priority:1` + `#[IsGranted('catalog.products.view')]`, mêmes filtres que la liste — conforme. - 119 tests Catalog + garde-fous archi verts en isolation (BDD fraîche). **Nits relevés (non bloquants) :** - `product.states` : `DEFAULT '[]'::jsonb` contredisait le `CHECK (jsonb_array_length(states) >= 1)` (default mort, jamais atteignable) → corrigé (commit `30e7839`). - `ProductExportControllerTest` : le `tearDown` réutilisait la constante des category-types (`TEST_CATEGORY_TYPE_PREFIX`) pour purger des storage-types → constante dédiée `TEST_STORAGE_PREFIX` (commit `30e7839`). - Import `Site` (cross-module) du controller utilisé seulement dans un commentaire `@var` ; DQL `p.id != :id` au lieu de `<>` : cosmétiques, laissés tels quels. - Provider `?pagination=false` renvoyant un `array` : conforme (pattern établi `ClientProvider`/`SupplierProvider`, échappatoire documentée pour alimenter les selects).
Author
Owner

Consolidée dans #154 : la pile M6 a été reciblée sur develop en une seule MR pour un CI unique. Commits intégralement inclus dans #154 — fermée sans merge individuel.

Consolidée dans #154 : la pile M6 a été reciblée sur `develop` en une seule MR pour un CI unique. Commits intégralement inclus dans #154 — fermée sans merge individuel.
matthieu closed this pull request 2026-06-25 12:36:06 +00:00
Some checks are pending
Pull Request — Quality gate / Frontend (lint + Vitest + build) (pull_request) Successful in 1m53s
Pull Request — Quality gate / Backend (PHP CS + PHPUnit) (pull_request) Successful in 3m31s

Pull request closed

Sign in to join this conversation.