diff --git a/packages/db/migrations/20260126132426_AddWorkspaceRoles.sql b/packages/db/migrations/20260126135909_AddWorkspaceRoles.sql similarity index 82% rename from packages/db/migrations/20260126132426_AddWorkspaceRoles.sql rename to packages/db/migrations/20260126135909_AddWorkspaceRoles.sql index bc84e7b4..82f7844a 100644 --- a/packages/db/migrations/20260126132426_AddWorkspaceRoles.sql +++ b/packages/db/migrations/20260126135909_AddWorkspaceRoles.sql @@ -19,13 +19,15 @@ CREATE TABLE IF NOT EXISTS "workspace_role_permissions" ( ALTER TABLE "workspace_role_permissions" ENABLE ROW LEVEL SECURITY;--> statement-breakpoint CREATE TABLE IF NOT EXISTS "workspace_roles" ( "id" bigserial PRIMARY KEY NOT NULL, + "publicId" varchar(12) NOT NULL, "workspaceId" bigint NOT NULL, "name" varchar(64) NOT NULL, "description" varchar(255), "hierarchyLevel" integer NOT NULL, "isSystem" boolean DEFAULT false NOT NULL, "createdAt" timestamp DEFAULT now() NOT NULL, - "updatedAt" timestamp + "updatedAt" timestamp, + CONSTRAINT "workspace_roles_publicId_unique" UNIQUE("publicId") ); --> statement-breakpoint ALTER TABLE "workspace_roles" ENABLE ROW LEVEL SECURITY;--> statement-breakpoint @@ -56,25 +58,40 @@ EXCEPTION END $$; --> statement-breakpoint +-- Helper function to generate 12-character public IDs +CREATE OR REPLACE FUNCTION generate_public_id() RETURNS varchar(12) AS $$ +DECLARE + chars text := 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'; + result varchar(12) := ''; + i integer; +BEGIN + FOR i IN 1..12 LOOP + result := result || substr(chars, floor(random() * length(chars) + 1)::integer, 1); + END LOOP; + RETURN result; +END; +$$ LANGUAGE plpgsql; +--> statement-breakpoint + -- Seed system roles for each existing workspace -INSERT INTO "workspace_roles" ("workspaceId", "name", "description", "hierarchyLevel", "isSystem", "createdAt") -SELECT w.id, 'admin', 'Full access to all workspace features', 100, true, NOW() +INSERT INTO "workspace_roles" ("publicId", "workspaceId", "name", "description", "hierarchyLevel", "isSystem", "createdAt") +SELECT generate_public_id(), w.id, 'admin', 'Full access to all workspace features', 100, true, NOW() FROM "workspace" w WHERE NOT EXISTS ( SELECT 1 FROM "workspace_roles" wr WHERE wr."workspaceId" = w.id AND wr."name" = 'admin' ); --> statement-breakpoint -INSERT INTO "workspace_roles" ("workspaceId", "name", "description", "hierarchyLevel", "isSystem", "createdAt") -SELECT w.id, 'member', 'Standard member with create and edit permissions', 50, true, NOW() +INSERT INTO "workspace_roles" ("publicId", "workspaceId", "name", "description", "hierarchyLevel", "isSystem", "createdAt") +SELECT generate_public_id(), w.id, 'member', 'Standard member with create and edit permissions', 50, true, NOW() FROM "workspace" w WHERE NOT EXISTS ( SELECT 1 FROM "workspace_roles" wr WHERE wr."workspaceId" = w.id AND wr."name" = 'member' ); --> statement-breakpoint -INSERT INTO "workspace_roles" ("workspaceId", "name", "description", "hierarchyLevel", "isSystem", "createdAt") -SELECT w.id, 'guest', 'View-only access', 10, true, NOW() +INSERT INTO "workspace_roles" ("publicId", "workspaceId", "name", "description", "hierarchyLevel", "isSystem", "createdAt") +SELECT generate_public_id(), w.id, 'guest', 'View-only access', 10, true, NOW() FROM "workspace" w WHERE NOT EXISTS ( SELECT 1 FROM "workspace_roles" wr @@ -149,3 +166,7 @@ FROM "workspace_roles" wr WHERE wm."workspaceId" = wr."workspaceId" AND wm."role"::text = wr."name" AND wm."roleId" IS NULL; +--> statement-breakpoint + +-- Clean up helper function +DROP FUNCTION IF EXISTS generate_public_id(); diff --git a/packages/db/migrations/meta/20260126132426_snapshot.json b/packages/db/migrations/meta/20260126135909_snapshot.json similarity index 99% rename from packages/db/migrations/meta/20260126132426_snapshot.json rename to packages/db/migrations/meta/20260126135909_snapshot.json index 58e1d60b..05d71975 100644 --- a/packages/db/migrations/meta/20260126132426_snapshot.json +++ b/packages/db/migrations/meta/20260126135909_snapshot.json @@ -1,5 +1,5 @@ { - "id": "50b875bf-3579-4fde-9073-33a40244182d", + "id": "c24a8e89-c100-4483-9f0b-391201327ac5", "prevId": "4e1ebb8b-bd52-48c5-87d6-8e6e5eb8bbde", "version": "7", "dialect": "postgresql", @@ -3071,6 +3071,12 @@ "primaryKey": true, "notNull": true }, + "publicId": { + "name": "publicId", + "type": "varchar(12)", + "primaryKey": false, + "notNull": true + }, "workspaceId": { "name": "workspaceId", "type": "bigint", @@ -3170,7 +3176,15 @@ } }, "compositePrimaryKeys": {}, - "uniqueConstraints": {}, + "uniqueConstraints": { + "workspace_roles_publicId_unique": { + "name": "workspace_roles_publicId_unique", + "nullsNotDistinct": false, + "columns": [ + "publicId" + ] + } + }, "policies": {}, "checkConstraints": {}, "isRLSEnabled": true diff --git a/packages/db/migrations/meta/_journal.json b/packages/db/migrations/meta/_journal.json index 60096a9f..795dc98c 100644 --- a/packages/db/migrations/meta/_journal.json +++ b/packages/db/migrations/meta/_journal.json @@ -166,8 +166,8 @@ { "idx": 23, "version": "7", - "when": 1769433866743, - "tag": "20260126132426_AddWorkspaceRoles", + "when": 1769435949476, + "tag": "20260126135909_AddWorkspaceRoles", "breakpoints": true } ]