using Microsoft.EntityFrameworkCore.Migrations; #nullable disable namespace HrynCo.NotificationService.DAL.EF.Migrations; public partial class LinkEmailChannelsToServices : Migration { protected override void Up(MigrationBuilder migrationBuilder) { // EF runs this whole migration in one transaction. Lock the source rows so a // concurrent rename or channel write cannot invalidate the verified mapping. migrationBuilder.Sql(""" LOCK TABLE services IN SHARE ROW EXCLUSIVE MODE; LOCK TABLE email_channels IN ACCESS EXCLUSIVE MODE; DO $$ BEGIN IF EXISTS ( SELECT 1 FROM email_channels c WHERE (SELECT count(*) FROM services s WHERE s.name = c.service_name OR (c.service_name = 'StoreMate-Prod' AND s.name = 'Invemory-Prod')) <> 1 ) THEN RAISE EXCEPTION 'Email channel migration stopped: every legacy service name must have exactly one existing service (including the approved StoreMate-Prod -> Invemory-Prod alias). Resolve missing or ambiguous names before retrying.'; END IF; END $$; ALTER TABLE email_channels ADD COLUMN service_id uuid; UPDATE email_channels c SET service_id = s.id FROM services s WHERE s.name = c.service_name OR (c.service_name = 'StoreMate-Prod' AND s.name = 'Invemory-Prod'); ALTER TABLE email_channels ALTER COLUMN service_id SET NOT NULL; """); migrationBuilder.DropIndex("IX_email_channels_service_name_priority", "email_channels"); migrationBuilder.DropColumn("service_name", "email_channels"); migrationBuilder.CreateIndex("IX_email_channels_service_id_priority", "email_channels", new[] { "service_id", "priority" }); migrationBuilder.AddForeignKey("FK_email_channels_services_service_id", "email_channels", "service_id", "services", principalColumn: "id", onDelete: ReferentialAction.Restrict); } protected override void Down(MigrationBuilder migrationBuilder) { // Restore current service names; historical names are intentionally not retained. migrationBuilder.Sql(""" ALTER TABLE email_channels ADD COLUMN service_name character varying(100); UPDATE email_channels c SET service_name = s.name FROM services s WHERE s.id = c.service_id; ALTER TABLE email_channels ALTER COLUMN service_name SET NOT NULL; """); migrationBuilder.DropForeignKey("FK_email_channels_services_service_id", "email_channels"); migrationBuilder.DropIndex("IX_email_channels_service_id_priority", "email_channels"); migrationBuilder.DropColumn("service_id", "email_channels"); migrationBuilder.CreateIndex("IX_email_channels_service_name_priority", "email_channels", new[] { "service_name", "priority" }); } }