spb/vquant Public MIT
VibeQuant — AI-powered institutional-grade financial intelligence platform.
TypeScript 84.3%
Python 11.7%
JavaScript 1.6%
CSS 1.5%
HTML 0.7%
1/*2 * =============================================================================3 * VibeQuant (vquant) — AI-Powered Financial Intelligence Platform4 * -----------------------------------------------------------------------------5 * File: server/db.ts6 *7 * Author: Simon-Pierre Boucher8 * Contact: contact@spboucher.ai9 * Website: https://www.spboucher.ai10 * Demo: https://www.vquant.ai11 * License: MIT (see LICENSE)12 *13 * Copyright © 2026 Simon-Pierre Boucher. All rights reserved.14 * =============================================================================15 */1617import { Pool as NeonPool, neonConfig } from '@neondatabase/serverless';18import { drizzle as drizzleNeon } from 'drizzle-orm/neon-serverless';19import { drizzle as drizzleNode } from 'drizzle-orm/node-postgres';20import { drizzle as drizzleSqlite, type BetterSQLite3Database } from 'drizzle-orm/better-sqlite3';21import type { NodePgDatabase } from 'drizzle-orm/node-postgres';22import type { NeonDatabase } from 'drizzle-orm/neon-serverless';23import { Pool as PgPool } from 'pg';24import Database from 'better-sqlite3';25import ws from "ws";26import * as schemaPg from "@shared/schema";27import * as schemaSqlite from "@shared/schema-sqlite";28import path from 'path';29import { logger } from './utils/logger';3031const databaseUrl = process.env.DATABASE_URL || 'sqlite://local.db';3233const isSqlite = databaseUrl.startsWith('sqlite://');34const isLocalDb = databaseUrl.includes('localhost') || databaseUrl.includes('127.0.0.1');3536// Both schemas export the same table names and structure.37// We use the SQLite schema as the canonical type since it's the superset.38type AppSchema = typeof schemaSqlite;39type AppDb = BetterSQLite3Database<AppSchema> | NodePgDatabase<typeof schemaPg> | NeonDatabase<typeof schemaPg>;40type AppPool = Database.Database | PgPool | NeonPool;4142let pool: AppPool;43let db: AppDb;44let schema: AppSchema;4546if (isSqlite) {47 const dbPath = databaseUrl.replace('sqlite://', '');48 const fullPath = path.isAbsolute(dbPath) ? dbPath : path.join(process.cwd(), dbPath);4950 const sqlite = new Database(fullPath);51 sqlite.pragma('journal_mode = WAL');5253 db = drizzleSqlite(sqlite, { schema: schemaSqlite });54 pool = sqlite;55 schema = schemaSqlite;5657 logger.info(`Using SQLite database at: ${fullPath}`);58} else if (isLocalDb) {59 const pgPool = new PgPool({ connectionString: databaseUrl });60 db = drizzleNode(pgPool, { schema: schemaPg });61 pool = pgPool;62 schema = schemaPg as unknown as AppSchema;6364 logger.info('Using local PostgreSQL database');65} else {66 neonConfig.webSocketConstructor = ws;67 const neonPool = new NeonPool({ connectionString: databaseUrl });68 db = drizzleNeon({ client: neonPool, schema: schemaPg });69 pool = neonPool;70 schema = schemaPg as unknown as AppSchema;7172 logger.info('Using Neon serverless PostgreSQL database');73}7475export { pool, db, schema, isSqlite };76export type { AppDb, AppPool, AppSchema };77