import type { SQL } from "drizzle-orm"; import type { AnyPgColumn } from "drizzle-orm/pg-core"; import { sql } from "drizzle-orm"; import * as pg from "drizzle-orm/pg-core"; import { generateId } from "@reactive-resume/utils/string"; function lower(column: T): SQL { return sql`lower(${column})`; } export const user = pg.pgTable( "user", { id: pg .text("id") .notNull() .primaryKey() .$defaultFn(() => generateId()), image: pg.text("image"), name: pg.text("name").notNull(), email: pg.text("email").notNull().unique(), emailVerified: pg.boolean("email_verified").notNull().default(false), username: pg.text("username").notNull().unique(), displayUsername: pg.text("display_username").notNull().unique(), twoFactorEnabled: pg.boolean("two_factor_enabled").notNull().default(false), lastActiveAt: pg.timestamp("last_active_at", { withTimezone: true }), role: pg.text("role").default("user"), banned: pg.boolean("banned").default(false), banReason: pg.text("ban_reason"), banExpires: pg.timestamp("ban_expires", { precision: 6, withTimezone: true, }), createdAt: pg.timestamp("created_at", { withTimezone: true }).notNull().defaultNow(), updatedAt: pg .timestamp("updated_at", { withTimezone: true }) .notNull() .defaultNow() .$onUpdate(() => /* @__PURE__ */ new Date()), }, (t) => [pg.index().on(t.createdAt.asc()), pg.uniqueIndex("user_email_lower_unique_idx").on(lower(t.email))], ); export const session = pg.pgTable( "session", { id: pg .text("id") .notNull() .primaryKey() .$defaultFn(() => generateId()), token: pg.text("token").notNull().unique(), ipAddress: pg.text("ip_address"), userAgent: pg.text("user_agent"), impersonatedBy: pg.text("impersonated_by"), userId: pg .text("user_id") .notNull() .references(() => user.id, { onDelete: "cascade" }), expiresAt: pg.timestamp("expires_at", { withTimezone: true }).notNull(), createdAt: pg.timestamp("created_at", { withTimezone: true }).notNull().defaultNow(), updatedAt: pg .timestamp("updated_at", { withTimezone: true }) .notNull() .defaultNow() .$onUpdate(() => /* @__PURE__ */ new Date()), }, (t) => [pg.index().on(t.token, t.userId), pg.index().on(t.expiresAt)], ); export const account = pg.pgTable( "account", { id: pg .text("id") .notNull() .primaryKey() .$defaultFn(() => generateId()), accountId: pg.text("account_id").notNull(), providerId: pg.text("provider_id").notNull().default("credential"), userId: pg .text("user_id") .notNull() .references(() => user.id, { onDelete: "cascade" }), scope: pg.text("scope"), idToken: pg.text("id_token"), password: pg.text("password"), accessToken: pg.text("access_token"), refreshToken: pg.text("refresh_token"), accessTokenExpiresAt: pg.timestamp("access_token_expires_at", { withTimezone: true, }), refreshTokenExpiresAt: pg.timestamp("refresh_token_expires_at", { withTimezone: true, }), createdAt: pg.timestamp("created_at", { withTimezone: true }).notNull().defaultNow(), updatedAt: pg .timestamp("updated_at", { withTimezone: true }) .notNull() .defaultNow() .$onUpdate(() => /* @__PURE__ */ new Date()), }, (t) => [pg.index().on(t.userId)], ); export const verification = pg.pgTable( "verification", { id: pg .text("id") .notNull() .primaryKey() .$defaultFn(() => generateId()), identifier: pg.text("identifier").notNull().unique(), value: pg.text("value").notNull(), expiresAt: pg.timestamp("expires_at", { withTimezone: true }).notNull(), createdAt: pg.timestamp("created_at", { withTimezone: true }).notNull().defaultNow(), updatedAt: pg .timestamp("updated_at", { withTimezone: true }) .notNull() .defaultNow() .$onUpdate(() => /* @__PURE__ */ new Date()), }, (t) => [pg.index().on(t.identifier)], ); export const twoFactor = pg.pgTable( "two_factor", { id: pg .text("id") .notNull() .primaryKey() .$defaultFn(() => generateId()), userId: pg .text("user_id") .notNull() .references(() => user.id, { onDelete: "cascade" }), secret: pg.text("secret").notNull(), backupCodes: pg.text("backup_codes").notNull(), verified: pg.boolean("verified").notNull().default(true), failedVerificationCount: pg.integer("failed_verification_count").default(0), lockedUntil: pg.timestamp("locked_until", { withTimezone: true }), createdAt: pg.timestamp("created_at", { withTimezone: true }).notNull().defaultNow(), updatedAt: pg .timestamp("updated_at", { withTimezone: true }) .notNull() .defaultNow() .$onUpdate(() => /* @__PURE__ */ new Date()), }, (t) => [pg.index().on(t.userId), pg.index().on(t.secret)], ); export const passkey = pg.pgTable( "passkey", { id: pg .text("id") .notNull() .primaryKey() .$defaultFn(() => generateId()), name: pg.text("name"), aaguid: pg.text("aaguid"), publicKey: pg.text("public_key").notNull(), credentialID: pg.text("credential_id").notNull(), counter: pg.integer("counter").notNull(), deviceType: pg.text("device_type").notNull(), backedUp: pg.boolean("backed_up").notNull().default(false), transports: pg.text("transports").notNull(), userId: pg .text("user_id") .notNull() .references(() => user.id, { onDelete: "cascade" }), createdAt: pg.timestamp("created_at", { withTimezone: true }).notNull().defaultNow(), updatedAt: pg .timestamp("updated_at", { withTimezone: true }) .notNull() .defaultNow() .$onUpdate(() => /* @__PURE__ */ new Date()), }, (t) => [pg.index().on(t.userId)], ); export const apikey = pg.pgTable( "apikey", { id: pg .text("id") .notNull() .primaryKey() .$defaultFn(() => generateId()), name: pg.text("name"), start: pg.text("start"), prefix: pg.text("prefix"), key: pg.text("key").notNull(), configId: pg.text("config_id").notNull().default("default"), referenceId: pg .text("reference_id") .notNull() .references(() => user.id, { onDelete: "cascade" }), refillInterval: pg.integer("refill_interval"), refillAmount: pg.integer("refill_amount"), lastRefillAt: pg.timestamp("last_refill_at", { withTimezone: true }), enabled: pg.boolean("enabled").notNull().default(true), rateLimitEnabled: pg.boolean("rate_limit_enabled").notNull().default(false), rateLimitTimeWindow: pg.integer("rate_limit_time_window").default(86400000), rateLimitMax: pg.integer("rate_limit_max").default(10), requestCount: pg.integer("request_count").notNull().default(0), remaining: pg.integer("remaining"), lastRequest: pg.timestamp("last_request", { withTimezone: true }), expiresAt: pg.timestamp("expires_at", { withTimezone: true }), createdAt: pg.timestamp("created_at", { withTimezone: true }).notNull().defaultNow(), updatedAt: pg .timestamp("updated_at", { withTimezone: true }) .notNull() .defaultNow() .$onUpdate(() => /* @__PURE__ */ new Date()), permissions: pg.text("permissions"), metadata: pg.jsonb("metadata"), }, (t) => [ pg.index().on(t.referenceId), pg.index().on(t.key), pg.index().on(t.configId), pg.index().on(t.enabled, t.referenceId), ], ); export const jwks = pg.pgTable("jwks", { id: pg .text("id") .notNull() .primaryKey() .$defaultFn(() => generateId()), publicKey: pg.text("public_key").notNull(), privateKey: pg.text("private_key").notNull(), createdAt: pg.timestamp("created_at", { withTimezone: true }).notNull().defaultNow(), expiresAt: pg.timestamp("expires_at", { withTimezone: true }), }); export const oauthClient = pg.pgTable( "oauth_client", { id: pg .text("id") .notNull() .primaryKey() .$defaultFn(() => generateId()), clientId: pg.text("client_id").notNull().unique(), clientSecret: pg.text("client_secret"), disabled: pg.boolean("disabled").default(false), skipConsent: pg.boolean("skip_consent"), enableEndSession: pg.boolean("enable_end_session"), subjectType: pg.text("subject_type"), scopes: pg.text("scopes").array(), userId: pg.text("user_id").references(() => user.id, { onDelete: "cascade" }), createdAt: pg.timestamp("created_at", { withTimezone: true }).defaultNow(), updatedAt: pg .timestamp("updated_at", { withTimezone: true }) .defaultNow() .$onUpdate(() => /* @__PURE__ */ new Date()), name: pg.text("name"), uri: pg.text("uri"), icon: pg.text("icon"), contacts: pg.text("contacts").array(), tos: pg.text("tos"), policy: pg.text("policy"), softwareId: pg.text("software_id"), softwareVersion: pg.text("software_version"), softwareStatement: pg.text("software_statement"), redirectUris: pg.text("redirect_uris").array().notNull(), postLogoutRedirectUris: pg.text("post_logout_redirect_uris").array(), tokenEndpointAuthMethod: pg.text("token_endpoint_auth_method"), grantTypes: pg.text("grant_types").array(), responseTypes: pg.text("response_types").array(), public: pg.boolean("public"), type: pg.text("type"), requirePKCE: pg.boolean("require_pkce"), referenceId: pg.text("reference_id"), metadata: pg.jsonb("metadata"), }, (t) => [pg.index().on(t.clientId)], ); export const oauthRefreshToken = pg.pgTable( "oauth_refresh_token", { id: pg .text("id") .notNull() .primaryKey() .$defaultFn(() => generateId()), token: pg.text("token").notNull(), clientId: pg .text("client_id") .notNull() .references(() => oauthClient.clientId, { onDelete: "cascade" }), sessionId: pg.text("session_id").references(() => session.id, { onDelete: "set null" }), userId: pg .text("user_id") .notNull() .references(() => user.id, { onDelete: "cascade" }), referenceId: pg.text("reference_id"), expiresAt: pg.timestamp("expires_at", { withTimezone: true }), createdAt: pg.timestamp("created_at", { withTimezone: true }).defaultNow(), revoked: pg.timestamp("revoked", { withTimezone: true }), authTime: pg.timestamp("auth_time", { withTimezone: true }), scopes: pg.text("scopes").array().notNull(), }, (t) => [pg.index().on(t.token)], ); export const oauthAccessToken = pg.pgTable( "oauth_access_token", { id: pg .text("id") .notNull() .primaryKey() .$defaultFn(() => generateId()), token: pg.text("token").notNull().unique(), clientId: pg .text("client_id") .notNull() .references(() => oauthClient.clientId, { onDelete: "cascade" }), sessionId: pg.text("session_id").references(() => session.id, { onDelete: "set null" }), userId: pg.text("user_id").references(() => user.id, { onDelete: "cascade" }), referenceId: pg.text("reference_id"), refreshId: pg.text("refresh_id").references(() => oauthRefreshToken.id, { onDelete: "cascade" }), expiresAt: pg.timestamp("expires_at", { withTimezone: true }), createdAt: pg.timestamp("created_at", { withTimezone: true }).defaultNow(), scopes: pg.text("scopes").array().notNull(), }, (t) => [pg.index().on(t.token)], ); export const oauthConsent = pg.pgTable( "oauth_consent", { id: pg .text("id") .notNull() .primaryKey() .$defaultFn(() => generateId()), clientId: pg .text("client_id") .notNull() .references(() => oauthClient.clientId, { onDelete: "cascade" }), userId: pg.text("user_id").references(() => user.id, { onDelete: "cascade" }), referenceId: pg.text("reference_id"), scopes: pg.text("scopes").array().notNull(), createdAt: pg.timestamp("created_at", { withTimezone: true }).defaultNow(), updatedAt: pg .timestamp("updated_at", { withTimezone: true }) .defaultNow() .$onUpdate(() => /* @__PURE__ */ new Date()), }, (t) => [pg.index().on(t.userId, t.clientId)], );