Skip to content

Commit 2986a92

Browse files
committed
address zero-member edge case
1 parent 396c38f commit 2986a92

1 file changed

Lines changed: 18 additions & 8 deletions

File tree

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,16 @@
11
-- migration-safe: data-only backfill. Non-default permission groups no longer support an
2-
-- "all workspaces" scope; they must target specific workspaces. This clears the flag on every
3-
-- grandfathered non-default all-workspaces group and, only for those that HAVE members, targets
4-
-- every workspace the org currently has -- so a member-bearing group keeps governing the same
5-
-- members on existing workspaces. A zero-member all-workspaces group governed nobody under the old
6-
-- member-keyed resolver, so it is left with no workspaces (still inert) rather than being turned
7-
-- into an all-members group that would suddenly govern everyone. Workspace rows are inserted before
8-
-- the flag is cleared so the source set still matches; idempotent via ON CONFLICT and the flag
9-
-- predicate, so a replay is a no-op.
2+
-- "all workspaces" scope (they must target specific workspaces), and a non-default group with no
3+
-- members now governs *all* members of its workspaces. The old resolver was member-keyed, so it is
4+
-- preserved under the new workspace-keyed resolver by:
5+
-- 1. pinning each member-bearing all-workspaces group to every workspace its org currently has, so
6+
-- it keeps governing the same members on existing workspaces;
7+
-- 2. clearing the workspace associations of every zero-member non-default group, so it stays inert
8+
-- -- it governed nobody before and must not flip to governing everyone in its workspaces. This
9+
-- covers both grandfathered all-workspaces groups and pre-existing workspace-specific groups
10+
-- that happen to have no members;
11+
-- 3. clearing the all-workspaces flag on all non-default groups (only the default may be org-wide).
12+
-- Idempotent: ON CONFLICT on the insert, the empty-membership predicate on the delete, and the flag
13+
-- predicate on the update all make a replay a no-op.
1014
INSERT INTO "permission_group_workspace" ("id", "permission_group_id", "workspace_id", "organization_id", "created_at")
1115
SELECT gen_random_uuid()::text, pg."id", w."id", pg."organization_id", now()
1216
FROM "permission_group" pg
@@ -15,6 +19,12 @@ WHERE pg."is_default" = false AND pg."applies_to_all_workspaces" = true
1519
AND EXISTS (SELECT 1 FROM "permission_group_member" m WHERE m."permission_group_id" = pg."id")
1620
ON CONFLICT ("permission_group_id", "workspace_id") DO NOTHING;
1721
--> statement-breakpoint
22+
DELETE FROM "permission_group_workspace" pgw
23+
USING "permission_group" pg
24+
WHERE pgw."permission_group_id" = pg."id"
25+
AND pg."is_default" = false
26+
AND NOT EXISTS (SELECT 1 FROM "permission_group_member" m WHERE m."permission_group_id" = pg."id");
27+
--> statement-breakpoint
1828
UPDATE "permission_group"
1929
SET "applies_to_all_workspaces" = false, "updated_at" = now()
2030
WHERE "is_default" = false AND "applies_to_all_workspaces" = true;

0 commit comments

Comments
 (0)