mirror of
https://github.com/Dokploy/dokploy
synced 2025-06-26 18:27:59 +00:00
Merge branch 'canary' into vicke4/canary
This commit is contained in:
194
packages/server/src/db/schema/account.ts
Normal file
194
packages/server/src/db/schema/account.ts
Normal file
@@ -0,0 +1,194 @@
|
||||
import { relations, sql } from "drizzle-orm";
|
||||
import {
|
||||
boolean,
|
||||
integer,
|
||||
pgTable,
|
||||
text,
|
||||
timestamp,
|
||||
} from "drizzle-orm/pg-core";
|
||||
import { nanoid } from "nanoid";
|
||||
import { projects } from "./project";
|
||||
import { server } from "./server";
|
||||
import { users_temp } from "./user";
|
||||
|
||||
export const account = pgTable("account", {
|
||||
id: text("id")
|
||||
.primaryKey()
|
||||
.$defaultFn(() => nanoid()),
|
||||
accountId: text("account_id")
|
||||
.notNull()
|
||||
.$defaultFn(() => nanoid()),
|
||||
providerId: text("provider_id").notNull(),
|
||||
userId: text("user_id")
|
||||
.notNull()
|
||||
.references(() => users_temp.id, { onDelete: "cascade" }),
|
||||
accessToken: text("access_token"),
|
||||
refreshToken: text("refresh_token"),
|
||||
idToken: text("id_token"),
|
||||
accessTokenExpiresAt: timestamp("access_token_expires_at"),
|
||||
refreshTokenExpiresAt: timestamp("refresh_token_expires_at"),
|
||||
scope: text("scope"),
|
||||
password: text("password"),
|
||||
is2FAEnabled: boolean("is2FAEnabled").notNull().default(false),
|
||||
createdAt: timestamp("created_at").notNull(),
|
||||
updatedAt: timestamp("updated_at").notNull(),
|
||||
resetPasswordToken: text("resetPasswordToken"),
|
||||
resetPasswordExpiresAt: text("resetPasswordExpiresAt"),
|
||||
confirmationToken: text("confirmationToken"),
|
||||
confirmationExpiresAt: text("confirmationExpiresAt"),
|
||||
});
|
||||
|
||||
export const accountRelations = relations(account, ({ one }) => ({
|
||||
user: one(users_temp, {
|
||||
fields: [account.userId],
|
||||
references: [users_temp.id],
|
||||
}),
|
||||
}));
|
||||
|
||||
export const verification = pgTable("verification", {
|
||||
id: text("id").primaryKey(),
|
||||
identifier: text("identifier").notNull(),
|
||||
value: text("value").notNull(),
|
||||
expiresAt: timestamp("expires_at").notNull(),
|
||||
createdAt: timestamp("created_at"),
|
||||
updatedAt: timestamp("updated_at"),
|
||||
});
|
||||
|
||||
export const organization = pgTable("organization", {
|
||||
id: text("id")
|
||||
.primaryKey()
|
||||
.$defaultFn(() => nanoid()),
|
||||
name: text("name").notNull(),
|
||||
slug: text("slug").unique(),
|
||||
logo: text("logo"),
|
||||
createdAt: timestamp("created_at").notNull(),
|
||||
metadata: text("metadata"),
|
||||
ownerId: text("owner_id")
|
||||
.notNull()
|
||||
.references(() => users_temp.id, { onDelete: "cascade" }),
|
||||
});
|
||||
|
||||
export const organizationRelations = relations(
|
||||
organization,
|
||||
({ one, many }) => ({
|
||||
owner: one(users_temp, {
|
||||
fields: [organization.ownerId],
|
||||
references: [users_temp.id],
|
||||
}),
|
||||
servers: many(server),
|
||||
projects: many(projects),
|
||||
members: many(member),
|
||||
}),
|
||||
);
|
||||
|
||||
export const member = pgTable("member", {
|
||||
id: text("id")
|
||||
.primaryKey()
|
||||
.$defaultFn(() => nanoid()),
|
||||
organizationId: text("organization_id")
|
||||
.notNull()
|
||||
.references(() => organization.id, { onDelete: "cascade" }),
|
||||
userId: text("user_id")
|
||||
.notNull()
|
||||
.references(() => users_temp.id, { onDelete: "cascade" }),
|
||||
role: text("role").notNull().$type<"owner" | "member" | "admin">(),
|
||||
createdAt: timestamp("created_at").notNull(),
|
||||
teamId: text("team_id"),
|
||||
// Permissions
|
||||
canCreateProjects: boolean("canCreateProjects").notNull().default(false),
|
||||
canAccessToSSHKeys: boolean("canAccessToSSHKeys").notNull().default(false),
|
||||
canCreateServices: boolean("canCreateServices").notNull().default(false),
|
||||
canDeleteProjects: boolean("canDeleteProjects").notNull().default(false),
|
||||
canDeleteServices: boolean("canDeleteServices").notNull().default(false),
|
||||
canAccessToDocker: boolean("canAccessToDocker").notNull().default(false),
|
||||
canAccessToAPI: boolean("canAccessToAPI").notNull().default(false),
|
||||
canAccessToGitProviders: boolean("canAccessToGitProviders")
|
||||
.notNull()
|
||||
.default(false),
|
||||
canAccessToTraefikFiles: boolean("canAccessToTraefikFiles")
|
||||
.notNull()
|
||||
.default(false),
|
||||
accessedProjects: text("accesedProjects")
|
||||
.array()
|
||||
.notNull()
|
||||
.default(sql`ARRAY[]::text[]`),
|
||||
accessedServices: text("accesedServices")
|
||||
.array()
|
||||
.notNull()
|
||||
.default(sql`ARRAY[]::text[]`),
|
||||
});
|
||||
|
||||
export const memberRelations = relations(member, ({ one }) => ({
|
||||
organization: one(organization, {
|
||||
fields: [member.organizationId],
|
||||
references: [organization.id],
|
||||
}),
|
||||
user: one(users_temp, {
|
||||
fields: [member.userId],
|
||||
references: [users_temp.id],
|
||||
}),
|
||||
}));
|
||||
|
||||
export const invitation = pgTable("invitation", {
|
||||
id: text("id").primaryKey(),
|
||||
organizationId: text("organization_id")
|
||||
.notNull()
|
||||
.references(() => organization.id, { onDelete: "cascade" }),
|
||||
email: text("email").notNull(),
|
||||
role: text("role").$type<"owner" | "member" | "admin">(),
|
||||
status: text("status").notNull(),
|
||||
expiresAt: timestamp("expires_at").notNull(),
|
||||
inviterId: text("inviter_id")
|
||||
.notNull()
|
||||
.references(() => users_temp.id, { onDelete: "cascade" }),
|
||||
teamId: text("team_id"),
|
||||
});
|
||||
|
||||
export const invitationRelations = relations(invitation, ({ one }) => ({
|
||||
organization: one(organization, {
|
||||
fields: [invitation.organizationId],
|
||||
references: [organization.id],
|
||||
}),
|
||||
}));
|
||||
|
||||
export const twoFactor = pgTable("two_factor", {
|
||||
id: text("id").primaryKey(),
|
||||
secret: text("secret").notNull(),
|
||||
backupCodes: text("backup_codes").notNull(),
|
||||
userId: text("user_id")
|
||||
.notNull()
|
||||
.references(() => users_temp.id, { onDelete: "cascade" }),
|
||||
});
|
||||
|
||||
export const apikey = pgTable("apikey", {
|
||||
id: text("id").primaryKey(),
|
||||
name: text("name"),
|
||||
start: text("start"),
|
||||
prefix: text("prefix"),
|
||||
key: text("key").notNull(),
|
||||
userId: text("user_id")
|
||||
.notNull()
|
||||
.references(() => users_temp.id, { onDelete: "cascade" }),
|
||||
refillInterval: integer("refill_interval"),
|
||||
refillAmount: integer("refill_amount"),
|
||||
lastRefillAt: timestamp("last_refill_at"),
|
||||
enabled: boolean("enabled"),
|
||||
rateLimitEnabled: boolean("rate_limit_enabled"),
|
||||
rateLimitTimeWindow: integer("rate_limit_time_window"),
|
||||
rateLimitMax: integer("rate_limit_max"),
|
||||
requestCount: integer("request_count"),
|
||||
remaining: integer("remaining"),
|
||||
lastRequest: timestamp("last_request"),
|
||||
expiresAt: timestamp("expires_at"),
|
||||
createdAt: timestamp("created_at").notNull(),
|
||||
updatedAt: timestamp("updated_at").notNull(),
|
||||
permissions: text("permissions"),
|
||||
metadata: text("metadata"),
|
||||
});
|
||||
|
||||
export const apikeyRelations = relations(apikey, ({ one }) => ({
|
||||
user: one(users_temp, {
|
||||
fields: [apikey.userId],
|
||||
references: [users_temp.id],
|
||||
}),
|
||||
}));
|
||||
@@ -1,210 +0,0 @@
|
||||
import { relations } from "drizzle-orm";
|
||||
import {
|
||||
boolean,
|
||||
integer,
|
||||
json,
|
||||
jsonb,
|
||||
pgTable,
|
||||
text,
|
||||
} from "drizzle-orm/pg-core";
|
||||
import { createInsertSchema } from "drizzle-zod";
|
||||
import { nanoid } from "nanoid";
|
||||
import { z } from "zod";
|
||||
import { auth } from "./auth";
|
||||
import { certificates } from "./certificate";
|
||||
import { registry } from "./registry";
|
||||
import { certificateType } from "./shared";
|
||||
import { sshKeys } from "./ssh-key";
|
||||
import { users } from "./user";
|
||||
|
||||
export const admins = pgTable("admin", {
|
||||
adminId: text("adminId")
|
||||
.notNull()
|
||||
.primaryKey()
|
||||
.$defaultFn(() => nanoid()),
|
||||
serverIp: text("serverIp"),
|
||||
certificateType: certificateType("certificateType").notNull().default("none"),
|
||||
host: text("host"),
|
||||
letsEncryptEmail: text("letsEncryptEmail"),
|
||||
sshPrivateKey: text("sshPrivateKey"),
|
||||
enableDockerCleanup: boolean("enableDockerCleanup").notNull().default(false),
|
||||
enableLogRotation: boolean("enableLogRotation").notNull().default(false),
|
||||
authId: text("authId")
|
||||
.notNull()
|
||||
.references(() => auth.id, { onDelete: "cascade" }),
|
||||
createdAt: text("createdAt")
|
||||
.notNull()
|
||||
.$defaultFn(() => new Date().toISOString()),
|
||||
stripeCustomerId: text("stripeCustomerId"),
|
||||
stripeSubscriptionId: text("stripeSubscriptionId"),
|
||||
serversQuantity: integer("serversQuantity").notNull().default(0),
|
||||
|
||||
// Metrics
|
||||
enablePaidFeatures: boolean("enablePaidFeatures").notNull().default(false),
|
||||
metricsConfig: jsonb("metricsConfig")
|
||||
.$type<{
|
||||
server: {
|
||||
type: "Dokploy" | "Remote";
|
||||
refreshRate: number;
|
||||
port: number;
|
||||
token: string;
|
||||
urlCallback: string;
|
||||
retentionDays: number;
|
||||
cronJob: string;
|
||||
thresholds: {
|
||||
cpu: number;
|
||||
memory: number;
|
||||
};
|
||||
};
|
||||
containers: {
|
||||
refreshRate: number;
|
||||
services: {
|
||||
include: string[];
|
||||
exclude: string[];
|
||||
};
|
||||
};
|
||||
}>()
|
||||
.notNull()
|
||||
.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("cleanupCacheApplications")
|
||||
.notNull()
|
||||
.default(false),
|
||||
cleanupCacheOnPreviews: boolean("cleanupCacheOnPreviews")
|
||||
.notNull()
|
||||
.default(false),
|
||||
cleanupCacheOnCompose: boolean("cleanupCacheOnCompose")
|
||||
.notNull()
|
||||
.default(false),
|
||||
});
|
||||
|
||||
export const adminsRelations = relations(admins, ({ one, many }) => ({
|
||||
auth: one(auth, {
|
||||
fields: [admins.authId],
|
||||
references: [auth.id],
|
||||
}),
|
||||
users: many(users),
|
||||
registry: many(registry),
|
||||
sshKeys: many(sshKeys),
|
||||
certificates: many(certificates),
|
||||
}));
|
||||
|
||||
const createSchema = createInsertSchema(admins, {
|
||||
adminId: z.string(),
|
||||
enableDockerCleanup: z.boolean().optional(),
|
||||
sshPrivateKey: z.string().optional(),
|
||||
certificateType: z.enum(["letsencrypt", "none"]).default("none"),
|
||||
serverIp: z.string().optional(),
|
||||
letsEncryptEmail: z.string().optional(),
|
||||
});
|
||||
|
||||
export const apiUpdateAdmin = createSchema.partial();
|
||||
|
||||
export const apiSaveSSHKey = createSchema
|
||||
.pick({
|
||||
sshPrivateKey: true,
|
||||
})
|
||||
.required();
|
||||
|
||||
export const apiAssignDomain = createSchema
|
||||
.pick({
|
||||
host: true,
|
||||
certificateType: true,
|
||||
letsEncryptEmail: true,
|
||||
})
|
||||
.required()
|
||||
.partial({
|
||||
letsEncryptEmail: true,
|
||||
});
|
||||
|
||||
export const apiUpdateDockerCleanup = createSchema
|
||||
.pick({
|
||||
enableDockerCleanup: true,
|
||||
})
|
||||
.required()
|
||||
.extend({
|
||||
serverId: z.string().optional(),
|
||||
});
|
||||
|
||||
export const apiTraefikConfig = z.object({
|
||||
traefikConfig: z.string().min(1),
|
||||
});
|
||||
|
||||
export const apiModifyTraefikConfig = z.object({
|
||||
path: z.string().min(1),
|
||||
traefikConfig: z.string().min(1),
|
||||
serverId: z.string().optional(),
|
||||
});
|
||||
export const apiReadTraefikConfig = z.object({
|
||||
path: z.string().min(1),
|
||||
serverId: z.string().optional(),
|
||||
});
|
||||
|
||||
export const apiEnableDashboard = z.object({
|
||||
enableDashboard: z.boolean().optional(),
|
||||
serverId: z.string().optional(),
|
||||
});
|
||||
|
||||
export const apiServerSchema = z
|
||||
.object({
|
||||
serverId: z.string().optional(),
|
||||
})
|
||||
.optional();
|
||||
|
||||
export const apiReadStatsLogs = z.object({
|
||||
page: z
|
||||
.object({
|
||||
pageIndex: z.number(),
|
||||
pageSize: z.number(),
|
||||
})
|
||||
.optional(),
|
||||
status: z.string().array().optional(),
|
||||
search: z.string().optional(),
|
||||
sort: z.object({ id: z.string(), desc: z.boolean() }).optional(),
|
||||
});
|
||||
|
||||
export const apiUpdateWebServerMonitoring = z.object({
|
||||
metricsConfig: z
|
||||
.object({
|
||||
server: z.object({
|
||||
refreshRate: z.number().min(2),
|
||||
port: z.number().min(1),
|
||||
token: z.string(),
|
||||
urlCallback: z.string().url(),
|
||||
retentionDays: z.number().min(1),
|
||||
cronJob: z.string().min(1),
|
||||
thresholds: z.object({
|
||||
cpu: z.number().min(0),
|
||||
memory: z.number().min(0),
|
||||
}),
|
||||
}),
|
||||
containers: z.object({
|
||||
refreshRate: z.number().min(2),
|
||||
services: z.object({
|
||||
include: z.array(z.string()).optional(),
|
||||
exclude: z.array(z.string()).optional(),
|
||||
}),
|
||||
}),
|
||||
})
|
||||
.required(),
|
||||
});
|
||||
@@ -44,7 +44,6 @@ export const buildType = pgEnum("buildType", [
|
||||
"static",
|
||||
]);
|
||||
|
||||
// TODO: refactor this types
|
||||
export interface HealthCheckSwarm {
|
||||
Test?: string[] | undefined;
|
||||
Interval?: number | undefined;
|
||||
|
||||
@@ -1,130 +0,0 @@
|
||||
import { getRandomValues } from "node:crypto";
|
||||
import { relations } from "drizzle-orm";
|
||||
import { boolean, pgEnum, pgTable, text } from "drizzle-orm/pg-core";
|
||||
import { createInsertSchema } from "drizzle-zod";
|
||||
import { nanoid } from "nanoid";
|
||||
import { z } from "zod";
|
||||
import { admins } from "./admin";
|
||||
import { users } from "./user";
|
||||
|
||||
const randomImages = [
|
||||
"/avatars/avatar-1.png",
|
||||
"/avatars/avatar-2.png",
|
||||
"/avatars/avatar-3.png",
|
||||
"/avatars/avatar-4.png",
|
||||
"/avatars/avatar-5.png",
|
||||
"/avatars/avatar-6.png",
|
||||
"/avatars/avatar-7.png",
|
||||
"/avatars/avatar-8.png",
|
||||
"/avatars/avatar-9.png",
|
||||
"/avatars/avatar-10.png",
|
||||
"/avatars/avatar-11.png",
|
||||
"/avatars/avatar-12.png",
|
||||
];
|
||||
|
||||
const generateRandomImage = () => {
|
||||
return (
|
||||
randomImages[
|
||||
// @ts-ignore
|
||||
getRandomValues(new Uint32Array(1))[0] % randomImages.length
|
||||
] || "/avatars/avatar-1.png"
|
||||
);
|
||||
};
|
||||
export type DatabaseUser = typeof auth.$inferSelect;
|
||||
export const roles = pgEnum("Roles", ["admin", "user"]);
|
||||
|
||||
export const auth = pgTable("auth", {
|
||||
id: text("id")
|
||||
.notNull()
|
||||
.primaryKey()
|
||||
.$defaultFn(() => nanoid()),
|
||||
email: text("email").notNull().unique(),
|
||||
password: text("password").notNull(),
|
||||
rol: roles("rol").notNull(),
|
||||
image: text("image").$defaultFn(() => generateRandomImage()),
|
||||
secret: text("secret"),
|
||||
token: text("token"),
|
||||
is2FAEnabled: boolean("is2FAEnabled").notNull().default(false),
|
||||
createdAt: text("createdAt")
|
||||
.notNull()
|
||||
.$defaultFn(() => new Date().toISOString()),
|
||||
resetPasswordToken: text("resetPasswordToken"),
|
||||
resetPasswordExpiresAt: text("resetPasswordExpiresAt"),
|
||||
confirmationToken: text("confirmationToken"),
|
||||
confirmationExpiresAt: text("confirmationExpiresAt"),
|
||||
});
|
||||
|
||||
export const authRelations = relations(auth, ({ many }) => ({
|
||||
admins: many(admins),
|
||||
users: many(users),
|
||||
}));
|
||||
const createSchema = createInsertSchema(auth, {
|
||||
email: z.string().email(),
|
||||
password: z.string().min(8),
|
||||
rol: z.enum(["admin", "user"]),
|
||||
image: z.string().optional(),
|
||||
});
|
||||
|
||||
export const apiCreateAdmin = createSchema.pick({
|
||||
email: true,
|
||||
password: true,
|
||||
});
|
||||
|
||||
export const apiCreateUser = createSchema
|
||||
.pick({
|
||||
password: true,
|
||||
id: true,
|
||||
token: true,
|
||||
})
|
||||
.required()
|
||||
.extend({
|
||||
token: z.string().min(1),
|
||||
});
|
||||
|
||||
export const apiLogin = createSchema
|
||||
.pick({
|
||||
email: true,
|
||||
password: true,
|
||||
})
|
||||
.required();
|
||||
|
||||
export const apiUpdateAuth = createSchema.partial().extend({
|
||||
email: z.string().nullable(),
|
||||
password: z.string().nullable(),
|
||||
image: z.string().optional(),
|
||||
currentPassword: z.string().nullable(),
|
||||
});
|
||||
|
||||
export const apiUpdateAuthByAdmin = createSchema.partial().extend({
|
||||
email: z.string().nullable(),
|
||||
password: z.string().nullable(),
|
||||
image: z.string().optional(),
|
||||
id: z.string().min(1),
|
||||
});
|
||||
|
||||
export const apiFindOneAuth = createSchema
|
||||
.pick({
|
||||
id: true,
|
||||
})
|
||||
.required();
|
||||
|
||||
export const apiVerify2FA = createSchema
|
||||
.extend({
|
||||
pin: z.string().min(6),
|
||||
secret: z.string().min(1),
|
||||
})
|
||||
.pick({
|
||||
pin: true,
|
||||
secret: true,
|
||||
})
|
||||
.required();
|
||||
|
||||
export const apiVerifyLogin2FA = createSchema
|
||||
.extend({
|
||||
pin: z.string().min(6),
|
||||
})
|
||||
.pick({
|
||||
pin: true,
|
||||
id: true,
|
||||
})
|
||||
.required();
|
||||
@@ -61,5 +61,5 @@ export const apiUpdateBitbucket = createSchema.extend({
|
||||
name: z.string().min(1),
|
||||
bitbucketUsername: z.string().optional(),
|
||||
bitbucketWorkspaceName: z.string().optional(),
|
||||
adminId: z.string().optional(),
|
||||
organizationId: z.string().optional(),
|
||||
});
|
||||
|
||||
@@ -3,7 +3,7 @@ import { boolean, pgTable, text } from "drizzle-orm/pg-core";
|
||||
import { createInsertSchema } from "drizzle-zod";
|
||||
import { nanoid } from "nanoid";
|
||||
import { z } from "zod";
|
||||
import { admins } from "./admin";
|
||||
import { organization } from "./account";
|
||||
import { server } from "./server";
|
||||
import { generateAppName } from "./utils";
|
||||
|
||||
@@ -20,27 +20,24 @@ export const certificates = pgTable("certificate", {
|
||||
.$defaultFn(() => generateAppName("certificate"))
|
||||
.unique(),
|
||||
autoRenew: boolean("autoRenew"),
|
||||
adminId: text("adminId").references(() => admins.adminId, {
|
||||
onDelete: "cascade",
|
||||
}),
|
||||
organizationId: text("organizationId")
|
||||
.notNull()
|
||||
.references(() => organization.id, { onDelete: "cascade" }),
|
||||
serverId: text("serverId").references(() => server.serverId, {
|
||||
onDelete: "cascade",
|
||||
}),
|
||||
});
|
||||
|
||||
export const certificatesRelations = relations(
|
||||
certificates,
|
||||
({ one, many }) => ({
|
||||
server: one(server, {
|
||||
fields: [certificates.serverId],
|
||||
references: [server.serverId],
|
||||
}),
|
||||
admin: one(admins, {
|
||||
fields: [certificates.adminId],
|
||||
references: [admins.adminId],
|
||||
}),
|
||||
export const certificatesRelations = relations(certificates, ({ one }) => ({
|
||||
server: one(server, {
|
||||
fields: [certificates.serverId],
|
||||
references: [server.serverId],
|
||||
}),
|
||||
);
|
||||
organization: one(organization, {
|
||||
fields: [certificates.organizationId],
|
||||
references: [organization.id],
|
||||
}),
|
||||
}));
|
||||
|
||||
export const apiCreateCertificate = createInsertSchema(certificates, {
|
||||
name: z.string().min(1),
|
||||
|
||||
7
packages/server/src/db/schema/dbml.ts
Normal file
7
packages/server/src/db/schema/dbml.ts
Normal 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 });
|
||||
@@ -1,4 +1,4 @@
|
||||
import { is, relations } from "drizzle-orm";
|
||||
import { relations } from "drizzle-orm";
|
||||
import {
|
||||
type AnyPgColumn,
|
||||
boolean,
|
||||
|
||||
@@ -3,7 +3,7 @@ import { pgTable, text } from "drizzle-orm/pg-core";
|
||||
import { createInsertSchema } from "drizzle-zod";
|
||||
import { nanoid } from "nanoid";
|
||||
import { z } from "zod";
|
||||
import { admins } from "./admin";
|
||||
import { organization } from "./account";
|
||||
import { backups } from "./backups";
|
||||
|
||||
export const destinations = pgTable("destination", {
|
||||
@@ -17,20 +17,19 @@ export const destinations = pgTable("destination", {
|
||||
secretAccessKey: text("secretAccessKey").notNull(),
|
||||
bucket: text("bucket").notNull(),
|
||||
region: text("region").notNull(),
|
||||
// maybe it can be null
|
||||
endpoint: text("endpoint").notNull(),
|
||||
adminId: text("adminId")
|
||||
organizationId: text("organizationId")
|
||||
.notNull()
|
||||
.references(() => admins.adminId, { onDelete: "cascade" }),
|
||||
.references(() => organization.id, { onDelete: "cascade" }),
|
||||
});
|
||||
|
||||
export const destinationsRelations = relations(
|
||||
destinations,
|
||||
({ many, one }) => ({
|
||||
backups: many(backups),
|
||||
admin: one(admins, {
|
||||
fields: [destinations.adminId],
|
||||
references: [admins.adminId],
|
||||
organization: one(organization, {
|
||||
fields: [destinations.organizationId],
|
||||
references: [organization.id],
|
||||
}),
|
||||
}),
|
||||
);
|
||||
|
||||
@@ -3,7 +3,7 @@ import { pgEnum, pgTable, text } from "drizzle-orm/pg-core";
|
||||
import { createInsertSchema } from "drizzle-zod";
|
||||
import { nanoid } from "nanoid";
|
||||
import { z } from "zod";
|
||||
import { admins } from "./admin";
|
||||
import { organization } from "./account";
|
||||
import { bitbucket } from "./bitbucket";
|
||||
import { github } from "./github";
|
||||
import { gitlab } from "./gitlab";
|
||||
@@ -24,12 +24,12 @@ export const gitProvider = pgTable("git_provider", {
|
||||
createdAt: text("createdAt")
|
||||
.notNull()
|
||||
.$defaultFn(() => new Date().toISOString()),
|
||||
adminId: text("adminId").references(() => admins.adminId, {
|
||||
onDelete: "cascade",
|
||||
}),
|
||||
organizationId: text("organizationId")
|
||||
.notNull()
|
||||
.references(() => organization.id, { onDelete: "cascade" }),
|
||||
});
|
||||
|
||||
export const gitProviderRelations = relations(gitProvider, ({ one, many }) => ({
|
||||
export const gitProviderRelations = relations(gitProvider, ({ one }) => ({
|
||||
github: one(github, {
|
||||
fields: [gitProvider.gitProviderId],
|
||||
references: [github.gitProviderId],
|
||||
@@ -42,9 +42,9 @@ export const gitProviderRelations = relations(gitProvider, ({ one, many }) => ({
|
||||
fields: [gitProvider.gitProviderId],
|
||||
references: [bitbucket.gitProviderId],
|
||||
}),
|
||||
admin: one(admins, {
|
||||
fields: [gitProvider.adminId],
|
||||
references: [admins.adminId],
|
||||
organization: one(organization, {
|
||||
fields: [gitProvider.organizationId],
|
||||
references: [organization.id],
|
||||
}),
|
||||
}));
|
||||
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
export * from "./application";
|
||||
export * from "./postgres";
|
||||
export * from "./user";
|
||||
export * from "./admin";
|
||||
export * from "./auth";
|
||||
export * from "./project";
|
||||
export * from "./domain";
|
||||
export * from "./mariadb";
|
||||
@@ -30,3 +28,4 @@ export * from "./gitlab";
|
||||
export * from "./server";
|
||||
export * from "./utils";
|
||||
export * from "./preview-deployments";
|
||||
export * from "./account";
|
||||
|
||||
@@ -3,7 +3,7 @@ import { boolean, integer, pgEnum, pgTable, text } from "drizzle-orm/pg-core";
|
||||
import { createInsertSchema } from "drizzle-zod";
|
||||
import { nanoid } from "nanoid";
|
||||
import { z } from "zod";
|
||||
import { admins } from "./admin";
|
||||
import { organization } from "./account";
|
||||
|
||||
export const notificationType = pgEnum("notificationType", [
|
||||
"slack",
|
||||
@@ -44,9 +44,9 @@ export const notifications = pgTable("notification", {
|
||||
gotifyId: text("gotifyId").references(() => gotify.gotifyId, {
|
||||
onDelete: "cascade",
|
||||
}),
|
||||
adminId: text("adminId").references(() => admins.adminId, {
|
||||
onDelete: "cascade",
|
||||
}),
|
||||
organizationId: text("organizationId")
|
||||
.notNull()
|
||||
.references(() => organization.id, { onDelete: "cascade" }),
|
||||
});
|
||||
|
||||
export const slack = pgTable("slack", {
|
||||
@@ -122,9 +122,9 @@ export const notificationsRelations = relations(notifications, ({ one }) => ({
|
||||
fields: [notifications.gotifyId],
|
||||
references: [gotify.gotifyId],
|
||||
}),
|
||||
admin: one(admins, {
|
||||
fields: [notifications.adminId],
|
||||
references: [admins.adminId],
|
||||
organization: one(organization, {
|
||||
fields: [notifications.organizationId],
|
||||
references: [organization.id],
|
||||
}),
|
||||
}));
|
||||
|
||||
@@ -149,7 +149,7 @@ export const apiCreateSlack = notificationsSchema
|
||||
export const apiUpdateSlack = apiCreateSlack.partial().extend({
|
||||
notificationId: z.string().min(1),
|
||||
slackId: z.string(),
|
||||
adminId: z.string().optional(),
|
||||
organizationId: z.string().optional(),
|
||||
});
|
||||
|
||||
export const apiTestSlackConnection = apiCreateSlack.pick({
|
||||
@@ -177,7 +177,7 @@ export const apiCreateTelegram = notificationsSchema
|
||||
export const apiUpdateTelegram = apiCreateTelegram.partial().extend({
|
||||
notificationId: z.string().min(1),
|
||||
telegramId: z.string().min(1),
|
||||
adminId: z.string().optional(),
|
||||
organizationId: z.string().optional(),
|
||||
});
|
||||
|
||||
export const apiTestTelegramConnection = apiCreateTelegram.pick({
|
||||
@@ -205,7 +205,7 @@ export const apiCreateDiscord = notificationsSchema
|
||||
export const apiUpdateDiscord = apiCreateDiscord.partial().extend({
|
||||
notificationId: z.string().min(1),
|
||||
discordId: z.string().min(1),
|
||||
adminId: z.string().optional(),
|
||||
organizationId: z.string().optional(),
|
||||
});
|
||||
|
||||
export const apiTestDiscordConnection = apiCreateDiscord
|
||||
@@ -239,7 +239,7 @@ export const apiCreateEmail = notificationsSchema
|
||||
export const apiUpdateEmail = apiCreateEmail.partial().extend({
|
||||
notificationId: z.string().min(1),
|
||||
emailId: z.string().min(1),
|
||||
adminId: z.string().optional(),
|
||||
organizationId: z.string().optional(),
|
||||
});
|
||||
|
||||
export const apiTestEmailConnection = apiCreateEmail.pick({
|
||||
@@ -271,7 +271,7 @@ export const apiCreateGotify = notificationsSchema
|
||||
export const apiUpdateGotify = apiCreateGotify.partial().extend({
|
||||
notificationId: z.string().min(1),
|
||||
gotifyId: z.string().min(1),
|
||||
adminId: z.string().optional(),
|
||||
organizationId: z.string().optional(),
|
||||
});
|
||||
|
||||
export const apiTestGotifyConnection = apiCreateGotify
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
import { relations } from "drizzle-orm";
|
||||
|
||||
import { pgTable, text } from "drizzle-orm/pg-core";
|
||||
import { createInsertSchema } from "drizzle-zod";
|
||||
import { nanoid } from "nanoid";
|
||||
import { z } from "zod";
|
||||
import { admins } from "./admin";
|
||||
import { organization } from "./account";
|
||||
import { applications } from "./application";
|
||||
import { compose } from "./compose";
|
||||
import { mariadb } from "./mariadb";
|
||||
@@ -23,9 +22,10 @@ export const projects = pgTable("project", {
|
||||
createdAt: text("createdAt")
|
||||
.notNull()
|
||||
.$defaultFn(() => new Date().toISOString()),
|
||||
adminId: text("adminId")
|
||||
|
||||
organizationId: text("organizationId")
|
||||
.notNull()
|
||||
.references(() => admins.adminId, { onDelete: "cascade" }),
|
||||
.references(() => organization.id, { onDelete: "cascade" }),
|
||||
env: text("env").notNull().default(""),
|
||||
});
|
||||
|
||||
@@ -37,9 +37,9 @@ export const projectRelations = relations(projects, ({ many, one }) => ({
|
||||
mongo: many(mongo),
|
||||
redis: many(redis),
|
||||
compose: many(compose),
|
||||
admin: one(admins, {
|
||||
fields: [projects.adminId],
|
||||
references: [admins.adminId],
|
||||
organization: one(organization, {
|
||||
fields: [projects.organizationId],
|
||||
references: [organization.id],
|
||||
}),
|
||||
}));
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ import { pgEnum, pgTable, text } from "drizzle-orm/pg-core";
|
||||
import { createInsertSchema } from "drizzle-zod";
|
||||
import { nanoid } from "nanoid";
|
||||
import { z } from "zod";
|
||||
import { admins } from "./admin";
|
||||
import { organization } from "./account";
|
||||
import { applications } from "./application";
|
||||
/**
|
||||
* This is an example of how to use the multi-project schema feature of Drizzle ORM. Use the same
|
||||
@@ -27,16 +27,12 @@ export const registry = pgTable("registry", {
|
||||
.notNull()
|
||||
.$defaultFn(() => new Date().toISOString()),
|
||||
registryType: registryType("selfHosted").notNull().default("cloud"),
|
||||
adminId: text("adminId")
|
||||
organizationId: text("organizationId")
|
||||
.notNull()
|
||||
.references(() => admins.adminId, { onDelete: "cascade" }),
|
||||
.references(() => organization.id, { onDelete: "cascade" }),
|
||||
});
|
||||
|
||||
export const registryRelations = relations(registry, ({ one, many }) => ({
|
||||
admin: one(admins, {
|
||||
fields: [registry.adminId],
|
||||
references: [admins.adminId],
|
||||
}),
|
||||
export const registryRelations = relations(registry, ({ many }) => ({
|
||||
applications: many(applications),
|
||||
}));
|
||||
|
||||
@@ -45,7 +41,7 @@ const createSchema = createInsertSchema(registry, {
|
||||
username: z.string().min(1),
|
||||
password: z.string().min(1),
|
||||
registryUrl: z.string(),
|
||||
adminId: z.string().min(1),
|
||||
organizationId: z.string().min(1),
|
||||
registryId: z.string().min(1),
|
||||
registryType: z.enum(["cloud"]),
|
||||
imagePrefix: z.string().nullable().optional(),
|
||||
|
||||
872
packages/server/src/db/schema/schema.dbml
Normal file
872
packages/server/src/db/schema/schema.dbml
Normal 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
|
||||
@@ -10,8 +10,7 @@ import {
|
||||
import { createInsertSchema } from "drizzle-zod";
|
||||
import { nanoid } from "nanoid";
|
||||
import { z } from "zod";
|
||||
|
||||
import { admins } from "./admin";
|
||||
import { organization } from "./account";
|
||||
import { applications } from "./application";
|
||||
import { certificates } from "./certificate";
|
||||
import { compose } from "./compose";
|
||||
@@ -40,12 +39,10 @@ export const server = pgTable("server", {
|
||||
.notNull()
|
||||
.$defaultFn(() => generateAppName("server")),
|
||||
enableDockerCleanup: boolean("enableDockerCleanup").notNull().default(false),
|
||||
createdAt: text("createdAt")
|
||||
createdAt: text("createdAt").notNull(),
|
||||
organizationId: text("organizationId")
|
||||
.notNull()
|
||||
.$defaultFn(() => new Date().toISOString()),
|
||||
adminId: text("adminId")
|
||||
.notNull()
|
||||
.references(() => admins.adminId, { onDelete: "cascade" }),
|
||||
.references(() => organization.id, { onDelete: "cascade" }),
|
||||
serverStatus: serverStatus("serverStatus").notNull().default("active"),
|
||||
command: text("command").notNull().default(""),
|
||||
sshKeyId: text("sshKeyId").references(() => sshKeys.sshKeyId, {
|
||||
@@ -100,10 +97,6 @@ export const server = pgTable("server", {
|
||||
});
|
||||
|
||||
export const serverRelations = relations(server, ({ one, many }) => ({
|
||||
admin: one(admins, {
|
||||
fields: [server.adminId],
|
||||
references: [admins.adminId],
|
||||
}),
|
||||
deployments: many(deployments),
|
||||
sshKey: one(sshKeys, {
|
||||
fields: [server.sshKeyId],
|
||||
@@ -117,6 +110,10 @@ export const serverRelations = relations(server, ({ one, many }) => ({
|
||||
mysql: many(mysql),
|
||||
postgres: many(postgres),
|
||||
certificates: many(certificates),
|
||||
organization: one(organization, {
|
||||
fields: [server.organizationId],
|
||||
references: [organization.id],
|
||||
}),
|
||||
}));
|
||||
|
||||
const createSchema = createInsertSchema(server, {
|
||||
|
||||
@@ -1,13 +1,18 @@
|
||||
import { pgTable, text, timestamp } from "drizzle-orm/pg-core";
|
||||
import { auth } from "./auth";
|
||||
import { users_temp } from "./user";
|
||||
|
||||
export const sessionTable = pgTable("session", {
|
||||
// OLD TABLE
|
||||
export const session = pgTable("session_temp", {
|
||||
id: text("id").primaryKey(),
|
||||
expiresAt: timestamp("expires_at").notNull(),
|
||||
token: text("token").notNull().unique(),
|
||||
createdAt: timestamp("created_at").notNull(),
|
||||
updatedAt: timestamp("updated_at").notNull(),
|
||||
ipAddress: text("ip_address"),
|
||||
userAgent: text("user_agent"),
|
||||
userId: text("user_id")
|
||||
.notNull()
|
||||
.references(() => auth.id, { onDelete: "cascade" }),
|
||||
expiresAt: timestamp("expires_at", {
|
||||
withTimezone: true,
|
||||
mode: "date",
|
||||
}).notNull(),
|
||||
.references(() => users_temp.id, { onDelete: "cascade" }),
|
||||
impersonatedBy: text("impersonated_by"),
|
||||
activeOrganizationId: text("active_organization_id"),
|
||||
});
|
||||
|
||||
@@ -1,27 +0,0 @@
|
||||
import { pgTable, text } from "drizzle-orm/pg-core";
|
||||
import { createInsertSchema } from "drizzle-zod";
|
||||
import { nanoid } from "nanoid";
|
||||
import { z } from "zod";
|
||||
|
||||
export const source = pgTable("project", {
|
||||
projectId: text("projectId")
|
||||
.notNull()
|
||||
.primaryKey()
|
||||
.$defaultFn(() => nanoid()),
|
||||
name: text("name").notNull(),
|
||||
description: text("description"),
|
||||
createdAt: text("createdAt")
|
||||
.notNull()
|
||||
.$defaultFn(() => new Date().toISOString()),
|
||||
});
|
||||
|
||||
const createSchema = createInsertSchema(source, {
|
||||
name: z.string().min(1),
|
||||
description: z.string(),
|
||||
projectId: z.string(),
|
||||
});
|
||||
|
||||
export const apiCreate = createSchema.pick({
|
||||
name: true,
|
||||
description: true,
|
||||
});
|
||||
@@ -3,7 +3,7 @@ import { pgTable, text } from "drizzle-orm/pg-core";
|
||||
import { createInsertSchema } from "drizzle-zod";
|
||||
import { nanoid } from "nanoid";
|
||||
import { sshKeyCreate, sshKeyType } from "../validations";
|
||||
import { admins } from "./admin";
|
||||
import { organization } from "./account";
|
||||
import { applications } from "./application";
|
||||
import { compose } from "./compose";
|
||||
import { server } from "./server";
|
||||
@@ -21,18 +21,18 @@ export const sshKeys = pgTable("ssh-key", {
|
||||
.notNull()
|
||||
.$defaultFn(() => new Date().toISOString()),
|
||||
lastUsedAt: text("lastUsedAt"),
|
||||
adminId: text("adminId").references(() => admins.adminId, {
|
||||
onDelete: "cascade",
|
||||
}),
|
||||
organizationId: text("organizationId")
|
||||
.notNull()
|
||||
.references(() => organization.id, { onDelete: "cascade" }),
|
||||
});
|
||||
|
||||
export const sshKeysRelations = relations(sshKeys, ({ many, one }) => ({
|
||||
applications: many(applications),
|
||||
compose: many(compose),
|
||||
servers: many(server),
|
||||
admin: one(admins, {
|
||||
fields: [sshKeys.adminId],
|
||||
references: [admins.adminId],
|
||||
organization: one(organization, {
|
||||
fields: [sshKeys.organizationId],
|
||||
references: [organization.id],
|
||||
}),
|
||||
}));
|
||||
|
||||
@@ -48,7 +48,7 @@ export const apiCreateSshKey = createSchema
|
||||
description: true,
|
||||
privateKey: true,
|
||||
publicKey: true,
|
||||
adminId: true,
|
||||
organizationId: true,
|
||||
})
|
||||
.merge(sshKeyCreate.pick({ privateKey: true }));
|
||||
|
||||
|
||||
@@ -1,10 +1,18 @@
|
||||
import { relations, sql } from "drizzle-orm";
|
||||
import { boolean, pgTable, text, timestamp } from "drizzle-orm/pg-core";
|
||||
import { relations } from "drizzle-orm";
|
||||
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";
|
||||
import { admins } from "./admin";
|
||||
import { auth } from "./auth";
|
||||
import { account, organization, apikey } from "./account";
|
||||
import { projects } from "./project";
|
||||
import { certificateType } from "./shared";
|
||||
/**
|
||||
* This is an example of how to use the multi-project schema feature of Drizzle ORM. Use the same
|
||||
* database instance for multiple projects.
|
||||
@@ -12,75 +20,115 @@ import { auth } from "./auth";
|
||||
* @see https://orm.drizzle.team/docs/goodies#multi-project-schema
|
||||
*/
|
||||
|
||||
export const users = pgTable("user", {
|
||||
userId: text("userId")
|
||||
// OLD TABLE
|
||||
|
||||
// TEMP
|
||||
export const users_temp = pgTable("user_temp", {
|
||||
id: text("id")
|
||||
.notNull()
|
||||
.primaryKey()
|
||||
.$defaultFn(() => nanoid()),
|
||||
|
||||
token: text("token").notNull(),
|
||||
name: text("name").notNull().default(""),
|
||||
isRegistered: boolean("isRegistered").notNull().default(false),
|
||||
expirationDate: timestamp("expirationDate", {
|
||||
precision: 3,
|
||||
mode: "string",
|
||||
}).notNull(),
|
||||
createdAt: text("createdAt")
|
||||
expirationDate: text("expirationDate")
|
||||
.notNull()
|
||||
.$defaultFn(() => new Date().toISOString()),
|
||||
canCreateProjects: boolean("canCreateProjects").notNull().default(false),
|
||||
canAccessToSSHKeys: boolean("canAccessToSSHKeys").notNull().default(false),
|
||||
canCreateServices: boolean("canCreateServices").notNull().default(false),
|
||||
canDeleteProjects: boolean("canDeleteProjects").notNull().default(false),
|
||||
canDeleteServices: boolean("canDeleteServices").notNull().default(false),
|
||||
canAccessToDocker: boolean("canAccessToDocker").notNull().default(false),
|
||||
canAccessToAPI: boolean("canAccessToAPI").notNull().default(false),
|
||||
canAccessToGitProviders: boolean("canAccessToGitProviders")
|
||||
createdAt2: text("createdAt")
|
||||
.notNull()
|
||||
.$defaultFn(() => new Date().toISOString()),
|
||||
createdAt: timestamp("created_at").defaultNow(),
|
||||
// Auth
|
||||
twoFactorEnabled: boolean("two_factor_enabled"),
|
||||
email: text("email").notNull().unique(),
|
||||
emailVerified: boolean("email_verified").notNull(),
|
||||
image: text("image"),
|
||||
banned: boolean("banned"),
|
||||
banReason: text("ban_reason"),
|
||||
banExpires: timestamp("ban_expires"),
|
||||
updatedAt: timestamp("updated_at").notNull(),
|
||||
// Admin
|
||||
serverIp: text("serverIp"),
|
||||
certificateType: certificateType("certificateType").notNull().default("none"),
|
||||
host: text("host"),
|
||||
letsEncryptEmail: text("letsEncryptEmail"),
|
||||
sshPrivateKey: text("sshPrivateKey"),
|
||||
enableDockerCleanup: boolean("enableDockerCleanup").notNull().default(false),
|
||||
enableLogRotation: boolean("enableLogRotation").notNull().default(false),
|
||||
// Metrics
|
||||
enablePaidFeatures: boolean("enablePaidFeatures").notNull().default(false),
|
||||
metricsConfig: jsonb("metricsConfig")
|
||||
.$type<{
|
||||
server: {
|
||||
type: "Dokploy" | "Remote";
|
||||
refreshRate: number;
|
||||
port: number;
|
||||
token: string;
|
||||
urlCallback: string;
|
||||
retentionDays: number;
|
||||
cronJob: string;
|
||||
thresholds: {
|
||||
cpu: number;
|
||||
memory: number;
|
||||
};
|
||||
};
|
||||
containers: {
|
||||
refreshRate: number;
|
||||
services: {
|
||||
include: string[];
|
||||
exclude: string[];
|
||||
};
|
||||
};
|
||||
}>()
|
||||
.notNull()
|
||||
.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("cleanupCacheApplications")
|
||||
.notNull()
|
||||
.default(false),
|
||||
canAccessToTraefikFiles: boolean("canAccessToTraefikFiles")
|
||||
cleanupCacheOnPreviews: boolean("cleanupCacheOnPreviews")
|
||||
.notNull()
|
||||
.default(false),
|
||||
accessedProjects: text("accesedProjects")
|
||||
.array()
|
||||
cleanupCacheOnCompose: boolean("cleanupCacheOnCompose")
|
||||
.notNull()
|
||||
.default(sql`ARRAY[]::text[]`),
|
||||
accessedServices: text("accesedServices")
|
||||
.array()
|
||||
.notNull()
|
||||
.default(sql`ARRAY[]::text[]`),
|
||||
adminId: text("adminId")
|
||||
.notNull()
|
||||
.references(() => admins.adminId, { onDelete: "cascade" }),
|
||||
authId: text("authId")
|
||||
.notNull()
|
||||
.references(() => auth.id, { onDelete: "cascade" }),
|
||||
.default(false),
|
||||
stripeCustomerId: text("stripeCustomerId"),
|
||||
stripeSubscriptionId: text("stripeSubscriptionId"),
|
||||
serversQuantity: integer("serversQuantity").notNull().default(0),
|
||||
});
|
||||
|
||||
export const usersRelations = relations(users, ({ one }) => ({
|
||||
auth: one(auth, {
|
||||
fields: [users.authId],
|
||||
references: [auth.id],
|
||||
}),
|
||||
admin: one(admins, {
|
||||
fields: [users.adminId],
|
||||
references: [admins.adminId],
|
||||
export const usersRelations = relations(users_temp, ({ one, many }) => ({
|
||||
account: one(account, {
|
||||
fields: [users_temp.id],
|
||||
references: [account.userId],
|
||||
}),
|
||||
organizations: many(organization),
|
||||
projects: many(projects),
|
||||
apiKeys: many(apikey),
|
||||
}));
|
||||
|
||||
const createSchema = createInsertSchema(users, {
|
||||
userId: z.string().min(1),
|
||||
authId: z.string().min(1),
|
||||
token: z.string().min(1),
|
||||
const createSchema = createInsertSchema(users_temp, {
|
||||
id: z.string().min(1),
|
||||
isRegistered: z.boolean().optional(),
|
||||
adminId: z.string(),
|
||||
accessedProjects: z.array(z.string()).optional(),
|
||||
accessedServices: z.array(z.string()).optional(),
|
||||
canCreateProjects: z.boolean().optional(),
|
||||
canCreateServices: z.boolean().optional(),
|
||||
canDeleteProjects: z.boolean().optional(),
|
||||
canDeleteServices: z.boolean().optional(),
|
||||
canAccessToDocker: z.boolean().optional(),
|
||||
canAccessToTraefikFiles: z.boolean().optional(),
|
||||
});
|
||||
|
||||
export const apiCreateUserInvitation = createSchema.pick({}).extend({
|
||||
@@ -89,41 +137,172 @@ export const apiCreateUserInvitation = createSchema.pick({}).extend({
|
||||
|
||||
export const apiRemoveUser = createSchema
|
||||
.pick({
|
||||
authId: true,
|
||||
id: true,
|
||||
})
|
||||
.required();
|
||||
|
||||
export const apiFindOneToken = createSchema
|
||||
.pick({
|
||||
token: true,
|
||||
})
|
||||
.required();
|
||||
.pick({})
|
||||
.required()
|
||||
.extend({
|
||||
token: z.string().min(1),
|
||||
});
|
||||
|
||||
export const apiAssignPermissions = createSchema
|
||||
.pick({
|
||||
userId: true,
|
||||
canCreateProjects: true,
|
||||
canCreateServices: true,
|
||||
canDeleteProjects: true,
|
||||
canDeleteServices: true,
|
||||
accessedProjects: true,
|
||||
accessedServices: true,
|
||||
canAccessToTraefikFiles: true,
|
||||
canAccessToDocker: true,
|
||||
canAccessToAPI: true,
|
||||
canAccessToSSHKeys: true,
|
||||
canAccessToGitProviders: true,
|
||||
id: true,
|
||||
// canCreateProjects: true,
|
||||
// canCreateServices: true,
|
||||
// canDeleteProjects: true,
|
||||
// canDeleteServices: true,
|
||||
// accessedProjects: true,
|
||||
// accessedServices: true,
|
||||
// canAccessToTraefikFiles: true,
|
||||
// canAccessToDocker: true,
|
||||
// canAccessToAPI: true,
|
||||
// canAccessToSSHKeys: true,
|
||||
// canAccessToGitProviders: true,
|
||||
})
|
||||
.extend({
|
||||
accessedProjects: z.array(z.string()).optional(),
|
||||
accessedServices: z.array(z.string()).optional(),
|
||||
canCreateProjects: z.boolean().optional(),
|
||||
canCreateServices: z.boolean().optional(),
|
||||
canDeleteProjects: z.boolean().optional(),
|
||||
canDeleteServices: z.boolean().optional(),
|
||||
canAccessToDocker: z.boolean().optional(),
|
||||
canAccessToTraefikFiles: z.boolean().optional(),
|
||||
canAccessToAPI: z.boolean().optional(),
|
||||
canAccessToSSHKeys: z.boolean().optional(),
|
||||
canAccessToGitProviders: z.boolean().optional(),
|
||||
})
|
||||
.required();
|
||||
|
||||
export const apiFindOneUser = createSchema
|
||||
.pick({
|
||||
userId: true,
|
||||
id: true,
|
||||
})
|
||||
.required();
|
||||
|
||||
export const apiFindOneUserByAuth = createSchema
|
||||
.pick({
|
||||
authId: true,
|
||||
// authId: true,
|
||||
})
|
||||
.required();
|
||||
export const apiSaveSSHKey = createSchema
|
||||
.pick({
|
||||
sshPrivateKey: true,
|
||||
})
|
||||
.required();
|
||||
|
||||
export const apiAssignDomain = createSchema
|
||||
.pick({
|
||||
host: true,
|
||||
certificateType: true,
|
||||
letsEncryptEmail: true,
|
||||
})
|
||||
.required()
|
||||
.partial({
|
||||
letsEncryptEmail: true,
|
||||
});
|
||||
|
||||
export const apiUpdateDockerCleanup = createSchema
|
||||
.pick({
|
||||
enableDockerCleanup: true,
|
||||
})
|
||||
.required()
|
||||
.extend({
|
||||
serverId: z.string().optional(),
|
||||
});
|
||||
|
||||
export const apiTraefikConfig = z.object({
|
||||
traefikConfig: z.string().min(1),
|
||||
});
|
||||
|
||||
export const apiModifyTraefikConfig = z.object({
|
||||
path: z.string().min(1),
|
||||
traefikConfig: z.string().min(1),
|
||||
serverId: z.string().optional(),
|
||||
});
|
||||
export const apiReadTraefikConfig = z.object({
|
||||
path: z.string().min(1),
|
||||
serverId: z.string().optional(),
|
||||
});
|
||||
|
||||
export const apiEnableDashboard = z.object({
|
||||
enableDashboard: z.boolean().optional(),
|
||||
serverId: z.string().optional(),
|
||||
});
|
||||
|
||||
export const apiServerSchema = z
|
||||
.object({
|
||||
serverId: z.string().optional(),
|
||||
})
|
||||
.optional();
|
||||
|
||||
export const apiReadStatsLogs = z.object({
|
||||
page: z
|
||||
.object({
|
||||
pageIndex: z.number(),
|
||||
pageSize: z.number(),
|
||||
})
|
||||
.optional(),
|
||||
status: z.string().array().optional(),
|
||||
search: z.string().optional(),
|
||||
sort: z.object({ id: z.string(), desc: z.boolean() }).optional(),
|
||||
});
|
||||
|
||||
export const apiUpdateWebServerMonitoring = z.object({
|
||||
metricsConfig: z
|
||||
.object({
|
||||
server: z.object({
|
||||
refreshRate: z.number().min(2),
|
||||
port: z.number().min(1),
|
||||
token: z.string(),
|
||||
urlCallback: z.string().url(),
|
||||
retentionDays: z.number().min(1),
|
||||
cronJob: z.string().min(1),
|
||||
thresholds: z.object({
|
||||
cpu: z.number().min(0),
|
||||
memory: z.number().min(0),
|
||||
}),
|
||||
}),
|
||||
containers: z.object({
|
||||
refreshRate: z.number().min(2),
|
||||
services: z.object({
|
||||
include: z.array(z.string()).optional(),
|
||||
exclude: z.array(z.string()).optional(),
|
||||
}),
|
||||
}),
|
||||
})
|
||||
.required(),
|
||||
});
|
||||
|
||||
export const apiUpdateUser = createSchema.partial().extend({
|
||||
password: z.string().optional(),
|
||||
currentPassword: z.string().optional(),
|
||||
metricsConfig: z
|
||||
.object({
|
||||
server: z.object({
|
||||
type: z.enum(["Dokploy", "Remote"]),
|
||||
refreshRate: z.number(),
|
||||
port: z.number(),
|
||||
token: z.string(),
|
||||
urlCallback: z.string(),
|
||||
retentionDays: z.number(),
|
||||
cronJob: z.string(),
|
||||
thresholds: z.object({
|
||||
cpu: z.number(),
|
||||
memory: z.number(),
|
||||
}),
|
||||
}),
|
||||
containers: z.object({
|
||||
refreshRate: z.number(),
|
||||
services: z.object({
|
||||
include: z.array(z.string()),
|
||||
exclude: z.array(z.string()),
|
||||
}),
|
||||
}),
|
||||
})
|
||||
.optional(),
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user