addSql('ALTER TABLE appointments ADD active_slot_key VARCHAR(64) DEFAULT NULL'); // Backfill slot-occupying appointments (pending/confirmed only — matches // isSlotTaken) so the unique index protects existing rows too. NULLs do // not collide in a MySQL/MariaDB unique index, so released slots are fine. // Assign the key to at most one row per (doctor, slot) — the latest id — // so the index builds even where dirty historical data already // double-booked a slot, without destructively cancelling any booking. $this->addSql(<<addSql('CREATE UNIQUE INDEX UNIQ_6A41727AE228889B ON appointments (active_slot_key)'); } public function down(Schema $schema): void { // this down() migration is auto-generated, please modify it to your needs $this->addSql('DROP INDEX UNIQ_6A41727AE228889B ON appointments'); $this->addSql('ALTER TABLE appointments DROP active_slot_key'); } }