Merge branch 'main' of github.com:amruthpillai/reactive-resume

This commit is contained in:
Amruth Pillai
2026-05-07 15:14:21 +02:00
1015 changed files with 106087 additions and 141872 deletions
+35
View File
@@ -0,0 +1,35 @@
# dependencies (bun install)
node_modules
# output
out
dist
*.tgz
/prisma/generated
# code coverage
coverage
*.lcov
# logs
logs
_.log
report.[0-9]_.[0-9]_.[0-9]_.[0-9]_.json
# dotenv environment variable files
.env
.env.development.local
.env.test.local
.env.production.local
.env.local
# caches
.eslintcache
.cache
*.tsbuildinfo
# IntelliJ based IDEs
.idea
# Finder (MacOS) folder config
.DS_Store
+10
View File
@@ -0,0 +1,10 @@
import { defineConfig } from "drizzle-kit";
export default defineConfig({
schema: "./src/schema/index.ts",
out: "../../migrations",
dialect: "postgresql",
dbCredentials: {
url: process.env.DATABASE_URL || "",
},
});
+38
View File
@@ -0,0 +1,38 @@
{
"name": "@reactive-resume/db",
"version": "0.0.0",
"type": "module",
"private": true,
"exports": {
"./client": {
"default": "./src/client.ts"
},
"./schema": {
"default": "./src/schema/index.ts"
}
},
"scripts": {
"db:generate": "drizzle-kit generate",
"db:migrate": "drizzle-kit migrate",
"db:studio": "drizzle-kit studio",
"typecheck": "tsgo --noEmit",
"test": "vitest run --passWithNoTests",
"test:coverage": "vitest run --coverage --passWithNoTests",
"test:ci": "vitest run --coverage --reporter=default --reporter=github-actions --reporter=json --reporter=junit --outputFile.json=reports/vitest-results.json --outputFile.junit=reports/vitest-junit.xml --passWithNoTests",
"test:agent": "vitest run --reporter=agent --reporter=json --outputFile.json=reports/vitest-results.json --passWithNoTests"
},
"dependencies": {
"@reactive-resume/env": "workspace:*",
"@reactive-resume/schema": "workspace:*",
"@reactive-resume/utils": "workspace:*",
"drizzle-orm": "1.0.0-beta.22",
"pg": "^8.20.0"
},
"devDependencies": {
"@reactive-resume/config": "workspace:*",
"@types/pg": "^8.20.0",
"@typescript/native-preview": "7.0.0-dev.20260507.1",
"drizzle-kit": "1.0.0-beta.22",
"typescript": "^6.0.3"
}
}
+32
View File
@@ -0,0 +1,32 @@
import type { NodePgDatabase } from "drizzle-orm/node-postgres";
import { drizzle } from "drizzle-orm/node-postgres";
import { Pool } from "pg";
import { env } from "@reactive-resume/env/server";
import { relations } from "./relations";
import * as schema from "./schema";
declare global {
var __pool: Pool | undefined;
var __drizzle: NodePgDatabase<typeof schema> | undefined;
}
function getPool() {
if (!globalThis.__pool) {
globalThis.__pool = new Pool({ connectionString: env.DATABASE_URL });
}
return globalThis.__pool;
}
function makeDrizzleClient() {
const pool = getPool();
return drizzle({ client: pool, schema, relations });
}
export function createDatabase() {
if (!globalThis.__drizzle) {
globalThis.__drizzle = makeDrizzleClient();
}
return globalThis.__drizzle;
}
export const db = createDatabase();
+129
View File
@@ -0,0 +1,129 @@
import { defineRelations } from "drizzle-orm";
import * as schema from "./schema";
export const relations = defineRelations(schema, (r) => ({
user: {
sessions: r.many.session(),
accounts: r.many.account(),
twoFactors: r.many.twoFactor(),
passkeys: r.many.passkey(),
resumes: r.many.resume(),
apiKeys: r.many.apikey(),
oauthClients: r.many.oauthClient(),
oauthRefreshTokens: r.many.oauthRefreshToken(),
oauthAccessTokens: r.many.oauthAccessToken(),
oauthConsents: r.many.oauthConsent(),
},
session: {
user: r.one.user({
from: r.session.userId,
to: r.user.id,
}),
oauthRefreshTokens: r.many.oauthRefreshToken({
from: r.session.id,
to: r.oauthRefreshToken.sessionId,
}),
oauthAccessTokens: r.many.oauthAccessToken({
from: r.session.id,
to: r.oauthAccessToken.sessionId,
}),
},
account: {
user: r.one.user({
from: r.account.userId,
to: r.user.id,
}),
},
twoFactor: {
user: r.one.user({
from: r.twoFactor.userId,
to: r.user.id,
}),
},
passkey: {
user: r.one.user({
from: r.passkey.userId,
to: r.user.id,
}),
},
resume: {
user: r.one.user({
from: r.resume.userId,
to: r.user.id,
}),
statistics: r.one.resumeStatistics({
from: r.resume.id,
to: r.resumeStatistics.resumeId,
}),
analysis: r.one.resumeAnalysis({
from: r.resume.id,
to: r.resumeAnalysis.resumeId,
}),
},
resumeStatistics: {
resume: r.one.resume({
from: r.resumeStatistics.resumeId,
to: r.resume.id,
}),
},
resumeAnalysis: {
resume: r.one.resume({
from: r.resumeAnalysis.resumeId,
to: r.resume.id,
}),
},
apikey: {
user: r.one.user({
from: r.apikey.referenceId,
to: r.user.id,
}),
},
oauthClient: {
user: r.one.user({
from: r.oauthClient.userId,
to: r.user.id,
}),
oauthRefreshTokens: r.many.oauthRefreshToken({
from: r.oauthClient.clientId,
to: r.oauthRefreshToken.clientId,
}),
oauthAccessTokens: r.many.oauthAccessToken({
from: r.oauthClient.clientId,
to: r.oauthAccessToken.clientId,
}),
oauthConsents: r.many.oauthConsent({
from: r.oauthClient.clientId,
to: r.oauthConsent.clientId,
}),
},
oauthRefreshToken: {
user: r.one.user({
from: r.oauthRefreshToken.userId,
to: r.user.id,
}),
session: r.one.session({
from: r.oauthRefreshToken.sessionId,
to: r.session.id,
}),
},
oauthAccessToken: {
user: r.one.user({
from: r.oauthAccessToken.userId,
to: r.user.id,
}),
session: r.one.session({
from: r.oauthAccessToken.sessionId,
to: r.session.id,
}),
refreshToken: r.one.oauthRefreshToken({
from: r.oauthAccessToken.refreshId,
to: r.oauthRefreshToken.id,
}),
},
oauthConsent: {
user: r.one.user({
from: r.oauthConsent.userId,
to: r.user.id,
}),
},
}));
+357
View File
@@ -0,0 +1,357 @@
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<T extends AnyPgColumn>(column: T): SQL<T> {
return sql`lower(${column})`;
}
export const user = pg.pgTable(
"user",
{
id: pg
.uuid("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
.uuid("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
.uuid("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
.uuid("id")
.notNull()
.primaryKey()
.$defaultFn(() => generateId()),
accountId: pg.text("account_id").notNull(),
providerId: pg.text("provider_id").notNull().default("credential"),
userId: pg
.uuid("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
.uuid("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
.uuid("id")
.notNull()
.primaryKey()
.$defaultFn(() => generateId()),
userId: pg
.uuid("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),
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
.uuid("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
.uuid("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
.uuid("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
.uuid("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
.uuid("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
.uuid("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.uuid("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
.uuid("id")
.notNull()
.primaryKey()
.$defaultFn(() => generateId()),
token: pg.text("token").notNull(),
clientId: pg
.text("client_id")
.notNull()
.references(() => oauthClient.clientId, { onDelete: "cascade" }),
sessionId: pg.uuid("session_id").references(() => session.id, { onDelete: "set null" }),
userId: pg
.uuid("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
.uuid("id")
.notNull()
.primaryKey()
.$defaultFn(() => generateId()),
token: pg.text("token").notNull().unique(),
clientId: pg
.text("client_id")
.notNull()
.references(() => oauthClient.clientId, { onDelete: "cascade" }),
sessionId: pg.uuid("session_id").references(() => session.id, { onDelete: "set null" }),
userId: pg.uuid("user_id").references(() => user.id, { onDelete: "cascade" }),
referenceId: pg.text("reference_id"),
refreshId: pg.uuid("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
.uuid("id")
.notNull()
.primaryKey()
.$defaultFn(() => generateId()),
clientId: pg
.text("client_id")
.notNull()
.references(() => oauthClient.clientId, { onDelete: "cascade" }),
userId: pg.uuid("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)],
);
+2
View File
@@ -0,0 +1,2 @@
export * from "./auth";
export * from "./resume";
+92
View File
@@ -0,0 +1,92 @@
import type { StoredResumeAnalysis } from "@reactive-resume/schema/resume/analysis";
import type { ResumeData } from "@reactive-resume/schema/resume/data";
import * as pg from "drizzle-orm/pg-core";
import { defaultResumeData } from "@reactive-resume/schema/resume/default";
import { generateId } from "@reactive-resume/utils/string";
import { user } from "./auth";
export const resume = pg.pgTable(
"resume",
{
id: pg
.uuid("id")
.notNull()
.primaryKey()
.$defaultFn(() => generateId()),
name: pg.text("name").notNull(),
slug: pg.text("slug").notNull(),
tags: pg.text("tags").array().notNull().default([]),
isPublic: pg.boolean("is_public").notNull().default(false),
isLocked: pg.boolean("is_locked").notNull().default(false),
password: pg.text("password"),
data: pg
.jsonb("data")
.notNull()
.$type<ResumeData>()
.$defaultFn(() => defaultResumeData),
userId: pg
.uuid("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.unique().on(t.slug, t.userId),
pg.index().on(t.userId),
pg.index().on(t.createdAt.asc()),
pg.index().on(t.userId, t.updatedAt.desc()),
pg.index().on(t.isPublic, t.slug, t.userId),
],
);
export const resumeStatistics = pg.pgTable("resume_statistics", {
id: pg
.uuid("id")
.notNull()
.primaryKey()
.$defaultFn(() => generateId()),
views: pg.integer("views").notNull().default(0),
downloads: pg.integer("downloads").notNull().default(0),
lastViewedAt: pg.timestamp("last_viewed_at", { withTimezone: true }),
lastDownloadedAt: pg.timestamp("last_downloaded_at", { withTimezone: true }),
resumeId: pg
.uuid("resume_id")
.unique()
.notNull()
.references(() => resume.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()),
});
export const resumeAnalysis = pg.pgTable(
"resume_analysis",
{
id: pg
.uuid("id")
.notNull()
.primaryKey()
.$defaultFn(() => generateId()),
analysis: pg.jsonb("analysis").notNull().$type<StoredResumeAnalysis>(),
resumeId: pg
.uuid("resume_id")
.unique()
.notNull()
.references(() => resume.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.resumeId)],
);
+3
View File
@@ -0,0 +1,3 @@
{
"extends": "@reactive-resume/config/tsconfig.base.json"
}
+7
View File
@@ -0,0 +1,7 @@
import { fileURLToPath } from "node:url";
import { createVitestProjectConfig } from "../../vitest.shared";
export default createVitestProjectConfig({
name: "@reactive-resume/db",
dirname: fileURLToPath(new URL(".", import.meta.url)),
});