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.
1014INSERT INTO " permission_group_workspace" (" id" , " permission_group_id" , " workspace_id" , " organization_id" , " created_at" )
1115SELECT gen_random_uuid()::text , pg." id" , w." id" , pg." organization_id" , now()
1216FROM " 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" )
1620ON 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
1828UPDATE " permission_group"
1929SET " applies_to_all_workspaces" = false, " updated_at" = now()
2030WHERE " is_default" = false AND " applies_to_all_workspaces" = true;
0 commit comments