2e7860637e
- Restructured server layer with 5 domains: shared, screener, portfolio, calls, finance - Migrated 58 TypeScript files to domain-driven structure - Updated CLAUDE.md with new architecture documentation - Added .gitignore rules for .md files (except CLAUDE.md) - Removed unused CatalystAnalyst import from app.ts - Fixed lint errors: removed unused imports, fixed regex escape, added console suppressions - Verified no sensitive data in git history - Server code compiles cleanly with TypeScript strict mode
101 lines
3.3 KiB
TypeScript
101 lines
3.3 KiB
TypeScript
/**
|
|
* SQL Query Constants
|
|
*
|
|
* All SQL queries used in the application.
|
|
* Repositories reference these by name (e.g., MARKET_CALLS_QUERIES.SELECT_ALL).
|
|
* QueryBuilder looks them up and binds parameters.
|
|
*
|
|
* All queries use parameterized statements (?) for security.
|
|
* User input NEVER goes into the SQL string.
|
|
*/
|
|
|
|
// ── Holdings Table Queries ───────────────────────────────────────────────────
|
|
|
|
export const HOLDINGS_QUERIES = {
|
|
// Check if any holdings exist
|
|
EXISTS: 'SELECT COUNT(*) AS n FROM holdings',
|
|
|
|
// Get all holdings, sorted by ticker
|
|
SELECT_ALL: 'SELECT ticker, shares, cost_basis, type, source FROM holdings ORDER BY ticker ASC',
|
|
|
|
// Insert or update a holding (UPSERT)
|
|
UPSERT: `
|
|
INSERT INTO holdings (ticker, shares, cost_basis, type, source)
|
|
VALUES (?, ?, ?, ?, ?)
|
|
ON CONFLICT(ticker) DO UPDATE SET
|
|
shares = excluded.shares,
|
|
cost_basis = excluded.cost_basis,
|
|
type = excluded.type,
|
|
source = excluded.source
|
|
`,
|
|
|
|
// Delete a holding by ticker
|
|
DELETE_BY_TICKER: 'DELETE FROM holdings WHERE ticker = ?',
|
|
};
|
|
|
|
// ── Market Calls Table Queries ───────────────────────────────────────────────
|
|
|
|
export const MARKET_CALLS_QUERIES = {
|
|
// Get all market calls, newest first
|
|
SELECT_ALL: `
|
|
SELECT id, title, quarter, date, thesis, tickers, snapshot, created_at
|
|
FROM market_calls
|
|
ORDER BY created_at DESC
|
|
`,
|
|
|
|
// Get a single market call by ID
|
|
SELECT_BY_ID: `
|
|
SELECT id, title, quarter, date, thesis, tickers, snapshot, created_at
|
|
FROM market_calls
|
|
WHERE id = ?
|
|
`,
|
|
|
|
// Insert a new market call
|
|
INSERT: `
|
|
INSERT INTO market_calls (id, title, quarter, date, thesis, tickers, snapshot, created_at)
|
|
VALUES (?, ?, ?, ?, ?, ?, ?, ?)
|
|
`,
|
|
|
|
// Delete a market call by ID
|
|
DELETE_BY_ID: 'DELETE FROM market_calls WHERE id = ?',
|
|
};
|
|
|
|
// ── Migration Queries (for DatabaseInitializer) ──────────────────────────────
|
|
|
|
export const MIGRATION_QUERIES = {
|
|
// Insert holdings during migration
|
|
HOLDINGS_INSERT_OR_IGNORE: `
|
|
INSERT OR IGNORE INTO holdings (ticker, shares, cost_basis, type, source)
|
|
VALUES (?, ?, ?, ?, ?)
|
|
`,
|
|
|
|
// Insert market calls during migration
|
|
MARKET_CALLS_INSERT_OR_IGNORE: `
|
|
INSERT OR IGNORE INTO market_calls (id, title, quarter, date, thesis, tickers, snapshot, created_at)
|
|
VALUES (?, ?, ?, ?, ?, ?, ?, ?)
|
|
`,
|
|
};
|
|
|
|
// ── Schema Definition (DDL) ──────────────────────────────────────────────────
|
|
|
|
export const DDL = `
|
|
CREATE TABLE IF NOT EXISTS holdings (
|
|
ticker TEXT PRIMARY KEY,
|
|
shares REAL NOT NULL,
|
|
cost_basis REAL NOT NULL DEFAULT 0,
|
|
type TEXT NOT NULL DEFAULT 'stock',
|
|
source TEXT NOT NULL DEFAULT 'Manual'
|
|
);
|
|
|
|
CREATE TABLE IF NOT EXISTS market_calls (
|
|
id TEXT PRIMARY KEY,
|
|
title TEXT NOT NULL,
|
|
quarter TEXT NOT NULL,
|
|
date TEXT NOT NULL,
|
|
thesis TEXT NOT NULL,
|
|
tickers TEXT NOT NULL, -- JSON array
|
|
snapshot TEXT NOT NULL, -- JSON object
|
|
created_at TEXT NOT NULL
|
|
);
|
|
`;
|