refactor: large codebase cleanup - consolidate schemas, migrate to Drizzle ORM, extract frontend components, modernize Docker builds
Build & Deploy / build-and-push (discord-gateway) (push) Failing after 2m22s
Build & Deploy / build-and-push (backend) (push) Failing after 3m22s
Build & Deploy / build-and-push (proxy) (push) Successful in 1m36s
Build & Deploy / deploy (push) Skipped
Build & Deploy / build-and-push (discord-gateway) (push) Failing after 2m22s
Build & Deploy / build-and-push (backend) (push) Failing after 3m22s
Build & Deploy / build-and-push (proxy) (push) Successful in 1m36s
Build & Deploy / deploy (push) Skipped
- Consolidate all DB schema definitions into packages/shared as single source of truth - Migrate backend from raw SQL to Drizzle ORM across all modules - Extract frontend inline UI into separate component files - Refactor discord-gateway circuitBreaker into conversationState + moderationState - Convert messageStore to Proxy singleton pattern - Add validateBody/validateQuery middleware + Zod schemas for API endpoints - Modernize Docker builds with multi-stage + pnpm deploy - Migrate CI/CD from deployment to image-based pipeline - Remove 60+ unused/dead files (~15K lines) - Update color scheme from sky-blue to teal-cyan - Move DB connection management to @bete/shared/database Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
63f21513bd
commit
5802d02e29
@@ -1,129 +1,38 @@
|
||||
import {
|
||||
closeDatabase as sharedCloseDb,
|
||||
executeAll as sharedExecAll,
|
||||
executeGet as sharedExecGet,
|
||||
getDatabase as sharedGetDb,
|
||||
initializeDatabase as sharedInit,
|
||||
withDatabaseClient as sharedWithClient,
|
||||
} from "@bete/shared/database/init";
|
||||
import { createChildLogger } from "@bete/shared/logger";
|
||||
import { drizzle as drizzlePostgres } from "drizzle-orm/node-postgres";
|
||||
import type { PoolClient } from "pg";
|
||||
import { Pool } from "pg";
|
||||
import { config } from "../../shared/config/config.js";
|
||||
import * as schema from "./schema.js";
|
||||
|
||||
const logger = createChildLogger("drizzle");
|
||||
|
||||
let db: ReturnType<typeof drizzlePostgres> | null = null;
|
||||
let rawPool: Pool | null = null;
|
||||
const dbConfig = {
|
||||
DATABASE_URL: config.DATABASE_URL,
|
||||
POSTGRES_HOST: config.POSTGRES_HOST,
|
||||
POSTGRES_PORT: config.POSTGRES_PORT,
|
||||
POSTGRES_USER: config.POSTGRES_USER,
|
||||
POSTGRES_PASSWORD: config.POSTGRES_PASSWORD,
|
||||
POSTGRES_DB: config.POSTGRES_DB,
|
||||
POSTGRES_POOL_MIN: config.POSTGRES_POOL_MIN,
|
||||
POSTGRES_POOL_MAX: config.POSTGRES_POOL_MAX,
|
||||
};
|
||||
|
||||
/**
|
||||
* Initialize the PostgreSQL database connection.
|
||||
*/
|
||||
export async function initializeDatabase() {
|
||||
if (db !== null) {
|
||||
return db;
|
||||
}
|
||||
|
||||
let pool: Pool;
|
||||
|
||||
if (config.DATABASE_URL) {
|
||||
pool = new Pool({
|
||||
connectionString: config.DATABASE_URL,
|
||||
min: config.POSTGRES_POOL_MIN,
|
||||
max: config.POSTGRES_POOL_MAX,
|
||||
});
|
||||
} else {
|
||||
pool = new Pool({
|
||||
host: config.POSTGRES_HOST,
|
||||
port: config.POSTGRES_PORT,
|
||||
user: config.POSTGRES_USER,
|
||||
password: config.POSTGRES_PASSWORD,
|
||||
database: config.POSTGRES_DB,
|
||||
min: config.POSTGRES_POOL_MIN,
|
||||
max: config.POSTGRES_POOL_MAX,
|
||||
});
|
||||
}
|
||||
|
||||
rawPool = pool;
|
||||
db = drizzlePostgres(pool, { schema });
|
||||
|
||||
try {
|
||||
(db as { run?: (sql: string) => Promise<unknown> }).run = (sql: string) =>
|
||||
pool.query(sql);
|
||||
} catch {
|
||||
// ignore
|
||||
}
|
||||
|
||||
logger.info("PostgreSQL database initialized");
|
||||
return db;
|
||||
logger.info("Initializing database");
|
||||
return sharedInit(dbConfig, schema);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the initialized database instance.
|
||||
* Throws if database has not been initialized.
|
||||
*/
|
||||
export function getDatabase() {
|
||||
if (db === null) {
|
||||
throw new Error(
|
||||
"Database not initialized. Call initializeDatabase() first.",
|
||||
);
|
||||
}
|
||||
return db;
|
||||
return sharedGetDb();
|
||||
}
|
||||
|
||||
function convertPlaceholdersForPostgres(sql: string) {
|
||||
let i = 0;
|
||||
return sql.replace(/\?/g, () => `$${++i}`);
|
||||
}
|
||||
|
||||
export async function executeAll(sql: string, params?: unknown[]) {
|
||||
if (!rawPool) {
|
||||
throw new Error(
|
||||
"Database not initialized. Call initializeDatabase() first.",
|
||||
);
|
||||
}
|
||||
|
||||
const query = convertPlaceholdersForPostgres(sql);
|
||||
const result = await rawPool.query(query, params || []);
|
||||
return result.rows;
|
||||
}
|
||||
|
||||
export async function executeGet(sql: string, params?: unknown[]) {
|
||||
if (!rawPool) {
|
||||
throw new Error(
|
||||
"Database not initialized. Call initializeDatabase() first.",
|
||||
);
|
||||
}
|
||||
|
||||
const query = convertPlaceholdersForPostgres(sql);
|
||||
const result = await rawPool.query(query, params || []);
|
||||
return result.rows[0] ?? null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Run a function with a dedicated PostgreSQL client from the shared pool.
|
||||
* Use this for session-scoped operations such as advisory locks.
|
||||
*/
|
||||
export async function withDatabaseClient<T>(
|
||||
callback: (client: PoolClient) => Promise<T>,
|
||||
): Promise<T> {
|
||||
if (!rawPool) {
|
||||
throw new Error(
|
||||
"Database not initialized. Call initializeDatabase() first.",
|
||||
);
|
||||
}
|
||||
|
||||
const client = await rawPool.connect();
|
||||
try {
|
||||
return await callback(client);
|
||||
} finally {
|
||||
client.release();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Close the PostgreSQL connection pool.
|
||||
*/
|
||||
export async function closeDatabase() {
|
||||
if (rawPool !== null) {
|
||||
await rawPool.end();
|
||||
}
|
||||
|
||||
rawPool = null;
|
||||
db = null;
|
||||
logger.info("PostgreSQL database closed");
|
||||
}
|
||||
export const closeDatabase = sharedCloseDb;
|
||||
export const executeAll = sharedExecAll;
|
||||
export const executeGet = sharedExecGet;
|
||||
export const withDatabaseClient = sharedWithClient;
|
||||
|
||||
Reference in New Issue
Block a user