import Database from 'better-sqlite3'; import path from 'path'; const db = new Database(path.join(process.cwd(), 'autotrader.sqlite')); db.pragma('foreign_keys = ON'); db.exec(` CREATE TABLE IF NOT EXISTS firms ( id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT NOT NULL UNIQUE, username TEXT NOT NULL, password TEXT NOT NULL ); CREATE TABLE IF NOT EXISTS account_configs ( id INTEGER PRIMARY KEY AUTOINCREMENT, firm_id INTEGER NOT NULL REFERENCES firms(id) ON DELETE CASCADE, prefix TEXT NOT NULL, profit_target REAL NOT NULL DEFAULT 3000, consistency REAL NOT NULL DEFAULT 0.5, min_day_pnl REAL NOT NULL DEFAULT -999, min_trading_days INTEGER NOT NULL DEFAULT 5 ); `); // Seed default data if empty const firmCount = (db.prepare('SELECT COUNT(*) as count FROM firms').get() as { count: number }).count; if (firmCount === 0) { const insertFirm = db.prepare('INSERT INTO firms (name, username, password) VALUES (?, ?, ?)'); const insertAccount = db.prepare( 'INSERT INTO account_configs (firm_id, prefix, profit_target, consistency, min_day_pnl, min_trading_days) VALUES (?, ?, ?, ?, ?, ?)' ); const alpha = insertFirm.run('Alpha', 'brandonsenoli72786', '-Z2kPm7nBg'); insertAccount.run(alpha.lastInsertRowid, 'AFSTDEV', 9000, 0.51, -999, 5); insertAccount.run(alpha.lastInsertRowid, 'AFSTDQA', 4500, 0.40, -999, 7); insertAccount.run(alpha.lastInsertRowid, 'AFZEROEV', 3000, 0.50, -999, 5); insertAccount.run(alpha.lastInsertRowid, 'AFZEROQA', 3000, 0.50, -999, 5); insertAccount.run(alpha.lastInsertRowid, 'AF', 3000, 0.50, -999, 5); const tpt = insertFirm.run('TakeProfitTrader', 'BRANDONLI1', 'W4592F5512U2817tv='); insertAccount.run(tpt.lastInsertRowid, 'TAKEPROFIT', 9000, 0.50, -999, 5); console.log('[db] Seeded default firms.'); } export interface AccountConfigRow { id: number; firm_id: number; prefix: string; profit_target: number; consistency: number; min_day_pnl: number; min_trading_days: number; } export interface FirmRow { id: number; name: string; username: string; password: string; } export interface FirmWithAccounts extends FirmRow { accounts: AccountConfigRow[]; } export function getFirms(): FirmWithAccounts[] { const firms = db.prepare('SELECT * FROM firms ORDER BY id').all() as FirmRow[]; const getAccounts = db.prepare('SELECT * FROM account_configs WHERE firm_id = ? ORDER BY id'); return firms.map((firm) => ({ ...firm, accounts: getAccounts.all(firm.id) as AccountConfigRow[], })); } export function createFirm(name: string, username: string, password: string): FirmRow { const stmt = db.prepare('INSERT INTO firms (name, username, password) VALUES (?, ?, ?)'); const result = stmt.run(name, username, password); return db.prepare('SELECT * FROM firms WHERE id = ?').get(result.lastInsertRowid) as FirmRow; } export function deleteFirm(id: number): boolean { const result = db.prepare('DELETE FROM firms WHERE id = ?').run(id); return result.changes > 0; }