refactor: add migration

This commit is contained in:
Mauricio Siu 2025-02-13 00:38:22 -06:00
parent 60eee55f2d
commit 23f1ce17de
13 changed files with 5661 additions and 78 deletions

View File

@ -0,0 +1,128 @@
CREATE TABLE "user_temp" (
"id" text PRIMARY KEY NOT NULL,
"name" text DEFAULT '' NOT NULL,
"token" text NOT NULL,
"isRegistered" boolean DEFAULT false NOT NULL,
"expirationDate" text NOT NULL,
"createdAt" text NOT NULL,
"canCreateProjects" boolean DEFAULT false NOT NULL,
"canAccessToSSHKeys" boolean DEFAULT false NOT NULL,
"canCreateServices" boolean DEFAULT false NOT NULL,
"canDeleteProjects" boolean DEFAULT false NOT NULL,
"canDeleteServices" boolean DEFAULT false NOT NULL,
"canAccessToDocker" boolean DEFAULT false NOT NULL,
"canAccessToAPI" boolean DEFAULT false NOT NULL,
"canAccessToGitProviders" boolean DEFAULT false NOT NULL,
"canAccessToTraefikFiles" boolean DEFAULT false NOT NULL,
"accesedProjects" text[] DEFAULT ARRAY[]::text[] NOT NULL,
"accesedServices" text[] DEFAULT ARRAY[]::text[] NOT NULL,
"email" text NOT NULL,
"email_verified" boolean NOT NULL,
"image" text,
"role" text,
"banned" boolean,
"ban_reason" text,
"ban_expires" timestamp,
"updated_at" timestamp NOT NULL,
"serverIp" text,
"certificateType" "certificateType" DEFAULT 'none' NOT NULL,
"host" text,
"letsEncryptEmail" text,
"sshPrivateKey" text,
"enableDockerCleanup" boolean DEFAULT false NOT NULL,
"enableLogRotation" boolean DEFAULT false NOT NULL,
"enablePaidFeatures" boolean DEFAULT false NOT NULL,
"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,
"cleanupCacheApplications" boolean DEFAULT false NOT NULL,
"cleanupCacheOnPreviews" boolean DEFAULT false NOT NULL,
"cleanupCacheOnCompose" boolean DEFAULT false NOT NULL,
"stripeCustomerId" text,
"stripeSubscriptionId" text,
"serversQuantity" integer DEFAULT 0 NOT NULL,
CONSTRAINT "user_temp_email_unique" UNIQUE("email")
);
--> statement-breakpoint
CREATE TABLE "session_temp" (
"id" text PRIMARY KEY NOT NULL,
"expires_at" timestamp NOT NULL,
"token" text NOT NULL,
"created_at" timestamp NOT NULL,
"updated_at" timestamp NOT NULL,
"ip_address" text,
"user_agent" text,
"user_id" text NOT NULL,
"impersonated_by" text,
"active_organization_id" text,
CONSTRAINT "session_temp_token_unique" UNIQUE("token")
);
--> statement-breakpoint
CREATE TABLE "account" (
"id" text PRIMARY KEY NOT NULL,
"account_id" text NOT NULL,
"provider_id" text NOT NULL,
"user_id" text NOT NULL,
"access_token" text,
"refresh_token" text,
"id_token" text,
"access_token_expires_at" timestamp,
"refresh_token_expires_at" timestamp,
"scope" text,
"password" text,
"is2FAEnabled" boolean DEFAULT false NOT NULL,
"created_at" timestamp NOT NULL,
"updated_at" timestamp NOT NULL,
"resetPasswordToken" text,
"resetPasswordExpiresAt" text,
"confirmationToken" text,
"confirmationExpiresAt" text
);
--> statement-breakpoint
CREATE TABLE "invitation" (
"id" text PRIMARY KEY NOT NULL,
"organization_id" text NOT NULL,
"email" text NOT NULL,
"role" text,
"status" text NOT NULL,
"expires_at" timestamp NOT NULL,
"inviter_id" text NOT NULL
);
--> statement-breakpoint
CREATE TABLE "member" (
"id" text PRIMARY KEY NOT NULL,
"organization_id" text NOT NULL,
"user_id" text NOT NULL,
"role" text NOT NULL,
"created_at" timestamp NOT NULL
);
--> statement-breakpoint
CREATE TABLE "organization" (
"id" text PRIMARY KEY NOT NULL,
"name" text NOT NULL,
"slug" text,
"logo" text,
"created_at" timestamp NOT NULL,
"metadata" text,
"owner_id" text NOT NULL,
CONSTRAINT "organization_slug_unique" UNIQUE("slug")
);
--> statement-breakpoint
CREATE TABLE "verification" (
"id" text PRIMARY KEY NOT NULL,
"identifier" text NOT NULL,
"value" text NOT NULL,
"expires_at" timestamp NOT NULL,
"created_at" timestamp,
"updated_at" timestamp
);
--> statement-breakpoint
ALTER TABLE "certificate" ALTER COLUMN "adminId" SET NOT NULL;--> statement-breakpoint
ALTER TABLE "notification" ALTER COLUMN "adminId" SET NOT NULL;--> statement-breakpoint
ALTER TABLE "ssh-key" ALTER COLUMN "adminId" SET NOT NULL;--> statement-breakpoint
ALTER TABLE "git_provider" ALTER COLUMN "adminId" SET NOT NULL;--> statement-breakpoint
ALTER TABLE "session_temp" ADD CONSTRAINT "session_temp_user_id_user_temp_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."user_temp"("id") ON DELETE no action ON UPDATE no action;--> statement-breakpoint
ALTER TABLE "account" ADD CONSTRAINT "account_user_id_user_temp_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."user_temp"("id") ON DELETE no action ON UPDATE no action;--> statement-breakpoint
ALTER TABLE "invitation" ADD CONSTRAINT "invitation_organization_id_organization_id_fk" FOREIGN KEY ("organization_id") REFERENCES "public"."organization"("id") ON DELETE no action ON UPDATE no action;--> statement-breakpoint
ALTER TABLE "invitation" ADD CONSTRAINT "invitation_inviter_id_user_temp_id_fk" FOREIGN KEY ("inviter_id") REFERENCES "public"."user_temp"("id") ON DELETE no action ON UPDATE no action;--> statement-breakpoint
ALTER TABLE "member" ADD CONSTRAINT "member_organization_id_organization_id_fk" FOREIGN KEY ("organization_id") REFERENCES "public"."organization"("id") ON DELETE no action ON UPDATE no action;--> statement-breakpoint
ALTER TABLE "member" ADD CONSTRAINT "member_user_id_user_temp_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."user_temp"("id") ON DELETE no action ON UPDATE no action;--> statement-breakpoint
ALTER TABLE "organization" ADD CONSTRAINT "organization_owner_id_user_temp_id_fk" FOREIGN KEY ("owner_id") REFERENCES "public"."user_temp"("id") ON DELETE no action ON UPDATE no action;

View File

@ -0,0 +1,170 @@
-- Custom SQL migration file, put your code below! --
WITH inserted_users AS (
-- Insertar usuarios desde admins
INSERT INTO user_temp (
id,
email,
token,
"email_verified",
"updated_at",
role,
"serverIp",
image,
"certificateType",
host,
"letsEncryptEmail",
"sshPrivateKey",
"enableDockerCleanup",
"enableLogRotation",
"enablePaidFeatures",
"metricsConfig",
"cleanupCacheApplications",
"cleanupCacheOnPreviews",
"cleanupCacheOnCompose",
"stripeCustomerId",
"stripeSubscriptionId",
"serversQuantity",
"expirationDate",
"createdAt"
)
SELECT
a."adminId",
auth.email,
COALESCE(auth.token, ''),
true,
CURRENT_TIMESTAMP,
'admin',
a."serverIp",
auth.image,
a."certificateType",
a.host,
a."letsEncryptEmail",
a."sshPrivateKey",
a."enableDockerCleanup",
a."enableLogRotation",
a."enablePaidFeatures",
a."metricsConfig",
a."cleanupCacheApplications",
a."cleanupCacheOnPreviews",
a."cleanupCacheOnCompose",
a."stripeCustomerId",
a."stripeSubscriptionId",
a."serversQuantity",
NOW() + INTERVAL '1 year',
NOW()
FROM admin a
JOIN auth ON auth.id = a."authId"
RETURNING *
),
inserted_accounts AS (
-- Insertar cuentas para los admins
INSERT INTO account (
id,
"account_id",
"provider_id",
"user_id",
password,
"is2FAEnabled",
"created_at",
"updated_at"
)
SELECT
gen_random_uuid(),
gen_random_uuid(),
'credentials',
a."adminId",
auth.password,
COALESCE(auth."is2FAEnabled", false),
NOW(),
NOW()
FROM admin a
JOIN auth ON auth.id = a."authId"
RETURNING *
),
inserted_orgs AS (
-- Crear organizaciones para cada admin
INSERT INTO organization (
id,
name,
slug,
"owner_id",
"created_at"
)
SELECT
gen_random_uuid(),
'My Organization',
-- Generamos un slug único usando una función de hash
encode(sha256((a."adminId" || CURRENT_TIMESTAMP)::bytea), 'hex'),
a."adminId",
NOW()
FROM admin a
RETURNING *
),
inserted_members AS (
-- Insertar usuarios miembros
INSERT INTO user_temp (
id,
email,
token,
"email_verified",
"updated_at",
role,
image,
"createdAt",
"canAccessToAPI",
"canAccessToDocker",
"canAccessToGitProviders",
"canAccessToSSHKeys",
"canAccessToTraefikFiles",
"canCreateProjects",
"canCreateServices",
"canDeleteProjects",
"canDeleteServices",
"accesedProjects",
"accesedServices",
"expirationDate"
)
SELECT
u."userId",
auth.email,
COALESCE(u.token, ''),
true,
CURRENT_TIMESTAMP,
'user',
auth.image,
NOW(),
COALESCE(u."canAccessToAPI", false),
COALESCE(u."canAccessToDocker", false),
COALESCE(u."canAccessToGitProviders", false),
COALESCE(u."canAccessToSSHKeys", false),
COALESCE(u."canAccessToTraefikFiles", false),
COALESCE(u."canCreateProjects", false),
COALESCE(u."canCreateServices", false),
COALESCE(u."canDeleteProjects", false),
COALESCE(u."canDeleteServices", false),
COALESCE(u."accesedProjects", '{}'),
COALESCE(u."accesedServices", '{}'),
NOW() + INTERVAL '1 year'
FROM "user" u
JOIN admin a ON u."adminId" = a."adminId"
JOIN auth ON auth.id = u."authId"
RETURNING *
)
-- Insertar miembros en las organizaciones
INSERT INTO member (
id,
"organization_id",
"user_id",
role,
"created_at"
)
SELECT
gen_random_uuid(),
o.id,
u."userId",
'admin',
NOW()
FROM "user" u
JOIN admin a ON u."adminId" = a."adminId"
JOIN inserted_orgs o ON o."owner_id" = a."adminId";

View File

@ -1,5 +1,5 @@
{
"id": "de382c48-6f10-4578-a307-884fecb4baa3",
"id": "67140673-fcd1-4c33-8dd1-bb7a34bdae23",
"prevId": "1240ec96-1751-4de3-b64f-cef9cb716786",
"version": "7",
"dialect": "postgresql",
@ -1449,8 +1449,8 @@
"primaryKey": false,
"notNull": true
},
"userId": {
"name": "userId",
"adminId": {
"name": "adminId",
"type": "text",
"primaryKey": false,
"notNull": true
@ -1465,15 +1465,15 @@
},
"indexes": {},
"foreignKeys": {
"project_userId_user_temp_id_fk": {
"name": "project_userId_user_temp_id_fk",
"project_adminId_admin_adminId_fk": {
"name": "project_adminId_admin_adminId_fk",
"tableFrom": "project",
"tableTo": "user_temp",
"tableTo": "admin",
"columnsFrom": [
"userId"
"adminId"
],
"columnsTo": [
"id"
"adminId"
],
"onDelete": "cascade",
"onUpdate": "no action"
@ -2326,8 +2326,8 @@
"primaryKey": false,
"notNull": true
},
"userId": {
"name": "userId",
"adminId": {
"name": "adminId",
"type": "text",
"primaryKey": false,
"notNull": true
@ -2335,15 +2335,15 @@
},
"indexes": {},
"foreignKeys": {
"destination_userId_user_temp_id_fk": {
"name": "destination_userId_user_temp_id_fk",
"destination_adminId_admin_adminId_fk": {
"name": "destination_adminId_admin_adminId_fk",
"tableFrom": "destination",
"tableTo": "user_temp",
"tableTo": "admin",
"columnsFrom": [
"userId"
"adminId"
],
"columnsTo": [
"id"
"adminId"
],
"onDelete": "cascade",
"onUpdate": "no action"
@ -2734,8 +2734,8 @@
"primaryKey": false,
"notNull": false
},
"userId": {
"name": "userId",
"adminId": {
"name": "adminId",
"type": "text",
"primaryKey": false,
"notNull": true
@ -2749,15 +2749,15 @@
},
"indexes": {},
"foreignKeys": {
"certificate_userId_user_temp_id_fk": {
"name": "certificate_userId_user_temp_id_fk",
"certificate_adminId_admin_adminId_fk": {
"name": "certificate_adminId_admin_adminId_fk",
"tableFrom": "certificate",
"tableTo": "user_temp",
"tableTo": "admin",
"columnsFrom": [
"userId"
"adminId"
],
"columnsTo": [
"id"
"adminId"
],
"onDelete": "cascade",
"onUpdate": "no action"
@ -3651,8 +3651,8 @@
"notNull": true,
"default": "'cloud'"
},
"userId": {
"name": "userId",
"adminId": {
"name": "adminId",
"type": "text",
"primaryKey": false,
"notNull": true
@ -3660,15 +3660,15 @@
},
"indexes": {},
"foreignKeys": {
"registry_userId_user_temp_id_fk": {
"name": "registry_userId_user_temp_id_fk",
"registry_adminId_admin_adminId_fk": {
"name": "registry_adminId_admin_adminId_fk",
"tableFrom": "registry",
"tableTo": "user_temp",
"tableTo": "admin",
"columnsFrom": [
"userId"
"adminId"
],
"columnsTo": [
"id"
"adminId"
],
"onDelete": "cascade",
"onUpdate": "no action"
@ -3911,8 +3911,8 @@
"primaryKey": false,
"notNull": false
},
"userId": {
"name": "userId",
"adminId": {
"name": "adminId",
"type": "text",
"primaryKey": false,
"notNull": true
@ -3985,15 +3985,15 @@
"onDelete": "cascade",
"onUpdate": "no action"
},
"notification_userId_user_temp_id_fk": {
"name": "notification_userId_user_temp_id_fk",
"notification_adminId_admin_adminId_fk": {
"name": "notification_adminId_admin_adminId_fk",
"tableFrom": "notification",
"tableTo": "user_temp",
"tableTo": "admin",
"columnsFrom": [
"userId"
"adminId"
],
"columnsTo": [
"id"
"adminId"
],
"onDelete": "cascade",
"onUpdate": "no action"
@ -4173,8 +4173,8 @@
"primaryKey": false,
"notNull": true
},
"userId": {
"name": "userId",
"adminId": {
"name": "adminId",
"type": "text",
"primaryKey": false,
"notNull": true
@ -4182,15 +4182,15 @@
},
"indexes": {},
"foreignKeys": {
"git_provider_userId_user_temp_id_fk": {
"name": "git_provider_userId_user_temp_id_fk",
"git_provider_adminId_admin_adminId_fk": {
"name": "git_provider_adminId_admin_adminId_fk",
"tableFrom": "git_provider",
"tableTo": "user_temp",
"tableTo": "admin",
"columnsFrom": [
"userId"
"adminId"
],
"columnsTo": [
"id"
"adminId"
],
"onDelete": "cascade",
"onUpdate": "no action"
@ -4488,8 +4488,8 @@
"primaryKey": false,
"notNull": true
},
"userId": {
"name": "userId",
"adminId": {
"name": "adminId",
"type": "text",
"primaryKey": false,
"notNull": true
@ -4525,15 +4525,15 @@
},
"indexes": {},
"foreignKeys": {
"server_userId_user_temp_id_fk": {
"name": "server_userId_user_temp_id_fk",
"server_adminId_admin_adminId_fk": {
"name": "server_adminId_admin_adminId_fk",
"tableFrom": "server",
"tableTo": "user_temp",
"tableTo": "admin",
"columnsFrom": [
"userId"
"adminId"
],
"columnsTo": [
"id"
"adminId"
],
"onDelete": "cascade",
"onUpdate": "no action"

File diff suppressed because it is too large Load Diff

View File

@ -467,8 +467,15 @@
{
"idx": 66,
"version": "7",
"when": 1739425241338,
"tag": "0066_rapid_morbius",
"when": 1739426913392,
"tag": "0066_yielding_echo",
"breakpoints": true
},
{
"idx": 67,
"version": "7",
"when": 1739427057545,
"tag": "0067_migrate-data",
"breakpoints": true
}
]

View File

@ -25,9 +25,9 @@ export const certificates = pgTable("certificate", {
// userId: text("userId").references(() => user.userId, {
// onDelete: "cascade",
// }),
userId: text("userId")
adminId: text("adminId")
.notNull()
.references(() => users_temp.id, { onDelete: "cascade" }),
.references(() => admins.adminId, { onDelete: "cascade" }),
serverId: text("serverId").references(() => server.serverId, {
onDelete: "cascade",
}),
@ -40,10 +40,10 @@ export const certificatesRelations = relations(
fields: [certificates.serverId],
references: [server.serverId],
}),
// user: one(user, {
// fields: [certificates.userId],
// references: [user.id],
// }),
admin: one(admins, {
fields: [certificates.adminId],
references: [admins.adminId],
}),
}),
);

View File

@ -24,9 +24,9 @@ export const destinations = pgTable("destination", {
// userId: text("userId")
// .notNull()
// .references(() => user.userId, { onDelete: "cascade" }),
userId: text("userId")
adminId: text("adminId")
.notNull()
.references(() => users_temp.id, { onDelete: "cascade" }),
.references(() => admins.adminId, { onDelete: "cascade" }),
});
export const destinationsRelations = relations(

View File

@ -29,9 +29,9 @@ export const gitProvider = pgTable("git_provider", {
// userId: text("userId").references(() => user.userId, {
// onDelete: "cascade",
// }),
userId: text("userId")
adminId: text("adminId")
.notNull()
.references(() => users_temp.id, { onDelete: "cascade" }),
.references(() => admins.adminId, { onDelete: "cascade" }),
});
export const gitProviderRelations = relations(gitProvider, ({ one, many }) => ({
@ -47,10 +47,10 @@ export const gitProviderRelations = relations(gitProvider, ({ one, many }) => ({
fields: [gitProvider.gitProviderId],
references: [bitbucket.gitProviderId],
}),
// user: one(user, {
// fields: [gitProvider.userId],
// references: [user.id],
// }),
admin: one(admins, {
fields: [gitProvider.adminId],
references: [admins.adminId],
}),
}));
const createSchema = createInsertSchema(gitProvider);

View File

@ -49,9 +49,9 @@ export const notifications = pgTable("notification", {
// userId: text("userId").references(() => user.userId, {
// onDelete: "cascade",
// }),
userId: text("userId")
adminId: text("adminId")
.notNull()
.references(() => users_temp.id, { onDelete: "cascade" }),
.references(() => admins.adminId, { onDelete: "cascade" }),
});
export const slack = pgTable("slack", {
@ -126,10 +126,10 @@ export const notificationsRelations = relations(notifications, ({ one }) => ({
fields: [notifications.gotifyId],
references: [gotify.gotifyId],
}),
// user: one(user, {
// fields: [notifications.userId],
// references: [user.id],
// }),
admin: one(admins, {
fields: [notifications.adminId],
references: [admins.adminId],
}),
}));
export const notificationsSchema = createInsertSchema(notifications);

View File

@ -28,9 +28,9 @@ export const projects = pgTable("project", {
// userId: text("userId")
// .notNull()
// .references(() => user.userId, { onDelete: "cascade" }),
userId: text("userId")
adminId: text("adminId")
.notNull()
.references(() => users_temp.id, { onDelete: "cascade" }),
.references(() => admins.adminId, { onDelete: "cascade" }),
env: text("env").notNull().default(""),
});

View File

@ -32,9 +32,9 @@ export const registry = pgTable("registry", {
// userId: text("userId")
// .notNull()
// .references(() => user.userId, { onDelete: "cascade" }),
userId: text("userId")
adminId: text("adminId")
.notNull()
.references(() => users_temp.id, { onDelete: "cascade" }),
.references(() => admins.adminId, { onDelete: "cascade" }),
});
export const registryRelations = relations(registry, ({ one, many }) => ({

View File

@ -47,9 +47,9 @@ export const server = pgTable("server", {
// userId: text("userId")
// .notNull()
// .references(() => user.userId, { onDelete: "cascade" }),
userId: text("userId")
adminId: text("adminId")
.notNull()
.references(() => users_temp.id, { onDelete: "cascade" }),
.references(() => admins.adminId, { onDelete: "cascade" }),
serverStatus: serverStatus("serverStatus").notNull().default("active"),
command: text("command").notNull().default(""),
sshKeyId: text("sshKeyId").references(() => sshKeys.sshKeyId, {