diff --git a/migrations/Version20260612100000.php b/migrations/Version20260612100000.php new file mode 100644 index 0000000..9ee3aec --- /dev/null +++ b/migrations/Version20260612100000.php @@ -0,0 +1,451 @@ += 1). Sert aussi le cloisonnement + * par site (idx_provider_site_site, § 2.13). + * - provider_address SIMPLIFIEE : pas de address_type / bennes / + * triage_provider (specifiques fournisseur). Champs : country / postal_code + * / city / street / street_complement / position + M2M sites/contacts/categories. + * + * Referentiels comptables NON recrees : tva_mode / payment_delay / payment_type + * / bank sont ceux du M1 (FK partagees, zero duplication — spec § 2.3). + * + * CategoryType PRESTATAIRE NON re-seede : il est cree par ERP-131 + * (Version20260612080000) avec ses categories de demonstration. Le M2M + * provider_category / provider_address_category s appuie sur ce type existant. + * + * Namespace racine `DoctrineMigrations` (regle ABSOLUE Starseed n°11) et NON + * `App\Module\Technique\...` : la migration cree un schema avec FK cross-module + * (user, category, site, et les referentiels comptables M1). Avec plusieurs + * migrations_paths, Doctrine Migrations 3.x trie par FQCN alphabetique — un + * namespace modulaire s executerait avant la creation de user/category/site sur + * base vide -> echec des FK. Le namespace racine garantit l ordre par timestamp. + * + * Style DDL aligne sur le M1/M2 (Version20260605130000) : `INT GENERATED BY + * DEFAULT AS IDENTITY` (et non SERIAL), `TIMESTAMP(0) WITHOUT TIME ZONE` (et non + * TIMESTAMPTZ, car le TimestampableBlamableTrait mappe `datetime_immutable`). + * Garantit que `schema:update` restera un no-op quand les entites arriveront + * (ticket ERP-133). + * + * Decision unicite (alignee Q4 M1 / § 2.6 M2) : unicite metier sur le NOM DE + * SOCIETE uniquement (uq_provider_company_name_active, partiel). Pas d index + * unique sur siren ni email. + * + * COMMENT ON COLUMN inline (regle ABSOLUE n°12) : chaque colonne metier porte sa + * description ici-meme. Volontairement NON ajoutees a `ColumnCommentsCatalog` / + * `makefile test-db-setup` a ce stade : tant que les entites Provider* n existent + * pas (ERP-133), `schema:update --force` du setup de test droppe ces tables non + * mappees — les referencer dans le catalogue ferait planter + * `app:apply-column-comments`. Le catalogue + la ligne `dbal:run-sql` + * (uq_provider_company_name_active) seront ajoutes au ticket entites (ERP-133), + * exactement comme supplier (ERP-86) apres sa migration (ERP-85). Les 4 colonnes + * Timestampable/Blamable reutilisent les textes standardises du catalogue + * (`timestampableBlamableComments()`, simple tableau statique sans dependance DB). + */ +final class Version20260612100000 extends AbstractMigration +{ + public function getDescription(): string + { + return 'ERP-132 (M3) : tables provider + sous-collections + jointures M2M (referentiels comptables et CategoryType PRESTATAIRE reutilises).'; + } + + public function up(Schema $schema): void + { + $this->createProviderTable(); + $this->createProviderCategory(); + $this->createProviderSite(); + $this->createProviderContact(); + $this->createProviderAddress(); + $this->createProviderAddressJoinTables(); + $this->createProviderRib(); + } + + public function down(Schema $schema): void + { + // Ordre inverse des dependances FK : jointures et sous-collections + // d abord, puis provider. Les referentiels comptables et le + // CategoryType PRESTATAIRE ne sont pas touches (crees ailleurs). + $this->addSql('DROP TABLE IF EXISTS provider_address_category'); + $this->addSql('DROP TABLE IF EXISTS provider_address_contact'); + $this->addSql('DROP TABLE IF EXISTS provider_address_site'); + $this->addSql('DROP TABLE IF EXISTS provider_rib'); + $this->addSql('DROP TABLE IF EXISTS provider_address'); + $this->addSql('DROP TABLE IF EXISTS provider_contact'); + $this->addSql('DROP TABLE IF EXISTS provider_site'); + $this->addSql('DROP TABLE IF EXISTS provider_category'); + $this->addSql('DROP TABLE IF EXISTS provider'); + } + + // ================================================================= + // Table principale `provider` + // ================================================================= + + private function createProviderTable(): void + { + $this->addSql(<<<'SQL' + CREATE TABLE provider ( + id INT GENERATED BY DEFAULT AS IDENTITY NOT NULL, + company_name VARCHAR(180) NOT NULL, + siren VARCHAR(20) DEFAULT NULL, + account_number VARCHAR(40) DEFAULT NULL, + tva_mode_id INT DEFAULT NULL, + n_tva VARCHAR(40) DEFAULT NULL, + payment_delay_id INT DEFAULT NULL, + payment_type_id INT DEFAULT NULL, + bank_id INT DEFAULT NULL, + is_archived BOOLEAN DEFAULT FALSE NOT NULL, + archived_at TIMESTAMP(0) WITHOUT TIME ZONE DEFAULT NULL, + deleted_at TIMESTAMP(0) WITHOUT TIME ZONE DEFAULT NULL, + created_at TIMESTAMP(0) WITHOUT TIME ZONE NOT NULL, + updated_at TIMESTAMP(0) WITHOUT TIME ZONE NOT NULL, + created_by INT DEFAULT NULL, + updated_by INT DEFAULT NULL, + PRIMARY KEY (id), + CONSTRAINT fk_provider_tva_mode + FOREIGN KEY (tva_mode_id) REFERENCES tva_mode (id) ON DELETE RESTRICT, + CONSTRAINT fk_provider_payment_delay + FOREIGN KEY (payment_delay_id) REFERENCES payment_delay (id) ON DELETE RESTRICT, + CONSTRAINT fk_provider_payment_type + FOREIGN KEY (payment_type_id) REFERENCES payment_type (id) ON DELETE RESTRICT, + CONSTRAINT fk_provider_bank + FOREIGN KEY (bank_id) REFERENCES bank (id) ON DELETE RESTRICT, + CONSTRAINT fk_provider_created_by + FOREIGN KEY (created_by) REFERENCES "user" (id) ON DELETE SET NULL, + CONSTRAINT fk_provider_updated_by + FOREIGN KEY (updated_by) REFERENCES "user" (id) ON DELETE SET NULL + ) + SQL); + + $this->addSql('CREATE INDEX idx_provider_is_archived ON provider (is_archived)'); + $this->addSql('CREATE INDEX idx_provider_deleted_at ON provider (deleted_at)'); + $this->addSql('CREATE INDEX idx_provider_created_by ON provider (created_by)'); + $this->addSql('CREATE INDEX idx_provider_updated_by ON provider (updated_by)'); + + // Index sur les FK des referentiels comptables (Postgres n indexe pas + // automatiquement les colonnes portant une FOREIGN KEY). + $this->addSql('CREATE INDEX idx_provider_tva_mode_id ON provider (tva_mode_id)'); + $this->addSql('CREATE INDEX idx_provider_payment_delay_id ON provider (payment_delay_id)'); + $this->addSql('CREATE INDEX idx_provider_payment_type_id ON provider (payment_type_id)'); + $this->addSql('CREATE INDEX idx_provider_bank_id ON provider (bank_id)'); + + // Unicite metier partielle : nom de societe insensible a la casse, parmi + // 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 + ON provider (LOWER(company_name)) + WHERE is_archived = FALSE AND deleted_at IS NULL + SQL); + + $this->comment('provider', '_table', 'Repertoire prestataires (M3 Technique) — entites archivables (is_archived) et soft-deletables (deleted_at, HP M4). Pas d onglet Information (≠ supplier).'); + $this->comment('provider', 'id', 'Identifiant interne auto-incremente.'); + $this->comment('provider', 'company_name', 'Raison sociale du prestataire (stockee en MAJUSCULES). Unique case-insensitive parmi les actifs non archives/non supprimes (uq_provider_company_name_active, RG-3.10).'); + $this->comment('provider', 'siren', 'Onglet Comptabilite : SIREN (9 chiffres attendus). NON unique — peut etre partage entre etablissements (RG-3.10).'); + $this->comment('provider', 'account_number', 'Onglet Comptabilite : numero de compte comptable du prestataire.'); + $this->comment('provider', 'tva_mode_id', 'Onglet Comptabilite : mode de TVA applique — FK -> tva_mode.id (referentiel partage M1), ON DELETE RESTRICT.'); + $this->comment('provider', 'n_tva', 'Onglet Comptabilite : numero de TVA intracommunautaire.'); + $this->comment('provider', 'payment_delay_id', 'Onglet Comptabilite : delai de reglement — FK -> payment_delay.id (M1), ON DELETE RESTRICT.'); + $this->comment('provider', 'payment_type_id', 'Onglet Comptabilite : type de reglement — FK -> payment_type.id (M1), ON DELETE RESTRICT. Pilote RG-3.07 (Banque si VIREMENT) et RG-3.08 (RIB).'); + $this->comment('provider', 'bank_id', 'Onglet Comptabilite : banque — FK -> bank.id (M1), ON DELETE RESTRICT. Obligatoire ssi payment_type = VIREMENT (RG-3.07), null sinon.'); + $this->comment('provider', 'is_archived', 'Drapeau fonctionnel d archivage — masque par defaut dans la liste. Bascule via permission technique.providers.archive.'); + $this->comment('provider', 'archived_at', 'Horodatage de l archivage — pose quand is_archived passe a vrai, remis a null a la restauration.'); + $this->comment('provider', 'deleted_at', 'Horodatage du soft-delete technique (HP M4) — non expose par l API au M3. Null = ligne active.'); + $this->addTimestampableBlamableComments('provider'); + } + + // ================================================================= + // M2M provider <-> category (type PRESTATAIRE — RG-3.09) + // ================================================================= + + private function createProviderCategory(): void + { + $this->addSql(<<<'SQL' + CREATE TABLE provider_category ( + provider_id INT NOT NULL, + category_id INT NOT NULL, + PRIMARY KEY (provider_id, category_id), + CONSTRAINT fk_provider_category_provider + FOREIGN KEY (provider_id) REFERENCES provider (id) ON DELETE CASCADE, + CONSTRAINT fk_provider_category_category + FOREIGN KEY (category_id) REFERENCES category (id) ON DELETE RESTRICT + ) + SQL); + $this->addSql('CREATE INDEX idx_provider_category_category ON provider_category (category_id)'); + + $this->comment('provider_category', '_table', 'Jointure M2M provider <-> category (Catalog) — categories de type PRESTATAIRE du prestataire, au moins une obligatoire (RG-3.09).'); + $this->comment('provider_category', 'provider_id', 'FK -> provider.id, ON DELETE CASCADE — prestataire porteur de la categorie.'); + $this->comment('provider_category', 'category_id', 'FK -> category.id, ON DELETE RESTRICT — categorie de type PRESTATAIRE rattachee au prestataire (RG-3.09).'); + } + + // ================================================================= + // M2M provider <-> site (formulaire principal — RG-3.03) + // ================================================================= + + private function createProviderSite(): void + { + $this->addSql(<<<'SQL' + CREATE TABLE provider_site ( + provider_id INT NOT NULL, + site_id INT NOT NULL, + PRIMARY KEY (provider_id, site_id), + CONSTRAINT fk_provider_site_provider + FOREIGN KEY (provider_id) REFERENCES provider (id) ON DELETE CASCADE, + CONSTRAINT fk_provider_site_site + FOREIGN KEY (site_id) REFERENCES site (id) ON DELETE RESTRICT + ) + SQL); + // Index sur site_id : sert le filtre de cloisonnement par site + // (WHERE site = :currentSite, § 2.13). + $this->addSql('CREATE INDEX idx_provider_site_site ON provider_site (site_id)'); + + $this->comment('provider_site', '_table', 'Jointure M2M provider <-> site (Sites) — sites du prestataire, selecteur du formulaire principal, au moins un obligatoire (RG-3.03). Sert le cloisonnement par site (§ 2.13).'); + $this->comment('provider_site', 'provider_id', 'FK -> provider.id, ON DELETE CASCADE — prestataire porteur du site.'); + $this->comment('provider_site', 'site_id', 'FK -> site.id, ON DELETE RESTRICT — site rattache au prestataire (RG-3.03, idx_provider_site_site).'); + } + + // ================================================================= + // Sous-collection : contacts (1:n) + // ================================================================= + + private function createProviderContact(): void + { + $this->addSql(<<<'SQL' + CREATE TABLE provider_contact ( + id INT GENERATED BY DEFAULT AS IDENTITY NOT NULL, + provider_id INT NOT NULL, + first_name VARCHAR(120) DEFAULT NULL, + last_name VARCHAR(120) DEFAULT NULL, + job_title VARCHAR(120) DEFAULT NULL, + phone_primary VARCHAR(20) DEFAULT NULL, + phone_secondary VARCHAR(20) DEFAULT NULL, + email VARCHAR(180) DEFAULT NULL, + position INT DEFAULT 0 NOT NULL, + created_at TIMESTAMP(0) WITHOUT TIME ZONE NOT NULL, + updated_at TIMESTAMP(0) WITHOUT TIME ZONE NOT NULL, + created_by INT DEFAULT NULL, + updated_by INT DEFAULT NULL, + PRIMARY KEY (id), + CONSTRAINT chk_provider_contact_name + CHECK (first_name IS NOT NULL OR last_name IS NOT NULL OR phone_primary IS NOT NULL OR email IS NOT NULL), + CONSTRAINT fk_provider_contact_provider + FOREIGN KEY (provider_id) REFERENCES provider (id) ON DELETE CASCADE, + CONSTRAINT fk_provider_contact_created_by + FOREIGN KEY (created_by) REFERENCES "user" (id) ON DELETE SET NULL, + CONSTRAINT fk_provider_contact_updated_by + FOREIGN KEY (updated_by) REFERENCES "user" (id) ON DELETE SET NULL + ) + SQL); + $this->addSql('CREATE INDEX idx_provider_contact_provider ON provider_contact (provider_id)'); + + $this->comment('provider_contact', '_table', 'Contacts d un prestataire (1:n) — au moins un champ rempli parmi prenom/nom/telephone/email (RG-3.04, chk_provider_contact_name).'); + $this->comment('provider_contact', 'id', 'Identifiant interne auto-incremente.'); + $this->comment('provider_contact', 'provider_id', 'FK -> provider.id, ON DELETE CASCADE — prestataire proprietaire du contact.'); + $this->comment('provider_contact', 'first_name', 'Prenom du contact (capitalise serveur). Au moins un champ du contact requis (RG-3.04, chk_provider_contact_name).'); + $this->comment('provider_contact', 'last_name', 'Nom du contact (capitalise serveur). Au moins un champ du contact requis (RG-3.04, chk_provider_contact_name).'); + $this->comment('provider_contact', 'job_title', 'Fonction / intitule de poste du contact (≤ 120 caracteres).'); + $this->comment('provider_contact', 'phone_primary', 'Telephone principal du contact — chiffres uniquement (normalisation serveur).'); + $this->comment('provider_contact', 'phone_secondary', 'Telephone secondaire du contact — chiffres uniquement (normalisation serveur).'); + $this->comment('provider_contact', 'email', 'Email du contact (lowercase serveur).'); + $this->comment('provider_contact', 'position', 'Ordre d affichage du contact dans la liste du prestataire (croissant).'); + $this->addTimestampableBlamableComments('provider_contact'); + } + + // ================================================================= + // Sous-collection : adresses (1:n) — SANS address_type / bennes / triage + // ================================================================= + + private function createProviderAddress(): void + { + $this->addSql(<<<'SQL' + CREATE TABLE provider_address ( + id INT GENERATED BY DEFAULT AS IDENTITY NOT NULL, + provider_id INT NOT NULL, + country VARCHAR(80) DEFAULT 'France' NOT NULL, + postal_code VARCHAR(20) NOT NULL, + city VARCHAR(120) NOT NULL, + street VARCHAR(255) NOT NULL, + street_complement VARCHAR(255) DEFAULT NULL, + position INT DEFAULT 0 NOT NULL, + created_at TIMESTAMP(0) WITHOUT TIME ZONE NOT NULL, + updated_at TIMESTAMP(0) WITHOUT TIME ZONE NOT NULL, + created_by INT DEFAULT NULL, + updated_by INT DEFAULT NULL, + PRIMARY KEY (id), + CONSTRAINT fk_provider_address_provider + FOREIGN KEY (provider_id) REFERENCES provider (id) ON DELETE CASCADE, + CONSTRAINT fk_provider_address_created_by + FOREIGN KEY (created_by) REFERENCES "user" (id) ON DELETE SET NULL, + CONSTRAINT fk_provider_address_updated_by + FOREIGN KEY (updated_by) REFERENCES "user" (id) ON DELETE SET NULL + ) + SQL); + $this->addSql('CREATE INDEX idx_provider_address_provider ON provider_address (provider_id)'); + + $this->comment('provider_address', '_table', 'Adresses d un prestataire (1:n) — >= 1 site rattache (RG-3.05). SANS address_type / bennes / triage_provider (specifiques fournisseur).'); + $this->comment('provider_address', 'id', 'Identifiant interne auto-incremente.'); + $this->comment('provider_address', 'provider_id', 'FK -> provider.id, ON DELETE CASCADE — prestataire proprietaire de l adresse.'); + $this->comment('provider_address', 'country', 'Pays de l adresse — defaut France.'); + $this->comment('provider_address', 'postal_code', 'Code postal (4-5 chiffres attendus) — declenche l autocompletion ville via l API BAN cote front (RG-3.06).'); + $this->comment('provider_address', 'city', 'Ville — preremplie depuis le code postal via API BAN cote front.'); + $this->comment('provider_address', 'street', 'Numero et voie de l adresse.'); + $this->comment('provider_address', 'street_complement', 'Complement d adresse (etage, batiment...) — optionnel.'); + $this->comment('provider_address', 'position', 'Ordre d affichage de l adresse dans la liste du prestataire (croissant).'); + $this->addTimestampableBlamableComments('provider_address'); + } + + // ================================================================= + // Jointures de provider_address (M2M) + // ================================================================= + + private function createProviderAddressJoinTables(): void + { + $this->addSql(<<<'SQL' + CREATE TABLE provider_address_site ( + provider_address_id INT NOT NULL, + site_id INT NOT NULL, + PRIMARY KEY (provider_address_id, site_id), + CONSTRAINT fk_provider_address_site_address + FOREIGN KEY (provider_address_id) REFERENCES provider_address (id) ON DELETE CASCADE, + CONSTRAINT fk_provider_address_site_site + FOREIGN KEY (site_id) REFERENCES site (id) ON DELETE RESTRICT + ) + SQL); + $this->comment('provider_address_site', '_table', 'Jointure M2M provider_address <-> site (Sites) — sites rattaches a l adresse (>= 1 obligatoire, RG-3.05).'); + $this->comment('provider_address_site', 'provider_address_id', 'FK -> provider_address.id, ON DELETE CASCADE — adresse concernee.'); + $this->comment('provider_address_site', 'site_id', 'FK -> site.id, ON DELETE RESTRICT — site rattache a l adresse.'); + + $this->addSql(<<<'SQL' + CREATE TABLE provider_address_contact ( + provider_address_id INT NOT NULL, + provider_contact_id INT NOT NULL, + PRIMARY KEY (provider_address_id, provider_contact_id), + CONSTRAINT fk_provider_address_contact_address + FOREIGN KEY (provider_address_id) REFERENCES provider_address (id) ON DELETE CASCADE, + CONSTRAINT fk_provider_address_contact_contact + FOREIGN KEY (provider_contact_id) REFERENCES provider_contact (id) ON DELETE CASCADE + ) + SQL); + $this->comment('provider_address_contact', '_table', 'Jointure M2M provider_address <-> provider_contact — contacts associes a une adresse.'); + $this->comment('provider_address_contact', 'provider_address_id', 'FK -> provider_address.id, ON DELETE CASCADE — adresse concernee.'); + $this->comment('provider_address_contact', 'provider_contact_id', 'FK -> provider_contact.id, ON DELETE CASCADE — contact associe a l adresse.'); + + $this->addSql(<<<'SQL' + CREATE TABLE provider_address_category ( + provider_address_id INT NOT NULL, + category_id INT NOT NULL, + PRIMARY KEY (provider_address_id, category_id), + CONSTRAINT fk_provider_address_category_address + FOREIGN KEY (provider_address_id) REFERENCES provider_address (id) ON DELETE CASCADE, + CONSTRAINT fk_provider_address_category_category + FOREIGN KEY (category_id) REFERENCES category (id) ON DELETE RESTRICT + ) + SQL); + $this->comment('provider_address_category', '_table', 'Jointure M2M provider_address <-> category — categories d adresse de type PRESTATAIRE (RG-3.09).'); + $this->comment('provider_address_category', 'provider_address_id', 'FK -> provider_address.id, ON DELETE CASCADE — adresse concernee.'); + $this->comment('provider_address_category', 'category_id', 'FK -> category.id, ON DELETE RESTRICT — categorie d adresse de type PRESTATAIRE (RG-3.09).'); + } + + // ================================================================= + // Sous-collection : RIB (1:n) + // ================================================================= + + private function createProviderRib(): void + { + $this->addSql(<<<'SQL' + CREATE TABLE provider_rib ( + id INT GENERATED BY DEFAULT AS IDENTITY NOT NULL, + provider_id INT NOT NULL, + label VARCHAR(120) NOT NULL, + bic VARCHAR(20) NOT NULL, + iban VARCHAR(34) NOT NULL, + position INT DEFAULT 0 NOT NULL, + created_at TIMESTAMP(0) WITHOUT TIME ZONE NOT NULL, + updated_at TIMESTAMP(0) WITHOUT TIME ZONE NOT NULL, + created_by INT DEFAULT NULL, + updated_by INT DEFAULT NULL, + PRIMARY KEY (id), + CONSTRAINT fk_provider_rib_provider + FOREIGN KEY (provider_id) REFERENCES provider (id) ON DELETE CASCADE, + CONSTRAINT fk_provider_rib_created_by + FOREIGN KEY (created_by) REFERENCES "user" (id) ON DELETE SET NULL, + CONSTRAINT fk_provider_rib_updated_by + FOREIGN KEY (updated_by) REFERENCES "user" (id) ON DELETE SET NULL + ) + SQL); + $this->addSql('CREATE INDEX idx_provider_rib_provider ON provider_rib (provider_id)'); + + $this->comment('provider_rib', '_table', 'Coordonnees bancaires d un prestataire (1:n) — >= 1 RIB attendu selon le type de reglement (RG-3.08). Tous les champs audites (pas d AuditIgnore).'); + $this->comment('provider_rib', 'id', 'Identifiant interne auto-incremente.'); + $this->comment('provider_rib', 'provider_id', 'FK -> provider.id, ON DELETE CASCADE — prestataire proprietaire du RIB.'); + $this->comment('provider_rib', 'label', 'Libelle du RIB (ex: compte principal).'); + $this->comment('provider_rib', 'bic', 'Code BIC/SWIFT de la banque (8 ou 11 caracteres).'); + $this->comment('provider_rib', 'iban', 'IBAN du compte (≤ 34 caracteres).'); + $this->comment('provider_rib', 'position', 'Ordre d affichage du RIB dans la liste du prestataire (croissant).'); + $this->addTimestampableBlamableComments('provider_rib'); + } + + // ================================================================= + // Helpers + // ================================================================= + + /** + * Pose les 4 commentaires standardises Timestampable/Blamable sur une table, + * en reutilisant le catalogue partage (source unique, cf. ERP-67). Seul le + * tableau statique des textes est reutilise — aucune dependance a l etat DB. + */ + private function addTimestampableBlamableComments(string $table): void + { + foreach (ColumnCommentsCatalog::timestampableBlamableComments() as $column => $description) { + $this->comment($table, $column, $description); + } + } + + /** + * Emet un `COMMENT ON TABLE` (colonne speciale `_table`) ou + * `COMMENT ON COLUMN` en dollar-quoting Postgres ($_$...$_$) pour eviter + * tout echappement d apostrophe. + */ + private function comment(string $table, string $column, string $description): void + { + $quotedTable = '"'.str_replace('"', '""', $table).'"'; + + if ('_table' === $column) { + $this->addSql(sprintf('COMMENT ON TABLE %s IS $_$%s$_$', $quotedTable, $description)); + + return; + } + + $this->addSql(sprintf( + 'COMMENT ON COLUMN %s.%s IS $_$%s$_$', + $quotedTable, + '"'.str_replace('"', '""', $column).'"', + $description, + )); + } +} diff --git a/src/Shared/Infrastructure/Database/ColumnCommentsCatalog.php b/src/Shared/Infrastructure/Database/ColumnCommentsCatalog.php index c2e0720..c034d04 100644 --- a/src/Shared/Infrastructure/Database/ColumnCommentsCatalog.php +++ b/src/Shared/Infrastructure/Database/ColumnCommentsCatalog.php @@ -361,6 +361,14 @@ final class ColumnCommentsCatalog 'iban' => 'IBAN du compte (≤ 34 caracteres).', 'position' => 'Ordre d affichage du RIB dans la liste du fournisseur (croissant).', ] + self::timestampableBlamableComments(), + + // NB : les tables provider* (M3 Technique) NE SONT PAS encore au + // catalogue. Tant que les entites Provider* n existent pas (ERP-133), + // `schema:update --force` du setup de test droppe ces tables non + // mappees ; les referencer ici ferait planter `app:apply-column-comments` + // (table absente en test). La migration ERP-132 porte ses COMMENT inline + // (dev/prod). Le catalogue sera etendu au ticket entites (ERP-133), + // comme l a fait supplier (ERP-86) apres sa migration (ERP-85). ]; }