fix(db): make grant migration replay safe

Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
DottaandPaperclip committed 2026-08-20 22:29:50 +00:00
1 parent b78d75192b
commit 8a1adc8c1d
2 files changed
+33 -12

No files matched your search

@@ -20,8 +20,15 @@ describe("connection grants phase 2 migration", () => {
});
it("adds credential policy and the grant audience table", () => {
expect(sql).toContain(`CREATE TABLE "connection_grant_members"`);
expect(sql).toContain(`ADD COLUMN "credential_policy" text DEFAULT 'shared' NOT NULL`);
expect(sql).toContain(`CREATE TABLE IF NOT EXISTS "connection_grant_members"`);
expect(sql).toContain(`ADD COLUMN IF NOT EXISTS "credential_policy" text DEFAULT 'shared' NOT NULL`);
expect(sql).toContain(`'shared', 'per_user', 'per_user_with_fallback'`);
});
it("is safe to replay when schema state is ahead of the migration journal", () => {
expect(sql).toContain(`DROP CONSTRAINT IF EXISTS "connection_grant_members_company_grant_fk"`);
expect(sql).toContain(`DROP CONSTRAINT IF EXISTS "tool_connections_credential_policy_check"`);
expect(sql).toContain(`CREATE UNIQUE INDEX IF NOT EXISTS "connection_grants_default_uq"`);
expect(sql).toContain(`IF NOT EXISTS (\n\t\tSELECT 1\n\t\tFROM pg_constraint`);
});
});
+24 -10
View File
@@ -9,7 +9,7 @@ WHERE "entry"."profile_id" = "profile"."id"
AND "profile"."metadata" ->> 'source' IN ('app_gallery_finish', 'tool_connection_install')
AND "profile"."metadata" ->> 'connectionId' = "entry"."connection_id"::text;
--> statement-breakpoint
CREATE TABLE "connection_grant_members" (
CREATE TABLE IF NOT EXISTS "connection_grant_members" (
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
"company_id" uuid NOT NULL,
"grant_id" uuid NOT NULL,
@@ -19,10 +19,14 @@ CREATE TABLE "connection_grant_members" (
CONSTRAINT "connection_grant_members_subject_type_check" CHECK ("connection_grant_members"."subject_type" in ('user'))
);
--> statement-breakpoint
ALTER TABLE "connection_grants" DROP CONSTRAINT "connection_grants_kind_check";--> statement-breakpoint
ALTER TABLE "connection_grants" DROP CONSTRAINT "connection_grants_subject_check";--> statement-breakpoint
ALTER TABLE "connection_grants" DROP CONSTRAINT "connection_grants_default_check";--> statement-breakpoint
DROP INDEX "connection_grants_default_uq";--> statement-breakpoint
ALTER TABLE "connection_grant_members" DROP CONSTRAINT IF EXISTS "connection_grant_members_company_grant_fk";--> statement-breakpoint
ALTER TABLE "connection_grant_members" DROP CONSTRAINT IF EXISTS "connection_grant_members_grant_id_connection_grants_id_fk";--> statement-breakpoint
ALTER TABLE "connection_grant_members" DROP CONSTRAINT IF EXISTS "connection_grant_members_company_id_companies_id_fk";--> statement-breakpoint
ALTER TABLE "connection_grants" DROP CONSTRAINT IF EXISTS "connection_grants_kind_check";--> statement-breakpoint
ALTER TABLE "connection_grants" DROP CONSTRAINT IF EXISTS "connection_grants_subject_check";--> statement-breakpoint
ALTER TABLE "connection_grants" DROP CONSTRAINT IF EXISTS "connection_grants_default_check";--> statement-breakpoint
ALTER TABLE "tool_connections" DROP CONSTRAINT IF EXISTS "tool_connections_credential_policy_check";--> statement-breakpoint
DROP INDEX IF EXISTS "connection_grants_default_uq";--> statement-breakpoint
UPDATE "connection_grants" SET "kind" = 'organization' WHERE "kind" = 'workspace';--> statement-breakpoint
INSERT INTO "connection_grants" (
"company_id", "connection_id", "kind", "credential_secret_refs", "status", "is_default",
@@ -36,13 +40,23 @@ WHERE NOT EXISTS (
SELECT 1 FROM "connection_grants" g
WHERE g."connection_id" = c."id" AND g."is_default" = true
);--> statement-breakpoint
ALTER TABLE "tool_connections" ADD COLUMN "credential_policy" text DEFAULT 'shared' NOT NULL;--> statement-breakpoint
ALTER TABLE "tool_connections" ADD COLUMN IF NOT EXISTS "credential_policy" text DEFAULT 'shared' NOT NULL;--> statement-breakpoint
ALTER TABLE "connection_grant_members" ADD CONSTRAINT "connection_grant_members_company_id_companies_id_fk" FOREIGN KEY ("company_id") REFERENCES "public"."companies"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
ALTER TABLE "connection_grants" ADD CONSTRAINT "connection_grants_company_id_uq" UNIQUE("company_id","id");--> statement-breakpoint
DO $$
BEGIN
IF NOT EXISTS (
SELECT 1
FROM pg_constraint
WHERE conname = 'connection_grants_company_id_uq'
AND conrelid = 'connection_grants'::regclass
) THEN
ALTER TABLE "connection_grants" ADD CONSTRAINT "connection_grants_company_id_uq" UNIQUE("company_id","id");
END IF;
END $$;--> statement-breakpoint
ALTER TABLE "connection_grant_members" ADD CONSTRAINT "connection_grant_members_company_grant_fk" FOREIGN KEY ("company_id","grant_id") REFERENCES "public"."connection_grants"("company_id","id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
CREATE INDEX "connection_grant_members_company_subject_idx" ON "connection_grant_members" USING btree ("company_id","subject_type","subject_id");--> statement-breakpoint
CREATE UNIQUE INDEX "connection_grant_members_grant_subject_uq" ON "connection_grant_members" USING btree ("grant_id","subject_type","subject_id");--> statement-breakpoint
CREATE UNIQUE INDEX "connection_grants_default_uq" ON "connection_grants" USING btree ("connection_id") WHERE "connection_grants"."is_default" = true and "connection_grants"."kind" = 'organization';--> statement-breakpoint
CREATE INDEX IF NOT EXISTS "connection_grant_members_company_subject_idx" ON "connection_grant_members" USING btree ("company_id","subject_type","subject_id");--> statement-breakpoint
CREATE UNIQUE INDEX IF NOT EXISTS "connection_grant_members_grant_subject_uq" ON "connection_grant_members" USING btree ("grant_id","subject_type","subject_id");--> statement-breakpoint
CREATE UNIQUE INDEX IF NOT EXISTS "connection_grants_default_uq" ON "connection_grants" USING btree ("connection_id") WHERE "connection_grants"."is_default" = true and "connection_grants"."kind" = 'organization';--> statement-breakpoint
ALTER TABLE "connection_grants" ADD CONSTRAINT "connection_grants_kind_check" CHECK ("connection_grants"."kind" in ('organization', 'user'));--> statement-breakpoint
ALTER TABLE "connection_grants" ADD CONSTRAINT "connection_grants_subject_check" CHECK (("connection_grants"."kind" = 'user' and "connection_grants"."subject_user_id" is not null) or ("connection_grants"."kind" = 'organization' and "connection_grants"."subject_user_id" is null));--> statement-breakpoint
ALTER TABLE "connection_grants" ADD CONSTRAINT "connection_grants_default_check" CHECK ("connection_grants"."is_default" = false or "connection_grants"."kind" = 'organization');--> statement-breakpoint