From ffdc8c5b6cd4d133e5ad0428b6c9b9f6cab173b3 Mon Sep 17 00:00:00 2001 From: kaunghtut24 Date: Mon, 16 Jun 2025 15:36:08 +0530 Subject: [PATCH] feat: prepare for Vercel deployment with PostgreSQL migration --- drizzle.config.ts | 9 ++++++--- next.config.mjs | 10 +++++++++- package.json | 13 ++++++++++--- src/lib/db/index.ts | 10 ++++------ src/lib/db/migrate.ts | 23 ++++++++++++++++++++--- src/lib/db/schema.ts | 19 ++++++++----------- vercel-post-deploy.js | 14 ++++++++++++++ vercel.json | 26 ++++++++++++++++++++++++++ 8 files changed, 97 insertions(+), 27 deletions(-) create mode 100644 vercel-post-deploy.js create mode 100644 vercel.json diff --git a/drizzle.config.ts b/drizzle.config.ts index a029112..e2cdd68 100644 --- a/drizzle.config.ts +++ b/drizzle.config.ts @@ -1,11 +1,14 @@ import { defineConfig } from 'drizzle-kit'; -import path from 'path'; +import * as dotenv from 'dotenv'; +dotenv.config(); export default defineConfig({ - dialect: 'sqlite', schema: './src/lib/db/schema.ts', out: './drizzle', + driver: 'pg', dbCredentials: { - url: path.join(process.cwd(), 'data', 'db.sqlite'), + connectionString: process.env.POSTGRES_URL!, }, + verbose: true, + strict: true, }); diff --git a/next.config.mjs b/next.config.mjs index 2300ff4..82d9598 100644 --- a/next.config.mjs +++ b/next.config.mjs @@ -8,7 +8,15 @@ const nextConfig = { }, ], }, - serverExternalPackages: ['pdf-parse'], + // Enable experimental features for better performance + experimental: { + serverActions: true, + serverComponentsExternalPackages: ['@vercel/postgres'], + }, + // Configure environment variables + env: { + POSTGRES_URL: process.env.POSTGRES_URL, + }, }; export default nextConfig; diff --git a/package.json b/package.json index f62543b..8865da1 100644 --- a/package.json +++ b/package.json @@ -9,7 +9,11 @@ "start": "next start", "lint": "next lint", "format:write": "prettier . --write", - "db:push": "drizzle-kit push" + "db:push": "drizzle-kit push:pg", + "db:generate": "drizzle-kit generate:pg", + "db:migrate": "tsx src/lib/db/migrate.ts", + "db:studio": "drizzle-kit studio", + "postdeploy": "node vercel-post-deploy.js" }, "dependencies": { "@headlessui/react": "^2.2.0", @@ -46,7 +50,9 @@ "tailwind-merge": "^2.2.2", "winston": "^3.17.0", "yet-another-react-lightbox": "^3.17.2", - "zod": "^3.22.4" + "zod": "^3.22.4", + "pg": "^8.11.3", + "@vercel/postgres": "^0.7.2" }, "devDependencies": { "@types/better-sqlite3": "^7.6.12", @@ -63,6 +69,7 @@ "postcss": "^8", "prettier": "^3.2.5", "tailwindcss": "^3.3.0", - "typescript": "^5" + "typescript": "^5", + "@types/pg": "^8.11.2" } } diff --git a/src/lib/db/index.ts b/src/lib/db/index.ts index 515cdb3..451745a 100644 --- a/src/lib/db/index.ts +++ b/src/lib/db/index.ts @@ -1,11 +1,9 @@ -import { drizzle } from 'drizzle-orm/better-sqlite3'; -import Database from 'better-sqlite3'; +import { drizzle } from 'drizzle-orm/vercel-postgres'; +import { sql } from '@vercel/postgres'; import * as schema from './schema'; -import path from 'path'; -const DATA_DIR = process.env.DATA_DIR || process.cwd(); -const sqlite = new Database(path.join(DATA_DIR, './data/db.sqlite')); -const db = drizzle(sqlite, { +// Create a PostgreSQL client using Vercel Postgres +const db = drizzle(sql, { schema: schema, }); diff --git a/src/lib/db/migrate.ts b/src/lib/db/migrate.ts index c3ebff6..f8315b0 100644 --- a/src/lib/db/migrate.ts +++ b/src/lib/db/migrate.ts @@ -1,5 +1,22 @@ -import db from './'; -import { migrate } from 'drizzle-orm/better-sqlite3/migrator'; +import { drizzle } from 'drizzle-orm/vercel-postgres'; +import { migrate } from 'drizzle-orm/vercel-postgres/migrator'; +import { sql } from '@vercel/postgres'; import path from 'path'; -migrate(db, { migrationsFolder: path.join(process.cwd(), 'drizzle') }); +async function main() { + const db = drizzle(sql); + + console.log('Running migrations...'); + + await migrate(db, { migrationsFolder: path.join(process.cwd(), 'drizzle') }); + + console.log('Migrations completed!'); + + process.exit(0); +} + +main().catch((err) => { + console.error('Migration failed!'); + console.error(err); + process.exit(1); +}); diff --git a/src/lib/db/schema.ts b/src/lib/db/schema.ts index cee9660..b5a851a 100644 --- a/src/lib/db/schema.ts +++ b/src/lib/db/schema.ts @@ -1,15 +1,14 @@ import { sql } from 'drizzle-orm'; -import { text, integer, sqliteTable } from 'drizzle-orm/sqlite-core'; +import { text, integer, pgTable, timestamp, jsonb } from 'drizzle-orm/pg-core'; -export const messages = sqliteTable('messages', { - id: integer('id').primaryKey(), +export const messages = pgTable('messages', { + id: integer('id').primaryKey().notNull(), content: text('content').notNull(), chatId: text('chatId').notNull(), messageId: text('messageId').notNull(), role: text('type', { enum: ['assistant', 'user'] }), - metadata: text('metadata', { - mode: 'json', - }), + metadata: jsonb('metadata'), + createdAt: timestamp('created_at').defaultNow(), }); interface File { @@ -17,12 +16,10 @@ interface File { fileId: string; } -export const chats = sqliteTable('chats', { +export const chats = pgTable('chats', { id: text('id').primaryKey(), title: text('title').notNull(), - createdAt: text('createdAt').notNull(), + createdAt: timestamp('created_at').defaultNow(), focusMode: text('focusMode').notNull(), - files: text('files', { mode: 'json' }) - .$type() - .default(sql`'[]'`), + files: jsonb('files').$type().default(sql`'[]'::jsonb`), }); diff --git a/vercel-post-deploy.js b/vercel-post-deploy.js new file mode 100644 index 0000000..ad08f51 --- /dev/null +++ b/vercel-post-deploy.js @@ -0,0 +1,14 @@ +const { execSync } = require('child_process'); + +async function runMigrations() { + try { + console.log('Running database migrations...'); + execSync('npm run db:migrate', { stdio: 'inherit' }); + console.log('Migrations completed successfully!'); + } catch (error) { + console.error('Migration failed:', error); + process.exit(1); + } +} + +runMigrations(); \ No newline at end of file diff --git a/vercel.json b/vercel.json new file mode 100644 index 0000000..0136a19 --- /dev/null +++ b/vercel.json @@ -0,0 +1,26 @@ +{ + "version": 2, + "buildCommand": "npm run build", + "installCommand": "npm install", + "framework": "nextjs", + "builds": [ + { + "src": "package.json", + "use": "@vercel/next" + } + ], + "env": { + "POSTGRES_URL": "@postgres_url", + "OPENAI_API_KEY": "@openai_api_key", + "GROQ_API_KEY": "@groq_api_key", + "ANTHROPIC_API_KEY": "@anthropic_api_key", + "GEMINI_API_KEY": "@gemini_api_key", + "DEEPSEEK_API_KEY": "@deepseek_api_key", + "SEARXNG_API_URL": "@searxng_api_url", + "OLLAMA_API_URL": "@ollama_api_url", + "LM_STUDIO_API_URL": "@lm_studio_api_url", + "CUSTOM_OPENAI_API_URL": "@custom_openai_api_url", + "CUSTOM_OPENAI_API_KEY": "@custom_openai_api_key", + "CUSTOM_OPENAI_MODEL_NAME": "@custom_openai_model_name" + } +} \ No newline at end of file