From 92a6343b666e075cb066147af3f5c76082330db7 Mon Sep 17 00:00:00 2001 From: THOLOT DECHENE Matthieu Date: Thu, 28 May 2026 09:40:00 +0000 Subject: [PATCH] [ERP-43] Migrer les tables Category et CategoryType (#14) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Ticket - Lesstime : [#43](https://gitea.malio.fr) — Migrer les tables Category et CategoryType (M0 Catalog, position 0.1) ## Contenu Migration Doctrine `migrations/Version20260527164000.php` (namespace racine `DoctrineMigrations`, règle ABSOLUE Starseed n°11) : - Table `category_type` : `id INT IDENTITY`, `code VARCHAR(40)` (UNIQUE), `label VARCHAR(120)` - Table `category` : `id`, `name`, `category_type_id` (FK RESTRICT), `deleted_at` (soft delete), + 4 colonnes Timestampable/Blamable (`created_at`/`updated_at` NOT NULL, `created_by`/`updated_by` nullable FK `"user"` ON DELETE SET NULL) - Index unique partiel `uq_category_name_type_active` sur `(LOWER(name), category_type_id) WHERE deleted_at IS NULL` → matérialise **RG-1.07** - Index `idx_category_deleted_at`, `idx_category_type_id`, `idx_category_created_by`, `idx_category_updated_by` ## Tests - `make php-cs-fixer-allow-risky` ✓ - `make db-reset` ✓ (migration exécutée sans erreur) - `make test` ✓ — 248 tests / 858 assertions, 0 échec - Vérification psql `\d category` ✓ (index partiel + 8 colonnes + 3 FK avec les bons ON DELETE) ## ⚠ Mode stacked PR Cette MR cible `feature/ERP-52-creer-pattern-timestampable-blamable-shared` au lieu de `develop`. Quand la MR #13 (ERP-52) sera mergée sur develop, Matthieu repointera la cible de cette MR vers develop. Reviewer suggéré : Tristan --------- Co-authored-by: Matthieu Reviewed-on: https://gitea.malio.fr/MALIO-DEV/Starseed/pulls/14 Reviewed-by: Autin Co-authored-by: THOLOT DECHENE Matthieu Co-committed-by: THOLOT DECHENE Matthieu --- migrations/Version20260527164000.php | 90 ++++++++++++++++++++++++++++ 1 file changed, 90 insertions(+) create mode 100644 migrations/Version20260527164000.php diff --git a/migrations/Version20260527164000.php b/migrations/Version20260527164000.php new file mode 100644 index 0000000..477588c --- /dev/null +++ b/migrations/Version20260527164000.php @@ -0,0 +1,90 @@ +addSql(<<<'SQL' + CREATE TABLE category_type ( + id INT GENERATED BY DEFAULT AS IDENTITY NOT NULL, + code VARCHAR(40) NOT NULL, + label VARCHAR(120) NOT NULL, + PRIMARY KEY (id) + ) + SQL); + $this->addSql('CREATE UNIQUE INDEX uq_category_type_code ON category_type (code)'); + + $this->addSql(<<<'SQL' + CREATE TABLE category ( + id INT GENERATED BY DEFAULT AS IDENTITY NOT NULL, + name VARCHAR(120) NOT NULL, + category_type_id INT NOT 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_category_type + FOREIGN KEY (category_type_id) REFERENCES category_type (id) ON DELETE RESTRICT, + CONSTRAINT fk_category_created_by + FOREIGN KEY (created_by) REFERENCES "user" (id) ON DELETE SET NULL, + CONSTRAINT fk_category_updated_by + FOREIGN KEY (updated_by) REFERENCES "user" (id) ON DELETE SET NULL + ) + SQL); + + // Unicite (name, type) case-insensitive, seulement sur les non-soft-deleted. + $this->addSql(<<<'SQL' + CREATE UNIQUE INDEX uq_category_name_type_active + ON category (LOWER(name), category_type_id) + WHERE deleted_at IS NULL + SQL); + + $this->addSql('CREATE INDEX idx_category_deleted_at ON category (deleted_at)'); + $this->addSql('CREATE INDEX idx_category_type_id ON category (category_type_id)'); + $this->addSql('CREATE INDEX idx_category_created_by ON category (created_by)'); + $this->addSql('CREATE INDEX idx_category_updated_by ON category (updated_by)'); + } + + public function down(Schema $schema): void + { + // Ordre important : `category` porte les FK vers `category_type`. + $this->addSql('DROP TABLE category'); + $this->addSql('DROP TABLE category_type'); + } +}