-- Mehrere Domains für Kurz-URLs. -- -- Zwei Dinge sind hier heikel und deshalb ausdrücklich schrittweise gelöst: -- -- 1. `QrCode.domainId` ist verpflichtend, es gibt aber schon Codes. Die -- Spalte entsteht zuerst ohne Einschränkung, wird gefüllt und erst danach -- auf NOT NULL gesetzt. -- 2. `slug` war global eindeutig und ist es künftig nur noch je Domain. Der -- alte Index muss weichen, bevor der neue greifen kann. -- CreateTable CREATE TABLE "Domain" ( "id" TEXT NOT NULL, "hostname" TEXT NOT NULL, "label" TEXT, "isActive" BOOLEAN NOT NULL DEFAULT true, "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, "updatedAt" TIMESTAMP(3) NOT NULL, CONSTRAINT "Domain_pkey" PRIMARY KEY ("id") ); -- CreateTable CREATE TABLE "DomainGrant" ( "id" TEXT NOT NULL, "domainId" TEXT NOT NULL, "groupId" TEXT NOT NULL, "isDefault" BOOLEAN NOT NULL DEFAULT false, "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, CONSTRAINT "DomainGrant_pkey" PRIMARY KEY ("id") ); -- CreateIndex CREATE UNIQUE INDEX "Domain_hostname_key" ON "Domain"("hostname"); -- CreateIndex CREATE INDEX "DomainGrant_groupId_idx" ON "DomainGrant"("groupId"); -- CreateIndex CREATE UNIQUE INDEX "DomainGrant_domainId_groupId_key" ON "DomainGrant"("domainId", "groupId"); -- Standard-Domain. Der Hostname ist zunächst ein Platzhalter: die -- Migration kennt BASE_URL nicht. Beim ersten Start ersetzt -- ensureDefaultDomain() ihn durch den Hostnamen aus BASE_URL. INSERT INTO "Domain" ("id", "hostname", "label", "isActive", "createdAt", "updatedAt") VALUES ( 'dom_standard', 'standard.invalid', 'Standard-Domain', true, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP ); -- Alle bestehenden Gruppen bekommen die Standard-Domain als Voreinstellung. INSERT INTO "DomainGrant" ("id", "domainId", "groupId", "isDefault", "createdAt") SELECT 'dg_std_' || "Group"."id", 'dom_standard', "Group"."id", true, CURRENT_TIMESTAMP FROM "Group"; -- AlterTable: erst nullable … ALTER TABLE "QrCode" ADD COLUMN "domainId" TEXT; -- … bestehende Codes der Standard-Domain zuordnen … UPDATE "QrCode" SET "domainId" = 'dom_standard' WHERE "domainId" IS NULL; -- … und erst jetzt verpflichtend machen. ALTER TABLE "QrCode" ALTER COLUMN "domainId" SET NOT NULL; -- Eindeutigkeit des Slugs von global auf „je Domain“ umstellen. DROP INDEX "QrCode_slug_key"; -- CreateIndex CREATE UNIQUE INDEX "QrCode_domainId_slug_key" ON "QrCode"("domainId", "slug"); -- CreateIndex CREATE INDEX "QrCode_domainId_idx" ON "QrCode"("domainId"); -- AddForeignKey ALTER TABLE "DomainGrant" ADD CONSTRAINT "DomainGrant_domainId_fkey" FOREIGN KEY ("domainId") REFERENCES "Domain"("id") ON DELETE CASCADE ON UPDATE CASCADE; -- AddForeignKey ALTER TABLE "DomainGrant" ADD CONSTRAINT "DomainGrant_groupId_fkey" FOREIGN KEY ("groupId") REFERENCES "Group"("id") ON DELETE CASCADE ON UPDATE CASCADE; -- AddForeignKey ALTER TABLE "QrCode" ADD CONSTRAINT "QrCode_domainId_fkey" FOREIGN KEY ("domainId") REFERENCES "Domain"("id") ON DELETE RESTRICT ON UPDATE CASCADE;