feat: prepare for Vercel deployment with PostgreSQL migration

This commit is contained in:
kaunghtut24 2025-06-16 15:36:08 +05:30
parent 38ab8a260c
commit ffdc8c5b6c
8 changed files with 97 additions and 27 deletions

View file

@ -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,
});

View file

@ -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;

View file

@ -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"
}
}

View file

@ -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,
});

View file

@ -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);
});

View file

@ -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<File[]>()
.default(sql`'[]'`),
files: jsonb('files').$type<File[]>().default(sql`'[]'::jsonb`),
});

14
vercel-post-deploy.js Normal file
View file

@ -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();

26
vercel.json Normal file
View file

@ -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"
}
}