addSql('ALTER TABLE machine_component_links DROP COLUMN IF EXISTS typemachinecomponentrequirementid'); $this->addSql('ALTER TABLE machine_piece_links DROP COLUMN IF EXISTS typemachinepiecerequirementid'); $this->addSql('ALTER TABLE machine_product_links DROP COLUMN IF EXISTS typemachineproductrequirementid'); // 2. Add machineid column to custom_fields (new direct FK to machines) $this->addSql('ALTER TABLE custom_fields ADD COLUMN IF NOT EXISTS machineid VARCHAR(36) DEFAULT NULL'); $this->addSql(<<<'SQL' DO $$ BEGIN IF NOT EXISTS ( SELECT 1 FROM information_schema.table_constraints WHERE constraint_name = 'fk_custom_fields_machine' AND table_name = 'custom_fields' ) THEN ALTER TABLE custom_fields ADD CONSTRAINT fk_custom_fields_machine FOREIGN KEY (machineid) REFERENCES machines(id) ON DELETE CASCADE; END IF; END $$; SQL); // 3. Enable pgcrypto for gen_random_bytes (needed for CUID generation) $this->addSql('CREATE EXTENSION IF NOT EXISTS pgcrypto'); // 4. Migrate existing custom fields: copy from TypeMachine to each linked Machine $this->addSql(<<<'SQL' INSERT INTO custom_fields (id, name, type, required, defaultvalue, options, orderindex, machineid, createdat, updatedat) SELECT 'cl' || encode(gen_random_bytes(12), 'hex'), cf.name, cf.type, cf.required, cf.defaultvalue, cf.options, cf.orderindex, m.id, NOW(), NOW() FROM custom_fields cf JOIN machines m ON m.typemachineid = cf.typemachineid WHERE cf.typemachineid IS NOT NULL AND NOT EXISTS ( SELECT 1 FROM custom_fields existing WHERE existing.machineid = m.id AND existing.name = cf.name ) SQL); // 4. Delete original TypeMachine-linked custom fields (now migrated) $this->addSql('DELETE FROM custom_fields WHERE typemachineid IS NOT NULL'); // 5. Drop typemachineid column from custom_fields $this->addSql('ALTER TABLE custom_fields DROP COLUMN IF EXISTS typemachineid'); // 6. Drop typemachineid column from machines $this->addSql('ALTER TABLE machines DROP COLUMN IF EXISTS typemachineid'); // 7. Drop requirement tables (order matters: these reference type_machines) $this->addSql('DROP TABLE IF EXISTS type_machine_component_requirements'); $this->addSql('DROP TABLE IF EXISTS type_machine_piece_requirements'); $this->addSql('DROP TABLE IF EXISTS type_machine_product_requirements'); // 8. Drop type_machines table $this->addSql('DROP TABLE IF EXISTS type_machines'); } public function down(Schema $schema): void { // Recreate type_machines table $this->addSql(<<<'SQL' CREATE TABLE IF NOT EXISTS type_machines ( id VARCHAR(36) NOT NULL PRIMARY KEY, name VARCHAR(255) NOT NULL UNIQUE, description TEXT DEFAULT NULL, category VARCHAR(255) DEFAULT NULL, maintenancefrequency VARCHAR(255) DEFAULT NULL, components JSON DEFAULT NULL, criticalparts JSON DEFAULT NULL, machinepieces JSON DEFAULT NULL, specifications JSON DEFAULT NULL, createdat TIMESTAMP(0) WITHOUT TIME ZONE NOT NULL, updatedat TIMESTAMP(0) WITHOUT TIME ZONE NOT NULL ) SQL); // Recreate requirement tables $this->addSql(<<<'SQL' CREATE TABLE IF NOT EXISTS type_machine_component_requirements ( id VARCHAR(36) NOT NULL PRIMARY KEY, typemachineid VARCHAR(36) NOT NULL REFERENCES type_machines(id) ON DELETE CASCADE, typecomposantid VARCHAR(36) NOT NULL REFERENCES model_types(id), label VARCHAR(255) DEFAULT NULL, mincount INTEGER DEFAULT 1, maxcount INTEGER DEFAULT NULL, required BOOLEAN DEFAULT true, allownewmodels BOOLEAN DEFAULT true, orderindex INTEGER DEFAULT 0, createdat TIMESTAMP(0) WITHOUT TIME ZONE NOT NULL, updatedat TIMESTAMP(0) WITHOUT TIME ZONE NOT NULL ) SQL); $this->addSql(<<<'SQL' CREATE TABLE IF NOT EXISTS type_machine_piece_requirements ( id VARCHAR(36) NOT NULL PRIMARY KEY, typemachineid VARCHAR(36) NOT NULL REFERENCES type_machines(id) ON DELETE CASCADE, typepieceid VARCHAR(36) NOT NULL REFERENCES model_types(id), label VARCHAR(255) DEFAULT NULL, mincount INTEGER DEFAULT 0, maxcount INTEGER DEFAULT NULL, required BOOLEAN DEFAULT false, allownewmodels BOOLEAN DEFAULT true, orderindex INTEGER DEFAULT 0, createdat TIMESTAMP(0) WITHOUT TIME ZONE NOT NULL, updatedat TIMESTAMP(0) WITHOUT TIME ZONE NOT NULL ) SQL); $this->addSql(<<<'SQL' CREATE TABLE IF NOT EXISTS type_machine_product_requirements ( id VARCHAR(36) NOT NULL PRIMARY KEY, typemachineid VARCHAR(36) NOT NULL REFERENCES type_machines(id) ON DELETE CASCADE, typeproductid VARCHAR(36) NOT NULL REFERENCES model_types(id), label VARCHAR(255) DEFAULT NULL, mincount INTEGER DEFAULT 0, maxcount INTEGER DEFAULT NULL, required BOOLEAN DEFAULT false, allownewmodels BOOLEAN DEFAULT true, orderindex INTEGER DEFAULT 0, createdat TIMESTAMP(0) WITHOUT TIME ZONE NOT NULL, updatedat TIMESTAMP(0) WITHOUT TIME ZONE NOT NULL ) SQL); // Re-add typemachineid to machines $this->addSql('ALTER TABLE machines ADD COLUMN IF NOT EXISTS typemachineid VARCHAR(36) DEFAULT NULL'); // Re-add typemachineid to custom_fields $this->addSql('ALTER TABLE custom_fields ADD COLUMN IF NOT EXISTS typemachineid VARCHAR(36) DEFAULT NULL'); // Re-add requirement FK columns to link tables $this->addSql('ALTER TABLE machine_component_links ADD COLUMN IF NOT EXISTS typemachinecomponentrequirementid VARCHAR(36) DEFAULT NULL'); $this->addSql('ALTER TABLE machine_piece_links ADD COLUMN IF NOT EXISTS typemachinepiecerequirementid VARCHAR(36) DEFAULT NULL'); $this->addSql('ALTER TABLE machine_product_links ADD COLUMN IF NOT EXISTS typemachineproductrequirementid VARCHAR(36) DEFAULT NULL'); // Drop machine FK on custom_fields $this->addSql('ALTER TABLE custom_fields DROP COLUMN IF EXISTS machineid'); } }