Fix: PostgreSQL setup on production droplet
- Revert schema to pgTable/serial (matches PostgreSQL) - db.ts switched back to node-postgres driver - PostgreSQL 16 installed and running on 142.93.245.235 - Database: gammanexus, User: gn_admin - Same schema across local and productionmaster
parent
8763a426e0
commit
1877bb7aa7
39
server/db.ts
39
server/db.ts
|
|
@ -1,35 +1,32 @@
|
||||||
import { drizzle } from "drizzle-orm/better-sqlite3";
|
import { drizzle } from "drizzle-orm/node-postgres";
|
||||||
import { eq } from "drizzle-orm";
|
import { eq } from "drizzle-orm";
|
||||||
import { users, User, NewUser } from "../shared/schema";
|
import { users, User, NewUser } from "../shared/schema";
|
||||||
import Database from "better-sqlite3";
|
import { Pool } from "pg";
|
||||||
import path from "node:path";
|
|
||||||
import fs from "node:fs";
|
|
||||||
import { fileURLToPath } from "node:url";
|
|
||||||
|
|
||||||
const __filename = fileURLToPath(import.meta.url);
|
// PostgreSQL connection (local on production droplet)
|
||||||
const __dirname = path.dirname(__filename);
|
const pool = new Pool({
|
||||||
|
host: process.env.DB_HOST || "127.0.0.1",
|
||||||
|
port: parseInt(process.env.DB_PORT || "5432"),
|
||||||
|
user: process.env.DB_USER || "gn_admin",
|
||||||
|
password: process.env.DB_PASSWORD || "",
|
||||||
|
database: process.env.DB_NAME || "gammanexus",
|
||||||
|
ssl: (process.env.DB_SSL === "true" && process.env.NODE_ENV === "production") ? { rejectUnauthorized: false } : false,
|
||||||
|
max: 20,
|
||||||
|
idleTimeoutMillis: 30000,
|
||||||
|
connectionTimeoutMillis: 5000,
|
||||||
|
});
|
||||||
|
|
||||||
// Use SQLite for production (PostgreSQL migration later)
|
export const db = drizzle(pool);
|
||||||
const dbPath = path.resolve(__dirname, "..", "data.db");
|
|
||||||
|
|
||||||
// Ensure data directory exists
|
|
||||||
const dbDir = path.dirname(dbPath);
|
|
||||||
if (!fs.existsSync(dbDir)) {
|
|
||||||
fs.mkdirSync(dbDir, { recursive: true });
|
|
||||||
}
|
|
||||||
|
|
||||||
const sqlite = new Database(dbPath);
|
|
||||||
export const db = drizzle(sqlite);
|
|
||||||
|
|
||||||
// Initialize users table if it doesn't exist (called at startup)
|
// Initialize users table if it doesn't exist (called at startup)
|
||||||
export async function initDb(): Promise<void> {
|
export async function initDb(): Promise<void> {
|
||||||
sqlite.exec(`
|
await db.execute(`
|
||||||
CREATE TABLE IF NOT EXISTS users (
|
CREATE TABLE IF NOT EXISTS users (
|
||||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
id SERIAL PRIMARY KEY,
|
||||||
name TEXT NOT NULL,
|
name TEXT NOT NULL,
|
||||||
email TEXT NOT NULL UNIQUE,
|
email TEXT NOT NULL UNIQUE,
|
||||||
password_hash TEXT NOT NULL,
|
password_hash TEXT NOT NULL,
|
||||||
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
|
created_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW()
|
||||||
)
|
)
|
||||||
`);
|
`);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,20 +1,20 @@
|
||||||
// GammaDesk shared data model
|
// GammaDesk shared data model
|
||||||
// ORATS-style options analytics types + Drizzle tables for auth.
|
// ORATS-style options analytics types + Drizzle tables for auth.
|
||||||
// Database: SQLite (PostgreSQL migration planned later)
|
// Database: PostgreSQL
|
||||||
|
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
import { sqliteTable, text, integer } from "drizzle-orm/sqlite-core";
|
import { pgTable, text, serial, timestamp } from "drizzle-orm/pg-core";
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
// Auth - Users table (Drizzle + SQLite)
|
// Auth - Users table (Drizzle + PostgreSQL)
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
export const users = sqliteTable("users", {
|
export const users = pgTable("users", {
|
||||||
id: integer("id").primaryKey({ autoIncrement: true }),
|
id: serial("id").primaryKey(),
|
||||||
name: text("name").notNull(),
|
name: text("name").notNull(),
|
||||||
email: text("email").notNull().unique(),
|
email: text("email").notNull().unique(),
|
||||||
passwordHash: text("password_hash").notNull(),
|
passwordHash: text("password_hash").notNull(),
|
||||||
createdAt: text("created_at").default(new Date().toISOString()),
|
createdAt: timestamp("created_at", { mode: "date" }).defaultNow().notNull(),
|
||||||
});
|
});
|
||||||
|
|
||||||
export type User = typeof users.$inferSelect;
|
export type User = typeof users.$inferSelect;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue