feat(technique) : migration schema repertoire prestataires (ERP-132) #90

Merged
matthieu merged 3 commits from feature/ERP-132-migrer-schema-bdd-m3 into develop 2026-06-12 14:19:48 +00:00
Owner

ERP-132 — Migrer le schéma BDD M3 (provider + sous-collections)

⚠️ MR stackée sur feat/erp-m3-technique-module-taxonomie (ERP-131, module Technique + type PRESTATAIRE). À merger après ERP-131. Base volontairement ≠ develop tant qu'ERP-131 n'est pas mergé.

Contenu

Crée tout le schéma Postgres du répertoire prestataires (1 migration, namespace racine DoctrineMigrations — FK cross-module user/category/site + référentiels comptables M1).

Tables (9) :

  • provider : company_name + bloc Comptabilité (siren/account_number/n_tva + FK tva_mode/payment_delay/payment_type/bank ON DELETE RESTRICT) + is_archived/archived_at/deleted_at + Timestampable/Blamable. Pas d'onglet Information (≠ supplier).
  • M2M formulaire principal : provider_category (RG-3.09), provider_site (sites du prestataire — RG-3.03, nouveau vs supplier + idx_provider_site_site pour le cloisonnement par site).
  • Sous-collections : provider_contact (CHECK chk_provider_contact_name : ≥1 champ parmi first_name/last_name/phone_primary/email), provider_address (sans address_type/bennes/triage), provider_rib.
  • Jointures adresse : provider_address_site (RG-3.05), provider_address_contact, provider_address_category.
  • Index partiel unique uq_provider_company_name_active (LOWER(company_name) WHERE non archivé/non supprimé — RG-3.10) + index FK.
  • COMMENT ON COLUMN/TABLE inline sur toutes les colonnes (règle ABSOLUE n°12).

Décisions

  • CategoryType PRESTATAIRE non re-seedé : déjà créé par ERP-131. Migration purement structurelle.
  • COMMENT inline (pas via ColumnCommentsCatalog) : tant que les entités Provider* n'existent pas (ERP-133), schema:update --force du setup test droppe les tables non mappées → les référencer dans le catalogue ferait planter app:apply-column-comments. Catalogue + ligne dbal:run-sql uq_provider différés à ERP-133, exactement comme supplier (ERP-86 après ERP-85).

Tests

  • make db-reset (dev + test-db-setup)
  • make test — 589 tests, ColumnsHaveSqlCommentTest vert
  • Index partiel vérifié partiel (clause WHERE), idx_provider_site_site présent, 0 colonne sans COMMENT
  • Cycle down()/up() OK
  • make php-cs-fixer-allow-risky (0 fichier)
## ERP-132 — Migrer le schéma BDD M3 (provider + sous-collections) > ⚠️ **MR stackée** sur `feat/erp-m3-technique-module-taxonomie` (ERP-131, module Technique + type PRESTATAIRE). À merger **après** ERP-131. Base volontairement ≠ develop tant qu'ERP-131 n'est pas mergé. ### Contenu Crée tout le schéma Postgres du répertoire prestataires (1 migration, namespace racine `DoctrineMigrations` — FK cross-module user/category/site + référentiels comptables M1). **Tables (9)** : - `provider` : company_name + bloc Comptabilité (siren/account_number/n_tva + FK tva_mode/payment_delay/payment_type/bank ON DELETE RESTRICT) + is_archived/archived_at/deleted_at + Timestampable/Blamable. **Pas d'onglet Information** (≠ supplier). - M2M formulaire principal : `provider_category` (RG-3.09), `provider_site` (sites du prestataire — RG-3.03, **nouveau vs supplier** + `idx_provider_site_site` pour le cloisonnement par site). - Sous-collections : `provider_contact` (CHECK `chk_provider_contact_name` : ≥1 champ parmi first_name/last_name/phone_primary/email), `provider_address` (**sans** address_type/bennes/triage), `provider_rib`. - Jointures adresse : `provider_address_site` (RG-3.05), `provider_address_contact`, `provider_address_category`. - Index partiel unique `uq_provider_company_name_active` (LOWER(company_name) WHERE non archivé/non supprimé — RG-3.10) + index FK. - `COMMENT ON COLUMN/TABLE` inline sur **toutes** les colonnes (règle ABSOLUE n°12). ### Décisions - **CategoryType PRESTATAIRE non re-seedé** : déjà créé par ERP-131. Migration purement structurelle. - **COMMENT inline (pas via ColumnCommentsCatalog)** : tant que les entités Provider* n'existent pas (ERP-133), `schema:update --force` du setup test droppe les tables non mappées → les référencer dans le catalogue ferait planter `app:apply-column-comments`. Catalogue + ligne `dbal:run-sql uq_provider` différés à ERP-133, exactement comme supplier (ERP-86 après ERP-85). ### Tests - ✅ `make db-reset` (dev + test-db-setup) - ✅ `make test` — 589 tests, `ColumnsHaveSqlCommentTest` vert - ✅ Index partiel vérifié partiel (clause WHERE), `idx_provider_site_site` présent, 0 colonne sans COMMENT - ✅ Cycle `down()`/`up()` OK - ✅ `make php-cs-fixer-allow-risky` (0 fichier)
matthieu added the backdbM3-Prestatairetype/feat labels 2026-06-12 07:49:15 +00:00
tristan reviewed 2026-06-12 08:00:59 +00:00
tristan left a comment
Owner

Revue de code ERP-132 (migration schéma prestataires). Migration DDL pure, très propre : miroir fidèle de supplier (M2) et alignée au spec § 3.1 ligne à ligne. Aucun bug de correctness trouvé (longueurs, FK ON DELETE, index partiel, CHECK contact, ordre down(), COMMENT exhaustifs — tout est conforme). 1 seul commentaire, non bloquant : un rappel forward-looking pour la stack (ERP-133).

Revue de code ERP-132 (migration schéma prestataires). Migration DDL pure, très propre : miroir fidèle de supplier (M2) et alignée au spec § 3.1 ligne à ligne. Aucun bug de correctness trouvé (longueurs, FK ON DELETE, index partiel, CHECK contact, ordre down(), COMMENT exhaustifs — tout est conforme). 1 seul commentaire, non bloquant : un rappel forward-looking pour la stack (ERP-133).
@@ -0,0 +158,4 @@
// les non-archives ET non soft-deletes uniquement (RG-3.10). Pas d index
// unique sur siren ni email.
$this->addSql(<<<'SQL'
CREATE UNIQUE INDEX uq_provider_company_name_active
Owner

Non bloquant — rappel pour ERP-133 (entités) : ne pas oublier de réappliquer cet index partiel dans le setup de la test-db, sinon les tests 409/RG-3.10 ne testeront rien.

Cet index unique partiel (WHERE is_archived = FALSE AND deleted_at IS NULL, expression LOWER(...)) est possédé par la seule migrationschema:update --force ne sait pas le régénérer depuis le mapping ORM (même situation que uq_category_name_active, doc de l'entité Category).

Conséquence à anticiper : dès qu'ERP-133 ajoutera les entités Provider*, le schema:update --force du test-db-setup recréera la table provider sans cet index. Si la ligne dbal:run-sql n'est pas ajoutée au makefile (comme tu l'annonces dans le docblock § COMMENT et dans ColumnCommentsCatalog), alors en base de test il n'y aura aucune contrainte d'unicité → le ProviderProcessor pourra détecter le doublon applicativement, mais tout test qui s'attend à un 409 garanti par la BDD (RG-3.10) passera au vert sans rien valider (faux positif silencieux).

Le précédent supplier (ERP-86 après ERP-85) a bien ajouté la ligne dbal:run-sql uq_supplier_company_name_active + l'entrée catalogue : à répliquer tel quel pour uq_provider_company_name_active au ticket entités. Rien à changer dans cette MR — c'est juste le maillon à ne pas perdre dans la stack.

Côté DDL pure : RAS. La migration colle au spec § 3.1 ligne à ligne (colonnes, longueurs, FK ON DELETE, prédicat de l'index partiel, CHECK chk_provider_contact_name) et reflète fidèlement supplier. Ordre des DROP dans down() correct, COMMENT ON COLUMN sur 100 % des colonnes.

**Non bloquant — rappel pour ERP-133 (entités) : ne pas oublier de réappliquer cet index partiel dans le setup de la test-db, sinon les tests 409/RG-3.10 ne testeront rien.** Cet index unique partiel (`WHERE is_archived = FALSE AND deleted_at IS NULL`, expression `LOWER(...)`) est **possédé par la seule migration** — `schema:update --force` ne sait pas le régénérer depuis le mapping ORM (même situation que `uq_category_name_active`, doc de l'entité `Category`). Conséquence à anticiper : dès qu'ERP-133 ajoutera les entités `Provider*`, le `schema:update --force` du `test-db-setup` recréera la table `provider` **sans** cet index. Si la ligne `dbal:run-sql` n'est pas ajoutée au makefile (comme tu l'annonces dans le docblock § COMMENT et dans `ColumnCommentsCatalog`), alors en base de test il n'y aura **aucune** contrainte d'unicité → le `ProviderProcessor` pourra détecter le doublon applicativement, mais tout test qui s'attend à un **409 garanti par la BDD** (RG-3.10) passera au vert sans rien valider (faux positif silencieux). Le précédent supplier (ERP-86 après ERP-85) a bien ajouté la ligne `dbal:run-sql uq_supplier_company_name_active` + l'entrée catalogue : à répliquer tel quel pour `uq_provider_company_name_active` au ticket entités. Rien à changer dans **cette** MR — c'est juste le maillon à ne pas perdre dans la stack. Côté DDL pure : RAS. La migration colle au spec § 3.1 ligne à ligne (colonnes, longueurs, FK ON DELETE, prédicat de l'index partiel, CHECK `chk_provider_contact_name`) et reflète fidèlement `supplier`. Ordre des `DROP` dans `down()` correct, `COMMENT ON COLUMN` sur 100 % des colonnes.
matthieu changed target branch from feat/erp-m3-technique-module-taxonomie to develop 2026-06-12 14:19:19 +00:00
matthieu added 2 commits 2026-06-12 14:19:19 +00:00
feat(technique) : module Technique + taxonomie categories prestataires
Pull Request — Quality gate / Backend (PHP CS + PHPUnit) (pull_request) Successful in 2m13s
Pull Request — Quality gate / Frontend (lint + Vitest + build) (pull_request) Successful in 1m27s
6ceef62056
Cree le nouveau module Technique (pole distinct du Commercial) prerequis du
M3 repertoire prestataires :
- TechniqueModule (ID=technique, REQUIRED=false) + 5 permissions RBAC
  technique.providers.* (view / manage / accounting.view / accounting.manage
  / archive), declarees pour app:sync-permissions.
- Activation dans config/modules.php + layer front frontend/modules/technique/.
- Seed taxonomie : nouveau CategoryType PRESTATAIRE + 3 categories
  (Maintenance industrielle, Nettoyage, Transport) via migration idempotente
  (ON CONFLICT / NOT EXISTS, jonction M2M category_category_type) ET fixtures
  CategoryType/Category (survivent au purger db-reset).
- Tests : structure du module (5 permissions figees) + filtre
  GET /api/categories?typeCode=PRESTATAIRE.

Inclut la spec back/front M3 et le RETEX M1.
Cree tout le schema BDD M3 du prestataire (jumeau du M2 fournisseur), sous
le namespace racine DoctrineMigrations (FK cross-module user/category/site +
referentiels comptables M1) :

- provider : company_name + bloc Comptabilite (siren/account_number/n_tva +
  FK tva_mode/payment_delay/payment_type/bank ON DELETE RESTRICT) +
  is_archived/archived_at/deleted_at + Timestampable/Blamable. Pas d onglet
  Information (contrairement a supplier).
- M2M formulaire principal : provider_category (RG-3.09), provider_site
  (sites du prestataire, RG-3.03 — nouveau vs supplier, + idx_provider_site_site).
- Sous-collections : provider_contact (CHECK chk_provider_contact_name :
  >=1 champ parmi first_name/last_name/phone_primary/email), provider_address
  (sans address_type/bennes/triage), provider_rib.
- Jointures adresse : provider_address_site (RG-3.05), provider_address_contact,
  provider_address_category.
- Index partiel unique uq_provider_company_name_active (LOWER(company_name)
  WHERE non archive/non supprime — RG-3.10) + index FK.
- COMMENT ON COLUMN/TABLE inline sur toutes les colonnes (regle n°12).

CategoryType PRESTATAIRE non re-seede (deja cree par ERP-131). Catalogue
ColumnCommentsCatalog et ligne dbal:run-sql differes au ticket entites (ERP-133),
comme supplier : tant que les entites Provider* n existent pas, schema:update du
setup test droppe ces tables non mappees et app:apply-column-comments planterait.
matthieu added 1 commit 2026-06-12 14:19:37 +00:00
Merge branch 'develop' into feature/ERP-132-migrer-schema-bdd-m3
Pull Request — Quality gate / Backend (PHP CS + PHPUnit) (pull_request) Successful in 2m29s
Pull Request — Quality gate / Frontend (lint + Vitest + build) (pull_request) Successful in 1m44s
59095a6441
matthieu merged commit 09a4b9d464 into develop 2026-06-12 14:19:48 +00:00
matthieu deleted branch feature/ERP-132-migrer-schema-bdd-m3 2026-06-12 14:19:49 +00:00
Sign in to join this conversation.