diff --git a/apps/dokploy/drizzle/0103_living_hemingway.sql b/apps/dokploy/drizzle/0103_swift_christian_walker.sql similarity index 89% rename from apps/dokploy/drizzle/0103_living_hemingway.sql rename to apps/dokploy/drizzle/0103_swift_christian_walker.sql index 7cae44016..ecf4a8e5c 100644 --- a/apps/dokploy/drizzle/0103_living_hemingway.sql +++ b/apps/dokploy/drizzle/0103_swift_christian_walker.sql @@ -8,8 +8,10 @@ CREATE TABLE "member_role" ( "created_at" timestamp DEFAULT now() NOT NULL, "updated_at" timestamp DEFAULT now() NOT NULL, "organizationId" text NOT NULL, - CONSTRAINT "member_role_name_unique" UNIQUE("name") + CONSTRAINT "member_role_name_unique" UNIQUE("name"), + CONSTRAINT "role_name_unique" UNIQUE("name","organizationId") ); + -- Create default roles for each organization DO $$ DECLARE @@ -18,7 +20,7 @@ BEGIN FOR org IN SELECT id FROM "organization" LOOP -- Insert owner role - INSERT INTO "organization_role" ("roleId", "name", "description", "canDelete", "is_system", "permissions", "created_at", "updated_at", "organizationId") + INSERT INTO "member_role" ("roleId", "name", "description", "canDelete", "is_system", "permissions", "created_at", "updated_at", "organizationId") VALUES ( org.id || '_owner', 'owner', @@ -32,7 +34,7 @@ BEGIN ); -- Insert admin role - INSERT INTO "organization_role" ("roleId", "name", "description", "canDelete", "is_system", "permissions", "created_at", "updated_at", "organizationId") + INSERT INTO "member_role" ("roleId", "name", "description", "canDelete", "is_system", "permissions", "created_at", "updated_at", "organizationId") VALUES ( org.id || '_admin', 'admin', @@ -46,7 +48,7 @@ BEGIN ); -- Insert member role - INSERT INTO "organization_role" ("roleId", "name", "description", "canDelete", "is_system", "permissions", "created_at", "updated_at", "organizationId") + INSERT INTO "member_role" ("roleId", "name", "description", "canDelete", "is_system", "permissions", "created_at", "updated_at", "organizationId") VALUES ( org.id || '_member', 'member', @@ -63,7 +65,6 @@ END $$; - --> statement-breakpoint ALTER TABLE "user_temp" RENAME TO "users";--> statement-breakpoint ALTER TABLE "users" DROP CONSTRAINT "user_temp_email_unique";--> statement-breakpoint @@ -97,28 +98,10 @@ ALTER TABLE "apikey" ADD CONSTRAINT "apikey_user_id_users_id_fk" FOREIGN KEY ("u ALTER TABLE "invitation" ADD CONSTRAINT "invitation_inviter_id_users_id_fk" FOREIGN KEY ("inviter_id") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint ALTER TABLE "member" ADD CONSTRAINT "member_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint ALTER TABLE "member" ADD CONSTRAINT "member_roleId_member_role_roleId_fk" FOREIGN KEY ("roleId") REFERENCES "public"."member_role"("roleId") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint - --- Update existing members with corresponding roles based on their current role type -DO $$ -DECLARE - mem RECORD; -BEGIN - FOR mem IN SELECT m.id, m.organization_id, m.role as role_type FROM "member" m - LOOP - UPDATE "member" - SET "roleId" = mem.organization_id || '_' || mem.role_type - WHERE id = mem.id; - END LOOP; -END $$; -ALTER TABLE "member" ALTER COLUMN "roleId" SET NOT NULL; - - ALTER TABLE "organization" ADD CONSTRAINT "organization_owner_id_users_id_fk" FOREIGN KEY ("owner_id") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint ALTER TABLE "two_factor" ADD CONSTRAINT "two_factor_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint ALTER TABLE "schedule" ADD CONSTRAINT "schedule_userId_users_id_fk" FOREIGN KEY ("userId") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint - - --> statement-breakpoint CREATE TABLE "web_server" ( "webServerId" text PRIMARY KEY NOT NULL, @@ -133,7 +116,6 @@ CREATE TABLE "web_server" ( "metricsConfig" jsonb DEFAULT '{"server":{"type":"Dokploy","refreshRate":60,"port":4500,"token":"","retentionDays":2,"cronJob":"","urlCallback":"","thresholds":{"cpu":0,"memory":0}},"containers":{"refreshRate":60,"services":{"include":[],"exclude":[]}}}'::jsonb NOT NULL ); --- Migrar datos del usuario owner Ășnico hacia web_server INSERT INTO "web_server" ( "webServerId", "serverIp", diff --git a/apps/dokploy/drizzle/meta/0103_snapshot.json b/apps/dokploy/drizzle/meta/0103_snapshot.json index d500630a8..0e2630dfa 100644 --- a/apps/dokploy/drizzle/meta/0103_snapshot.json +++ b/apps/dokploy/drizzle/meta/0103_snapshot.json @@ -1,5 +1,5 @@ { - "id": "6f7f4450-7a3f-4827-981d-1a609d1091e0", + "id": "56c5008e-c689-4a20-9f3d-06a06e9a5e39", "prevId": "218e3c9b-ef86-4665-98af-56d65282b73b", "version": "7", "dialect": "postgresql", @@ -4738,6 +4738,14 @@ "columns": [ "name" ] + }, + "role_name_unique": { + "name": "role_name_unique", + "nullsNotDistinct": false, + "columns": [ + "name", + "organizationId" + ] } }, "policies": {}, diff --git a/apps/dokploy/drizzle/meta/_journal.json b/apps/dokploy/drizzle/meta/_journal.json index 366ebe12e..182d394dd 100644 --- a/apps/dokploy/drizzle/meta/_journal.json +++ b/apps/dokploy/drizzle/meta/_journal.json @@ -726,8 +726,8 @@ { "idx": 103, "version": "7", - "when": 1752386222325, - "tag": "0103_living_hemingway", + "when": 1752387187927, + "tag": "0103_swift_christian_walker", "breakpoints": true } ] diff --git a/packages/server/src/db/schema/rbac.ts b/packages/server/src/db/schema/rbac.ts index c6ab71cc3..937a4f7da 100644 --- a/packages/server/src/db/schema/rbac.ts +++ b/packages/server/src/db/schema/rbac.ts @@ -1,5 +1,5 @@ import { relations } from "drizzle-orm"; -import { pgTable, text, timestamp, boolean } from "drizzle-orm/pg-core"; +import { pgTable, text, timestamp, boolean, unique } from "drizzle-orm/pg-core"; import { nanoid } from "nanoid"; import { organization, member } from "./account"; import { createInsertSchema } from "drizzle-zod"; @@ -110,21 +110,27 @@ export const defaultPermissions = [ }, ] as const; -export const role = pgTable("member_role", { - roleId: text("roleId") - .primaryKey() - .$defaultFn(() => nanoid()), - name: text("name").notNull().unique(), - description: text("description"), - canDelete: boolean("canDelete").notNull().default(true), - isSystem: boolean("is_system").default(false), - permissions: text("permissions").array(), - createdAt: timestamp("created_at").notNull().defaultNow(), - updatedAt: timestamp("updated_at").notNull().defaultNow(), - organizationId: text("organizationId") - .notNull() - .references(() => organization.id, { onDelete: "cascade" }), -}); +export const role = pgTable( + "member_role", + { + roleId: text("roleId") + .primaryKey() + .$defaultFn(() => nanoid()), + name: text("name").notNull().unique(), + description: text("description"), + canDelete: boolean("canDelete").notNull().default(true), + isSystem: boolean("is_system").default(false), + permissions: text("permissions").array(), + createdAt: timestamp("created_at").notNull().defaultNow(), + updatedAt: timestamp("updated_at").notNull().defaultNow(), + organizationId: text("organizationId") + .notNull() + .references(() => organization.id, { onDelete: "cascade" }), + }, + (table) => ({ + roleName: unique("role_name_unique").on(table.name, table.organizationId), + }), +); export const roleRelations = relations(role, ({ one, many }) => ({ organization: one(organization, {