refactor: add migration

This commit is contained in:
Mauricio Siu
2025-02-10 00:39:46 -06:00
parent 1db6ba94f4
commit b7112b89fd
10 changed files with 6227 additions and 12 deletions

View File

@@ -0,0 +1,367 @@
-- Primero ejecutar todas las modificaciones estructurales
ALTER TABLE "user" RENAME COLUMN "userId" TO "id";
--> statement-breakpoint
ALTER TABLE "project" RENAME COLUMN "adminId" TO "userId";
--> statement-breakpoint
ALTER TABLE "destination" RENAME COLUMN "adminId" TO "userId";
--> statement-breakpoint
ALTER TABLE "certificate" RENAME COLUMN "adminId" TO "userId";
--> statement-breakpoint
ALTER TABLE "registry" RENAME COLUMN "adminId" TO "userId";
--> statement-breakpoint
ALTER TABLE "notification" RENAME COLUMN "adminId" TO "userId";
--> statement-breakpoint
ALTER TABLE "ssh-key" RENAME COLUMN "adminId" TO "userId";
--> statement-breakpoint
ALTER TABLE "git_provider" RENAME COLUMN "adminId" TO "userId";
--> statement-breakpoint
ALTER TABLE "server" RENAME COLUMN "adminId" TO "userId";
--> statement-breakpoint
ALTER TABLE "user" DROP CONSTRAINT "user_adminId_admin_adminId_fk";
--> statement-breakpoint
ALTER TABLE "user" DROP CONSTRAINT "user_authId_auth_id_fk";
--> statement-breakpoint
ALTER TABLE "admin" DROP CONSTRAINT "admin_authId_auth_id_fk";
--> statement-breakpoint
ALTER TABLE "project" DROP CONSTRAINT "project_adminId_admin_adminId_fk";
--> statement-breakpoint
ALTER TABLE "destination" DROP CONSTRAINT "destination_adminId_admin_adminId_fk";
--> statement-breakpoint
ALTER TABLE "certificate" DROP CONSTRAINT "certificate_adminId_admin_adminId_fk";
--> statement-breakpoint
ALTER TABLE "session" DROP CONSTRAINT "session_user_id_auth_id_fk";
--> statement-breakpoint
ALTER TABLE "registry" DROP CONSTRAINT "registry_adminId_admin_adminId_fk";
--> statement-breakpoint
ALTER TABLE "notification" DROP CONSTRAINT "notification_adminId_admin_adminId_fk";
--> statement-breakpoint
ALTER TABLE "ssh-key" DROP CONSTRAINT "ssh-key_adminId_admin_adminId_fk";
--> statement-breakpoint
ALTER TABLE "git_provider" DROP CONSTRAINT "git_provider_adminId_admin_adminId_fk";
--> statement-breakpoint
ALTER TABLE "server" DROP CONSTRAINT "server_adminId_admin_adminId_fk";
--> statement-breakpoint
ALTER TABLE "user" ALTER COLUMN "expirationDate" SET DATA TYPE text;
--> statement-breakpoint
ALTER TABLE "session" ALTER COLUMN "expires_at" SET DATA TYPE timestamp;
--> statement-breakpoint
ALTER TABLE "user" ADD COLUMN "name" text DEFAULT '' NOT NULL;
--> statement-breakpoint
ALTER TABLE "user" ADD COLUMN "email" text NOT NULL;
--> statement-breakpoint
ALTER TABLE "user" ADD COLUMN "email_verified" boolean NOT NULL;
--> statement-breakpoint
ALTER TABLE "user" ADD COLUMN "image" text;
--> statement-breakpoint
ALTER TABLE "user" ADD COLUMN "role" text;
--> statement-breakpoint
ALTER TABLE "user" ADD COLUMN "banned" boolean;
--> statement-breakpoint
ALTER TABLE "user" ADD COLUMN "ban_reason" text;
--> statement-breakpoint
ALTER TABLE "user" ADD COLUMN "ban_expires" timestamp;
--> statement-breakpoint
ALTER TABLE "user" ADD COLUMN "updated_at" timestamp NOT NULL;
--> statement-breakpoint
ALTER TABLE "user" ADD COLUMN "serverIp" text;
--> statement-breakpoint
ALTER TABLE "user" ADD COLUMN "certificateType" "certificateType" DEFAULT 'none' NOT NULL;
--> statement-breakpoint
ALTER TABLE "user" ADD COLUMN "host" text;
--> statement-breakpoint
ALTER TABLE "user" ADD COLUMN "letsEncryptEmail" text;
--> statement-breakpoint
ALTER TABLE "user" ADD COLUMN "sshPrivateKey" text;
--> statement-breakpoint
ALTER TABLE "user" ADD COLUMN "enableDockerCleanup" boolean DEFAULT false NOT NULL;
--> statement-breakpoint
ALTER TABLE "user" ADD COLUMN "enableLogRotation" boolean DEFAULT false NOT NULL;
--> statement-breakpoint
ALTER TABLE "user" ADD COLUMN "enablePaidFeatures" boolean DEFAULT false NOT NULL;
--> statement-breakpoint
ALTER TABLE "user" ADD COLUMN "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;
--> statement-breakpoint
ALTER TABLE "user" ADD COLUMN "cleanupCacheApplications" boolean DEFAULT false NOT NULL;
--> statement-breakpoint
ALTER TABLE "user" ADD COLUMN "cleanupCacheOnPreviews" boolean DEFAULT false NOT NULL;
--> statement-breakpoint
ALTER TABLE "user" ADD COLUMN "cleanupCacheOnCompose" boolean DEFAULT false NOT NULL;
--> statement-breakpoint
ALTER TABLE "user" ADD COLUMN "stripeCustomerId" text;
--> statement-breakpoint
ALTER TABLE "user" ADD COLUMN "stripeSubscriptionId" text;
--> statement-breakpoint
ALTER TABLE "user" ADD COLUMN "serversQuantity" integer DEFAULT 0 NOT NULL;
--> statement-breakpoint
ALTER TABLE "session" ADD COLUMN "token" text NOT NULL;
--> statement-breakpoint
ALTER TABLE "session" ADD COLUMN "created_at" timestamp NOT NULL;
--> statement-breakpoint
ALTER TABLE "session" ADD COLUMN "updated_at" timestamp NOT NULL;
--> statement-breakpoint
ALTER TABLE "session" ADD COLUMN "ip_address" text;
--> statement-breakpoint
ALTER TABLE "session" ADD COLUMN "user_agent" text;
--> statement-breakpoint
ALTER TABLE "session" ADD COLUMN "impersonated_by" text;
--> statement-breakpoint
ALTER TABLE "session" ADD COLUMN "active_organization_id" text;
--> 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 "account" ADD CONSTRAINT "account_user_id_user_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."user"("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_id_fk" FOREIGN KEY ("inviter_id") REFERENCES "public"."user"("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_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."user"("id") ON DELETE no action ON UPDATE no action;
--> statement-breakpoint
ALTER TABLE "organization" ADD CONSTRAINT "organization_owner_id_user_id_fk" FOREIGN KEY ("owner_id") REFERENCES "public"."user"("id") ON DELETE no action ON UPDATE no action;
--> statement-breakpoint
ALTER TABLE "project" ADD CONSTRAINT "project_userId_user_id_fk" FOREIGN KEY ("userId") REFERENCES "public"."user"("id") ON DELETE cascade ON UPDATE no action;
--> statement-breakpoint
ALTER TABLE "destination" ADD CONSTRAINT "destination_userId_user_id_fk" FOREIGN KEY ("userId") REFERENCES "public"."user"("id") ON DELETE cascade ON UPDATE no action;
--> statement-breakpoint
ALTER TABLE "certificate" ADD CONSTRAINT "certificate_userId_user_id_fk" FOREIGN KEY ("userId") REFERENCES "public"."user"("id") ON DELETE cascade ON UPDATE no action;
--> statement-breakpoint
ALTER TABLE "session" ADD CONSTRAINT "session_user_id_user_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."user"("id") ON DELETE no action ON UPDATE no action;
--> statement-breakpoint
ALTER TABLE "registry" ADD CONSTRAINT "registry_userId_user_id_fk" FOREIGN KEY ("userId") REFERENCES "public"."user"("id") ON DELETE cascade ON UPDATE no action;
--> statement-breakpoint
ALTER TABLE "notification" ADD CONSTRAINT "notification_userId_user_id_fk" FOREIGN KEY ("userId") REFERENCES "public"."user"("id") ON DELETE cascade ON UPDATE no action;
--> statement-breakpoint
ALTER TABLE "ssh-key" ADD CONSTRAINT "ssh-key_userId_user_id_fk" FOREIGN KEY ("userId") REFERENCES "public"."user"("id") ON DELETE cascade ON UPDATE no action;
--> statement-breakpoint
ALTER TABLE "git_provider" ADD CONSTRAINT "git_provider_userId_user_id_fk" FOREIGN KEY ("userId") REFERENCES "public"."user"("id") ON DELETE cascade ON UPDATE no action;
--> statement-breakpoint
ALTER TABLE "server" ADD CONSTRAINT "server_userId_user_id_fk" FOREIGN KEY ("userId") REFERENCES "public"."user"("id") ON DELETE cascade ON UPDATE no action;
--> statement-breakpoint
ALTER TABLE "user" DROP COLUMN "adminId";
--> statement-breakpoint
ALTER TABLE "user" DROP COLUMN "authId";
--> statement-breakpoint
ALTER TABLE "admin" DROP COLUMN "adminId";
--> statement-breakpoint
ALTER TABLE "admin" DROP COLUMN "serverIp";
--> statement-breakpoint
ALTER TABLE "admin" DROP COLUMN "certificateType";
--> statement-breakpoint
ALTER TABLE "admin" DROP COLUMN "host";
--> statement-breakpoint
ALTER TABLE "admin" DROP COLUMN "letsEncryptEmail";
--> statement-breakpoint
ALTER TABLE "admin" DROP COLUMN "sshPrivateKey";
--> statement-breakpoint
ALTER TABLE "admin" DROP COLUMN "enableDockerCleanup";
--> statement-breakpoint
ALTER TABLE "admin" DROP COLUMN "enableLogRotation";
--> statement-breakpoint
ALTER TABLE "admin" DROP COLUMN "authId";
--> statement-breakpoint
ALTER TABLE "admin" DROP COLUMN "createdAt";
--> statement-breakpoint
ALTER TABLE "admin" DROP COLUMN "stripeCustomerId";
--> statement-breakpoint
ALTER TABLE "admin" DROP COLUMN "stripeSubscriptionId";
--> statement-breakpoint
ALTER TABLE "admin" DROP COLUMN "serversQuantity";
--> statement-breakpoint
ALTER TABLE "admin" DROP COLUMN "enablePaidFeatures";
--> statement-breakpoint
ALTER TABLE "admin" DROP COLUMN "metricsConfig";
--> statement-breakpoint
ALTER TABLE "admin" DROP COLUMN "cleanupCacheApplications";
--> statement-breakpoint
ALTER TABLE "admin" DROP COLUMN "cleanupCacheOnPreviews";
--> statement-breakpoint
ALTER TABLE "admin" DROP COLUMN "cleanupCacheOnCompose";
--> statement-breakpoint
ALTER TABLE "user" ADD CONSTRAINT "user_email_unique" UNIQUE("email");
--> statement-breakpoint
-- Primero quitar NOT NULL temporalmente
ALTER TABLE "session" ALTER COLUMN "token" DROP NOT NULL;
--> statement-breakpoint
-- Actualizar tokens existentes
UPDATE "session" SET
token = gen_random_uuid(),
created_at = COALESCE(created_at, NOW() - interval '1 day'),
updated_at = NOW()
WHERE token IS NULL;
-- Restablecer restricciones
ALTER TABLE "session" ALTER COLUMN "token" SET NOT NULL;
ALTER TABLE "session" ADD CONSTRAINT "session_token_unique" UNIQUE (token);
-- Luego realizar la migración de datos
-- Migración de datos para Admins
WITH admin_users AS (
INSERT INTO "user" (
id, created_at, token, email, email_verified, role, updated_at,
certificate_type, server_ip, host, lets_encrypt_email, ssh_private_key,
enable_docker_cleanup, enable_log_rotation, enable_paid_features,
metrics_config, cleanup_cache_applications, cleanup_cache_on_previews,
cleanup_cache_on_compose, stripe_customer_id, stripe_subscription_id,
servers_quantity
)
SELECT
gen_random_uuid(),
a.created_at,
a.token,
a.email,
true,
'admin',
a.created_at,
ad.certificate_type,
ad.server_ip,
ad.host,
ad.lets_encrypt_email,
ad.ssh_private_key,
ad.enable_docker_cleanup,
ad.enable_log_rotation,
ad.enable_paid_features,
ad.metrics_config,
ad.cleanup_cache_applications,
ad.cleanup_cache_on_previews,
ad.cleanup_cache_on_compose,
ad.stripe_customer_id,
ad.stripe_subscription_id,
ad.servers_quantity
FROM auth a
JOIN admins ad ON a.id = ad.auth_id
RETURNING id AS user_id, created_at, email
)
INSERT INTO account (id, account_id, provider_id, user_id, password, created_at, updated_at)
SELECT
gen_random_uuid(),
a.id,
'credentials',
au.user_id,
a.password,
au.created_at,
au.created_at
FROM auth a
JOIN admin_users au ON a.email = au.email;
-- Crear organizaciones para admins
WITH admin_orgs AS (
INSERT INTO organization (id, name, slug, created_at, owner_id)
SELECT
gen_random_uuid(),
'My Organization',
'org/' || au.user_id,
au.created_at,
au.user_id
FROM admin_users au
RETURNING id AS org_id, owner_id
)
-- Migrar usuarios regulares y asociar a organizaciones
INSERT INTO "user" (
id, created_at, token, email, email_verified, role, updated_at,
can_create_projects, can_access_ssh_keys
)
SELECT
gen_random_uuid(),
a.created_at,
a.token,
a.email,
true,
'user',
a.created_at,
u.can_create_projects,
u.can_access_ssh_keys
FROM auth a
JOIN users u ON a.id = u.auth_id
WHERE a.role = 'user';
-- Crear accounts para usuarios
INSERT INTO account (id, account_id, provider_id, user_id, password, created_at, updated_at)
SELECT
gen_random_uuid(),
a.id,
'credentials',
u.id,
a.password,
a.created_at,
a.created_at
FROM auth a
JOIN "user" u ON a.email = u.email;
-- Asociar usuarios a organizaciones de sus admins
INSERT INTO member (id, organization_id, user_id, role, created_at)
SELECT
gen_random_uuid(),
ao.org_id,
u.id,
'user',
u.created_at
FROM "user" u
JOIN users old_u ON u.email = old_u.email
JOIN auth a ON old_u.auth_id = a.id
JOIN admin_orgs ao ON ao.owner_id = a.id;
-- Eliminar tablas obsoletas
DROP TABLE IF EXISTS admins;
DROP TABLE IF EXISTS users;
DROP TABLE IF EXISTS auth;

File diff suppressed because it is too large Load Diff

View File

@@ -463,7 +463,13 @@
"when": 1739087857244,
"tag": "0065_daily_zaladane",
"breakpoints": true
},
{
"idx": 66,
"version": "7",
"when": 1739168611366,
"tag": "0066_calm_vengeance",
"breakpoints": true
}
]
}

View File

@@ -64,6 +64,9 @@ export const organization = pgTable("organization", {
logo: text("logo"),
createdAt: timestamp("created_at").notNull(),
metadata: text("metadata"),
ownerId: text("owner_id")
.notNull()
.references(() => user.id),
});
export const member = pgTable("member", {

View File

@@ -28,6 +28,7 @@
"typecheck": "tsc --noEmit"
},
"dependencies": {
"drizzle-dbml-generator":"0.10.0",
"better-auth":"1.1.16",
"rotating-file-stream": "3.2.3",
"@faker-js/faker": "^8.4.1",

View File

@@ -40,6 +40,9 @@ export const organization = pgTable("organization", {
logo: text("logo"),
createdAt: timestamp("created_at").notNull(),
metadata: text("metadata"),
ownerId: text("owner_id")
.notNull()
.references(() => user.id),
});
export const member = pgTable("member", {

View File

@@ -0,0 +1,7 @@
import { pgGenerate } from "drizzle-dbml-generator"; // Using Postgres for this example
import * as schema from "./index";
const out = "./schema.dbml";
const relational = true;
pgGenerate({ schema, out, relational });

View File

@@ -0,0 +1,872 @@
enum applicationStatus {
idle
running
done
error
}
enum buildType {
dockerfile
heroku_buildpacks
paketo_buildpacks
nixpacks
static
}
enum certificateType {
letsencrypt
none
}
enum composeType {
"docker-compose"
stack
}
enum databaseType {
postgres
mariadb
mysql
mongo
}
enum deploymentStatus {
running
done
error
}
enum domainType {
compose
application
preview
}
enum gitProviderType {
github
gitlab
bitbucket
}
enum mountType {
bind
volume
file
}
enum notificationType {
slack
telegram
discord
email
gotify
}
enum protocolType {
tcp
udp
}
enum RegistryType {
selfHosted
cloud
}
enum Roles {
admin
user
}
enum serverStatus {
active
inactive
}
enum serviceType {
application
postgres
mysql
mariadb
mongo
redis
compose
}
enum sourceType {
docker
git
github
gitlab
bitbucket
drop
}
enum sourceTypeCompose {
git
github
gitlab
bitbucket
raw
}
table account {
id text [pk, 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 [not null, default: false]
created_at timestamp [not null]
updated_at timestamp [not null]
resetPasswordToken text
resetPasswordExpiresAt text
confirmationToken text
confirmationExpiresAt text
}
table admin {
}
table application {
applicationId text [pk, not null]
name text [not null]
appName text [not null, unique]
description text
env text
previewEnv text
previewBuildArgs text
previewWildcard text
previewPort integer [default: 3000]
previewHttps boolean [not null, default: false]
previewPath text [default: '/']
certificateType certificateType [not null, default: 'none']
previewLimit integer [default: 3]
isPreviewDeploymentsActive boolean [default: false]
buildArgs text
memoryReservation text
memoryLimit text
cpuReservation text
cpuLimit text
title text
enabled boolean
subtitle text
command text
refreshToken text
sourceType sourceType [not null, default: 'github']
repository text
owner text
branch text
buildPath text [default: '/']
autoDeploy boolean
gitlabProjectId integer
gitlabRepository text
gitlabOwner text
gitlabBranch text
gitlabBuildPath text [default: '/']
gitlabPathNamespace text
bitbucketRepository text
bitbucketOwner text
bitbucketBranch text
bitbucketBuildPath text [default: '/']
username text
password text
dockerImage text
registryUrl text
customGitUrl text
customGitBranch text
customGitBuildPath text
customGitSSHKeyId text
dockerfile text
dockerContextPath text
dockerBuildStage text
dropBuildPath text
healthCheckSwarm json
restartPolicySwarm json
placementSwarm json
updateConfigSwarm json
rollbackConfigSwarm json
modeSwarm json
labelsSwarm json
networkSwarm json
replicas integer [not null, default: 1]
applicationStatus applicationStatus [not null, default: 'idle']
buildType buildType [not null, default: 'nixpacks']
herokuVersion text [default: '24']
publishDirectory text
createdAt text [not null]
registryId text
projectId text [not null]
githubId text
gitlabId text
bitbucketId text
serverId text
}
table auth {
id text [pk, not null]
email text [not null, unique]
password text [not null]
rol Roles [not null]
image text
secret text
token text
is2FAEnabled boolean [not null, default: false]
createdAt text [not null]
resetPasswordToken text
resetPasswordExpiresAt text
confirmationToken text
confirmationExpiresAt text
}
table backup {
backupId text [pk, not null]
schedule text [not null]
enabled boolean
database text [not null]
prefix text [not null]
destinationId text [not null]
databaseType databaseType [not null]
postgresId text
mariadbId text
mysqlId text
mongoId text
}
table bitbucket {
bitbucketId text [pk, not null]
bitbucketUsername text
appPassword text
bitbucketWorkspaceName text
gitProviderId text [not null]
}
table certificate {
certificateId text [pk, not null]
name text [not null]
certificateData text [not null]
privateKey text [not null]
certificatePath text [not null, unique]
autoRenew boolean
userId text
serverId text
}
table compose {
composeId text [pk, not null]
name text [not null]
appName text [not null]
description text
env text
composeFile text [not null, default: '']
refreshToken text
sourceType sourceTypeCompose [not null, default: 'github']
composeType composeType [not null, default: 'docker-compose']
repository text
owner text
branch text
autoDeploy boolean
gitlabProjectId integer
gitlabRepository text
gitlabOwner text
gitlabBranch text
gitlabPathNamespace text
bitbucketRepository text
bitbucketOwner text
bitbucketBranch text
customGitUrl text
customGitBranch text
customGitSSHKeyId text
command text [not null, default: '']
composePath text [not null, default: './docker-compose.yml']
suffix text [not null, default: '']
randomize boolean [not null, default: false]
isolatedDeployment boolean [not null, default: false]
composeStatus applicationStatus [not null, default: 'idle']
projectId text [not null]
createdAt text [not null]
githubId text
gitlabId text
bitbucketId text
serverId text
}
table deployment {
deploymentId text [pk, not null]
title text [not null]
description text
status deploymentStatus [default: 'running']
logPath text [not null]
applicationId text
composeId text
serverId text
isPreviewDeployment boolean [default: false]
previewDeploymentId text
createdAt text [not null]
errorMessage text
}
table destination {
destinationId text [pk, not null]
name text [not null]
provider text
accessKey text [not null]
secretAccessKey text [not null]
bucket text [not null]
region text [not null]
endpoint text [not null]
userId text [not null]
}
table discord {
discordId text [pk, not null]
webhookUrl text [not null]
decoration boolean
}
table domain {
domainId text [pk, not null]
host text [not null]
https boolean [not null, default: false]
port integer [default: 3000]
path text [default: '/']
serviceName text
domainType domainType [default: 'application']
uniqueConfigKey serial [not null, increment]
createdAt text [not null]
composeId text
applicationId text
previewDeploymentId text
certificateType certificateType [not null, default: 'none']
}
table email {
emailId text [pk, not null]
smtpServer text [not null]
smtpPort integer [not null]
username text [not null]
password text [not null]
fromAddress text [not null]
toAddress text[] [not null]
}
table git_provider {
gitProviderId text [pk, not null]
name text [not null]
providerType gitProviderType [not null, default: 'github']
createdAt text [not null]
userId text
}
table github {
githubId text [pk, not null]
githubAppName text
githubAppId integer
githubClientId text
githubClientSecret text
githubInstallationId text
githubPrivateKey text
githubWebhookSecret text
gitProviderId text [not null]
}
table gitlab {
gitlabId text [pk, not null]
gitlabUrl text [not null, default: 'https://gitlab.com']
application_id text
redirect_uri text
secret text
access_token text
refresh_token text
group_name text
expires_at integer
gitProviderId text [not null]
}
table gotify {
gotifyId text [pk, not null]
serverUrl text [not null]
appToken text [not null]
priority integer [not null, default: 5]
decoration boolean
}
table invitation {
id text [pk, 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]
}
table mariadb {
mariadbId text [pk, not null]
name text [not null]
appName text [not null, unique]
description text
databaseName text [not null]
databaseUser text [not null]
databasePassword text [not null]
rootPassword text [not null]
dockerImage text [not null]
command text
env text
memoryReservation text
memoryLimit text
cpuReservation text
cpuLimit text
externalPort integer
applicationStatus applicationStatus [not null, default: 'idle']
createdAt text [not null]
projectId text [not null]
serverId text
}
table member {
id text [pk, not null]
organization_id text [not null]
user_id text [not null]
role text [not null]
created_at timestamp [not null]
}
table mongo {
mongoId text [pk, not null]
name text [not null]
appName text [not null, unique]
description text
databaseUser text [not null]
databasePassword text [not null]
dockerImage text [not null]
command text
env text
memoryReservation text
memoryLimit text
cpuReservation text
cpuLimit text
externalPort integer
applicationStatus applicationStatus [not null, default: 'idle']
createdAt text [not null]
projectId text [not null]
serverId text
replicaSets boolean [default: false]
}
table mount {
mountId text [pk, not null]
type mountType [not null]
hostPath text
volumeName text
filePath text
content text
serviceType serviceType [not null, default: 'application']
mountPath text [not null]
applicationId text
postgresId text
mariadbId text
mongoId text
mysqlId text
redisId text
composeId text
}
table mysql {
mysqlId text [pk, not null]
name text [not null]
appName text [not null, unique]
description text
databaseName text [not null]
databaseUser text [not null]
databasePassword text [not null]
rootPassword text [not null]
dockerImage text [not null]
command text
env text
memoryReservation text
memoryLimit text
cpuReservation text
cpuLimit text
externalPort integer
applicationStatus applicationStatus [not null, default: 'idle']
createdAt text [not null]
projectId text [not null]
serverId text
}
table notification {
notificationId text [pk, not null]
name text [not null]
appDeploy boolean [not null, default: false]
appBuildError boolean [not null, default: false]
databaseBackup boolean [not null, default: false]
dokployRestart boolean [not null, default: false]
dockerCleanup boolean [not null, default: false]
serverThreshold boolean [not null, default: false]
notificationType notificationType [not null]
createdAt text [not null]
slackId text
telegramId text
discordId text
emailId text
gotifyId text
userId text
}
table organization {
id text [pk, not null]
name text [not null]
slug text [unique]
logo text
created_at timestamp [not null]
metadata text
owner_id text [not null]
}
table port {
portId text [pk, not null]
publishedPort integer [not null]
targetPort integer [not null]
protocol protocolType [not null]
applicationId text [not null]
}
table postgres {
postgresId text [pk, not null]
name text [not null]
appName text [not null, unique]
databaseName text [not null]
databaseUser text [not null]
databasePassword text [not null]
description text
dockerImage text [not null]
command text
env text
memoryReservation text
externalPort integer
memoryLimit text
cpuReservation text
cpuLimit text
applicationStatus applicationStatus [not null, default: 'idle']
createdAt text [not null]
projectId text [not null]
serverId text
}
table preview_deployments {
previewDeploymentId text [pk, not null]
branch text [not null]
pullRequestId text [not null]
pullRequestNumber text [not null]
pullRequestURL text [not null]
pullRequestTitle text [not null]
pullRequestCommentId text [not null]
previewStatus applicationStatus [not null, default: 'idle']
appName text [not null, unique]
applicationId text [not null]
domainId text
createdAt text [not null]
expiresAt text
}
table project {
projectId text [pk, not null]
name text [not null]
description text
createdAt text [not null]
userId text [not null]
env text [not null, default: '']
}
table redirect {
redirectId text [pk, not null]
regex text [not null]
replacement text [not null]
permanent boolean [not null, default: false]
uniqueConfigKey serial [not null, increment]
createdAt text [not null]
applicationId text [not null]
}
table redis {
redisId text [pk, not null]
name text [not null]
appName text [not null, unique]
description text
password text [not null]
dockerImage text [not null]
command text
env text
memoryReservation text
memoryLimit text
cpuReservation text
cpuLimit text
externalPort integer
createdAt text [not null]
applicationStatus applicationStatus [not null, default: 'idle']
projectId text [not null]
serverId text
}
table registry {
registryId text [pk, not null]
registryName text [not null]
imagePrefix text
username text [not null]
password text [not null]
registryUrl text [not null, default: '']
createdAt text [not null]
selfHosted RegistryType [not null, default: 'cloud']
userId text [not null]
}
table security {
securityId text [pk, not null]
username text [not null]
password text [not null]
createdAt text [not null]
applicationId text [not null]
indexes {
(username, applicationId) [name: 'security_username_applicationId_unique', unique]
}
}
table server {
serverId text [pk, not null]
name text [not null]
description text
ipAddress text [not null]
port integer [not null]
username text [not null, default: 'root']
appName text [not null]
enableDockerCleanup boolean [not null, default: false]
createdAt text [not null]
userId text [not null]
serverStatus serverStatus [not null, default: 'active']
command text [not null, default: '']
sshKeyId text
metricsConfig jsonb [not null, default: `{"server":{"type":"Remote","refreshRate":60,"port":4500,"token":"","urlCallback":"","cronJob":"","retentionDays":2,"thresholds":{"cpu":0,"memory":0}},"containers":{"refreshRate":60,"services":{"include":[],"exclude":[]}}}`]
}
table session {
id text [pk, not null]
expires_at timestamp [not null]
token text [not null, unique]
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
}
table slack {
slackId text [pk, not null]
webhookUrl text [not null]
channel text
}
table "ssh-key" {
sshKeyId text [pk, not null]
privateKey text [not null, default: '']
publicKey text [not null]
name text [not null]
description text
createdAt text [not null]
lastUsedAt text
userId text
}
table telegram {
telegramId text [pk, not null]
botToken text [not null]
chatId text [not null]
}
table user {
id text [pk, not null]
name text [not null, default: '']
token text [not null]
isRegistered boolean [not null, default: false]
expirationDate text [not null]
createdAt text [not null]
canCreateProjects boolean [not null, default: false]
canAccessToSSHKeys boolean [not null, default: false]
canCreateServices boolean [not null, default: false]
canDeleteProjects boolean [not null, default: false]
canDeleteServices boolean [not null, default: false]
canAccessToDocker boolean [not null, default: false]
canAccessToAPI boolean [not null, default: false]
canAccessToGitProviders boolean [not null, default: false]
canAccessToTraefikFiles boolean [not null, default: false]
accesedProjects text[] [not null, default: `ARRAY[]::text[]`]
accesedServices text[] [not null, default: `ARRAY[]::text[]`]
email text [not null, unique]
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 [not null, default: 'none']
host text
letsEncryptEmail text
sshPrivateKey text
enableDockerCleanup boolean [not null, default: false]
enableLogRotation boolean [not null, default: false]
enablePaidFeatures boolean [not null, default: false]
metricsConfig jsonb [not null, default: `{"server":{"type":"Dokploy","refreshRate":60,"port":4500,"token":"","retentionDays":2,"cronJob":"","urlCallback":"","thresholds":{"cpu":0,"memory":0}},"containers":{"refreshRate":60,"services":{"include":[],"exclude":[]}}}`]
cleanupCacheApplications boolean [not null, default: false]
cleanupCacheOnPreviews boolean [not null, default: false]
cleanupCacheOnCompose boolean [not null, default: false]
stripeCustomerId text
stripeSubscriptionId text
serversQuantity integer [not null, default: 0]
}
table verification {
id text [pk, not null]
identifier text [not null]
value text [not null]
expires_at timestamp [not null]
created_at timestamp
updated_at timestamp
}
ref: mount.applicationId > application.applicationId
ref: mount.postgresId > postgres.postgresId
ref: mount.mariadbId > mariadb.mariadbId
ref: mount.mongoId > mongo.mongoId
ref: mount.mysqlId > mysql.mysqlId
ref: mount.redisId > redis.redisId
ref: mount.composeId > compose.composeId
ref: application.projectId > project.projectId
ref: application.customGitSSHKeyId > "ssh-key".sshKeyId
ref: application.registryId > registry.registryId
ref: application.githubId - github.githubId
ref: application.gitlabId - gitlab.gitlabId
ref: application.bitbucketId - bitbucket.bitbucketId
ref: application.serverId > server.serverId
ref: backup.destinationId > destination.destinationId
ref: backup.postgresId > postgres.postgresId
ref: backup.mariadbId > mariadb.mariadbId
ref: backup.mysqlId > mysql.mysqlId
ref: backup.mongoId > mongo.mongoId
ref: git_provider.gitProviderId - bitbucket.gitProviderId
ref: certificate.serverId > server.serverId
ref: certificate.userId - user.id
ref: compose.projectId > project.projectId
ref: compose.customGitSSHKeyId > "ssh-key".sshKeyId
ref: compose.githubId - github.githubId
ref: compose.gitlabId - gitlab.gitlabId
ref: compose.bitbucketId - bitbucket.bitbucketId
ref: compose.serverId > server.serverId
ref: deployment.applicationId > application.applicationId
ref: deployment.composeId > compose.composeId
ref: deployment.serverId > server.serverId
ref: deployment.previewDeploymentId > preview_deployments.previewDeploymentId
ref: destination.userId - user.id
ref: domain.applicationId > application.applicationId
ref: domain.composeId > compose.composeId
ref: preview_deployments.domainId - domain.domainId
ref: github.gitProviderId - git_provider.gitProviderId
ref: gitlab.gitProviderId - git_provider.gitProviderId
ref: git_provider.userId - user.id
ref: mariadb.projectId > project.projectId
ref: mariadb.serverId > server.serverId
ref: mongo.projectId > project.projectId
ref: mongo.serverId > server.serverId
ref: mysql.projectId > project.projectId
ref: mysql.serverId > server.serverId
ref: notification.slackId - slack.slackId
ref: notification.telegramId - telegram.telegramId
ref: notification.discordId - discord.discordId
ref: notification.emailId - email.emailId
ref: notification.gotifyId - gotify.gotifyId
ref: notification.userId - user.id
ref: port.applicationId > application.applicationId
ref: postgres.projectId > project.projectId
ref: postgres.serverId > server.serverId
ref: preview_deployments.applicationId > application.applicationId
ref: project.userId - user.id
ref: redirect.applicationId > application.applicationId
ref: redis.projectId > project.projectId
ref: redis.serverId > server.serverId
ref: registry.userId - user.id
ref: security.applicationId > application.applicationId
ref: server.userId - user.id
ref: server.sshKeyId > "ssh-key".sshKeyId
ref: "ssh-key".userId - user.id

View File

@@ -1,5 +1,12 @@
import { relations, sql } from "drizzle-orm";
import { boolean, jsonb, pgTable, text, timestamp } from "drizzle-orm/pg-core";
import {
boolean,
integer,
jsonb,
pgTable,
text,
timestamp,
} from "drizzle-orm/pg-core";
import { createInsertSchema } from "drizzle-zod";
import { nanoid } from "nanoid";
import { z } from "zod";
@@ -22,18 +29,12 @@ export const user = pgTable("user", {
name: text("name").notNull().default(""),
token: text("token").notNull(),
isRegistered: boolean("isRegistered").notNull().default(false),
expirationDate: timestamp("expirationDate", {
precision: 3,
mode: "date",
})
expirationDate: text("expirationDate")
.notNull()
.$defaultFn(() => new Date()),
createdAt: timestamp("createdAt", {
precision: 3,
mode: "date",
})
.$defaultFn(() => new Date().toISOString()),
createdAt: text("createdAt")
.notNull()
.$defaultFn(() => new Date()),
.$defaultFn(() => new Date().toISOString()),
canCreateProjects: boolean("canCreateProjects").notNull().default(false),
canAccessToSSHKeys: boolean("canAccessToSSHKeys").notNull().default(false),
canCreateServices: boolean("canCreateServices").notNull().default(false),
@@ -132,6 +133,9 @@ export const user = pgTable("user", {
cleanupCacheOnCompose: boolean("cleanupCacheOnCompose")
.notNull()
.default(false),
stripeCustomerId: text("stripeCustomerId"),
stripeSubscriptionId: text("stripeSubscriptionId"),
serversQuantity: integer("serversQuantity").notNull().default(0),
});
export const usersRelations = relations(user, ({ one }) => ({

12
pnpm-lock.yaml generated
View File

@@ -588,6 +588,9 @@ importers:
dotenv:
specifier: 16.4.5
version: 16.4.5
drizzle-dbml-generator:
specifier: 0.10.0
version: 0.10.0(drizzle-orm@0.39.1(@types/react@18.3.5)(kysely@0.27.5)(postgres@3.4.4)(react@18.2.0)(sqlite3@5.1.7))
drizzle-orm:
specifier: ^0.39.1
version: 0.39.1(@types/react@18.3.5)(kysely@0.27.5)(postgres@3.4.4)(react@18.2.0)(sqlite3@5.1.7)
@@ -4446,6 +4449,11 @@ packages:
resolution: {integrity: sha512-pYxfDYpued//QpnLIm4Avk7rsNtAtQkUES2cwAYSvD/wd2pKD71gN2Ebj3e7klzXwjocvE8c5vx/1fxwpqmSxA==}
engines: {node: '>=4'}
drizzle-dbml-generator@0.10.0:
resolution: {integrity: sha512-cMZq9E3U3RlmE0uBeXyc6oWJ0royOkC6HiTlc9LDeMe+W87poZTzKoNYUyAxZrs4Q1RQtob+cGKiefV4ZoI8HA==}
peerDependencies:
drizzle-orm: '>=0.36.0'
drizzle-kit@0.30.4:
resolution: {integrity: sha512-B2oJN5UkvwwNHscPWXDG5KqAixu7AUzZ3qbe++KU9SsQ+cZWR4DXEPYcvWplyFAno0dhRJECNEhNxiDmFaPGyQ==}
hasBin: true
@@ -11119,6 +11127,10 @@ snapshots:
drange@1.1.1: {}
drizzle-dbml-generator@0.10.0(drizzle-orm@0.39.1(@types/react@18.3.5)(kysely@0.27.5)(postgres@3.4.4)(react@18.2.0)(sqlite3@5.1.7)):
dependencies:
drizzle-orm: 0.39.1(@types/react@18.3.5)(kysely@0.27.5)(postgres@3.4.4)(react@18.2.0)(sqlite3@5.1.7)
drizzle-kit@0.30.4:
dependencies:
'@drizzle-team/brocli': 0.10.2