feat(catalog) : ERP-198 — migration schéma M6 (storage_type, product, jonctions, type PRODUIT) #149

Closed
matthieu wants to merge 1 commits from feat/erp-198-migration-schema-m6-produit into feat/erp-197-permissions-catalog-products
Owner

ERP-198 (1.2) — Migration schéma M6 produit

Crée le schéma BDD du module Catalogue produit (M6) en une migration au namespace racine DoctrineMigrations (FK cross-module user/site/category — cf. précédent M5).

Tables créées (Version20260625110000.php)

  • storage_type — référentiel provisoire des types de stockage (code VARCHAR(40) unique uq_storage_type_code, label).
  • storage_type_site — jonction M2M storage_type ↔ site (CASCADE/CASCADE).
  • product — table principale : code VARCHAR(50), name, states JSONB (≥1 via CHECK chk_product_states_not_empty), manufactured/contains_molasses BOOLEAN, category_id FK NOT NULL RESTRICT, deleted_at + 4 colonnes Timestampable/Blamable.
    • Index partiel uq_product_code_active (unicité globale parmi les actifs, RG-6.01).
    • Index category_id, deleted_at, created_by, updated_by.
  • product_site / product_storage_type — jonctions M2M (CASCADE côté product, RESTRICT côté référentiel).

Seed

  • category_type PRODUIT (ON CONFLICT DO NOTHING) — miroir CategoryTypeFixtures (l'ajout aux fixtures + catégories PRODUIT suit en ERP-201).

Garde-fous (règle ABSOLUE n°12)

  • COMMENT ON COLUMN sur chaque colonne (FR ≤ 200 car.) + COMMENT ON TABLE ; 4 colonnes standard via ColumnCommentsCatalog::timestampableBlamableComments().
  • Tables non encore mappées ORM (entités en ERP-199) → droppées par schema:update sur la BDD de test uniquement, sans impact (précédent M5 ERP-182). Mirror ColumnCommentsCatalog reporté à ERP-199.

Vérifications

  • make db-reset (tables + COMMENT + index partiel + CHECK + seed vérifiés)
  • make test (garde-fous ColumnsHaveSqlCommentTest, EntitiesAreTimestampableBlamableTest, CollectionsArePaginatedTest verts ; échec isolé UploadedDocumentApiTest = permission var/uploads, hors sujet)
  • make php-cs-fixer-allow-risky (0 fichier corrigé)

MR stackée sur feat/erp-197... (bas de stack → develop).

## ERP-198 (1.2) — Migration schéma M6 produit Crée le schéma BDD du module Catalogue produit (M6) en une migration au namespace racine `DoctrineMigrations` (FK cross-module user/site/category — cf. précédent M5). ### Tables créées (`Version20260625110000.php`) - **`storage_type`** — référentiel provisoire des types de stockage (`code` VARCHAR(40) unique `uq_storage_type_code`, `label`). - **`storage_type_site`** — jonction M2M storage_type ↔ site (CASCADE/CASCADE). - **`product`** — table principale : `code` VARCHAR(50), `name`, `states` JSONB (≥1 via CHECK `chk_product_states_not_empty`), `manufactured`/`contains_molasses` BOOLEAN, `category_id` FK NOT NULL RESTRICT, `deleted_at` + 4 colonnes Timestampable/Blamable. - Index partiel **`uq_product_code_active`** (unicité globale parmi les actifs, RG-6.01). - Index `category_id`, `deleted_at`, `created_by`, `updated_by`. - **`product_site`** / **`product_storage_type`** — jonctions M2M (CASCADE côté product, RESTRICT côté référentiel). ### Seed - `category_type` **PRODUIT** (`ON CONFLICT DO NOTHING`) — miroir CategoryTypeFixtures (l'ajout aux fixtures + catégories PRODUIT suit en ERP-201). ### Garde-fous (règle ABSOLUE n°12) - `COMMENT ON COLUMN` sur chaque colonne (FR ≤ 200 car.) + `COMMENT ON TABLE` ; 4 colonnes standard via `ColumnCommentsCatalog::timestampableBlamableComments()`. - Tables non encore mappées ORM (entités en ERP-199) → droppées par `schema:update` sur la BDD de **test** uniquement, sans impact (précédent M5 ERP-182). Mirror `ColumnCommentsCatalog` reporté à ERP-199. ### Vérifications - `make db-reset` ✅ (tables + COMMENT + index partiel + CHECK + seed vérifiés) - `make test` ✅ (garde-fous `ColumnsHaveSqlCommentTest`, `EntitiesAreTimestampableBlamableTest`, `CollectionsArePaginatedTest` verts ; échec isolé `UploadedDocumentApiTest` = permission `var/uploads`, hors sujet) - `make php-cs-fixer-allow-risky` ✅ (0 fichier corrigé) > MR stackée sur `feat/erp-197...` (bas de stack → develop).
matthieu added 1 commit 2026-06-25 08:21:22 +00:00
matthieu added the backdbM6-Produittype/feat labels 2026-06-25 08:21:54 +00:00
Author
Owner

Review back — ERP-198 (migration schéma M6), read-only.

Périmètre : storage_type (+ jonction site), product (+ jonctions), seed type PRODUIT.

Vérifié conforme :

  • COMMENT ON COLUMN sur chaque colonne créée + COMMENT ON TABLE (garde-fou ColumnsHaveSqlCommentTest vert).
  • Les 5 tables M6 mirorées dans ColumnCommentsCatalog (piège connu évité — sinon test-db-setup drope les COMMENT).
  • Index partiel uq_product_code_active créé ET ligne dbal:run-sql du makefile (test-db-setup) alignée (piège connu évité).
  • CHECK chk_product_states_not_empty (RG-6.02), 4 colonnes Timestampable/Blamable via le helper centralisé, namespace racine DoctrineMigrations, colonnes en minuscules.

Verdict : aucun retour obligatoire.

**Review back — ERP-198 (migration schéma M6), read-only.** Périmètre : `storage_type` (+ jonction site), `product` (+ jonctions), seed type PRODUIT. Vérifié conforme : - `COMMENT ON COLUMN` sur chaque colonne créée + `COMMENT ON TABLE` (garde-fou `ColumnsHaveSqlCommentTest` vert). - Les 5 tables M6 mirorées dans `ColumnCommentsCatalog` (piège connu évité — sinon `test-db-setup` drope les COMMENT). - Index partiel `uq_product_code_active` créé ET ligne `dbal:run-sql` du `makefile` (`test-db-setup`) alignée (piège connu évité). - CHECK `chk_product_states_not_empty` (RG-6.02), 4 colonnes Timestampable/Blamable via le helper centralisé, namespace racine `DoctrineMigrations`, colonnes en minuscules. 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

Pull request closed

Sign in to join this conversation.