From 3ff89d43ede4a3ecf5d741140ecc5cbd574da08e Mon Sep 17 00:00:00 2001 From: Matthieu Date: Wed, 6 May 2026 16:34:26 +0200 Subject: [PATCH] fix(db) : ajoute les FK CASCADE manquantes documents.composantId et machine_component_links.composantId MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Les entités Doctrine déclaraient déjà onDelete: CASCADE pour ces deux relations, mais les contraintes correspondantes étaient absentes en base. Conséquence : la suppression d'un composant pouvait laisser des documents ou des links machine orphelins. La migration nettoie les orphelins existants (avec trace dans audit_logs) puis ajoute les deux FK. --- ...n20260506140000_FixComposantCascadeFKs.php | 106 ++++++++++++++++++ 1 file changed, 106 insertions(+) create mode 100644 migrations/Version20260506140000_FixComposantCascadeFKs.php diff --git a/migrations/Version20260506140000_FixComposantCascadeFKs.php b/migrations/Version20260506140000_FixComposantCascadeFKs.php new file mode 100644 index 0000000..7b5a0e8 --- /dev/null +++ b/migrations/Version20260506140000_FixComposantCascadeFKs.php @@ -0,0 +1,106 @@ +addSql(<<<'SQL' + INSERT INTO audit_logs (id, entitytype, entityid, action, snapshot, actorprofileid, createdat) + SELECT + 'cl' || substring(md5(random()::text || clock_timestamp()::text), 1, 24), + 'document', + d.id, + 'delete', + json_build_object( + 'id', d.id, + 'name', d.name, + 'filename', d.filename, + 'composantId', d.composantid, + 'note', 'Cleaned by FK cascade fix migration (Version20260506140000) - referenced composant no longer existed' + ), + NULL, + NOW() + FROM documents d + WHERE d.composantid IS NOT NULL + AND d.composantid NOT IN (SELECT id FROM composants) + SQL); + + $this->addSql(<<<'SQL' + INSERT INTO audit_logs (id, entitytype, entityid, action, snapshot, actorprofileid, createdat) + SELECT + 'cl' || substring(md5(random()::text || clock_timestamp()::text), 1, 24), + 'machine_component_link', + l.id, + 'delete', + json_build_object( + 'id', l.id, + 'machineId', l.machineid, + 'composantId', l.composantid, + 'note', 'Cleaned by FK cascade fix migration (Version20260506140000) - referenced composant no longer existed' + ), + NULL, + NOW() + FROM machine_component_links l + WHERE l.composantid IS NOT NULL + AND l.composantid NOT IN (SELECT id FROM composants) + SQL); + + // 2. Nettoyage des orphelins. + $this->addSql(<<<'SQL' + DELETE FROM documents + WHERE composantid IS NOT NULL + AND composantid NOT IN (SELECT id FROM composants) + SQL); + + $this->addSql(<<<'SQL' + DELETE FROM machine_component_links + WHERE composantid IS NOT NULL + AND composantid NOT IN (SELECT id FROM composants) + SQL); + + // 3. Ajout idempotent des 2 FK manquantes (alignement avec les entités Doctrine). + $this->addSql(<<<'SQL' + DO $$ BEGIN + IF NOT EXISTS ( + SELECT 1 FROM information_schema.table_constraints + WHERE constraint_name = 'fk_documents_composant' AND table_name = 'documents' + ) THEN + ALTER TABLE documents ADD CONSTRAINT fk_documents_composant + FOREIGN KEY (composantid) REFERENCES composants(id) ON DELETE CASCADE; + END IF; + END $$; + SQL); + + $this->addSql(<<<'SQL' + DO $$ BEGIN + IF NOT EXISTS ( + SELECT 1 FROM information_schema.table_constraints + WHERE constraint_name = 'fk_mcl_composant' AND table_name = 'machine_component_links' + ) THEN + ALTER TABLE machine_component_links ADD CONSTRAINT fk_mcl_composant + FOREIGN KEY (composantid) REFERENCES composants(id) ON DELETE CASCADE; + END IF; + END $$; + SQL); + } + + public function down(Schema $schema): void + { + $this->addSql('ALTER TABLE documents DROP CONSTRAINT IF EXISTS fk_documents_composant'); + $this->addSql('ALTER TABLE machine_component_links DROP CONSTRAINT IF EXISTS fk_mcl_composant'); + } +}