UI enhancemnts
This commit is contained in:
@@ -139,6 +139,15 @@ export class DatabaseConnection {
|
||||
return txn();
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute a raw SQL SELECT and return all rows.
|
||||
* Use only when QueryBuilder is not practical (e.g. static named queries).
|
||||
*/
|
||||
rawAll<T = Record<string, unknown>>(sql: string, params: unknown[] = []): T[] {
|
||||
const stmt = this.getOrCacheStatement(sql);
|
||||
return stmt.all(...params) as T[];
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute a raw SQL SELECT and return the first row.
|
||||
* Use only when QueryBuilder is not practical (e.g. auth domain with static queries).
|
||||
|
||||
@@ -130,6 +130,82 @@ export const RESET_TOKEN_QUERIES = {
|
||||
|
||||
// ── Schema Definition (DDL) ──────────────────────────────────────────────────
|
||||
|
||||
// ── Watchlist Queries ────────────────────────────────────────────────────────
|
||||
|
||||
export const WATCHLIST_QUERIES = {
|
||||
SELECT_ALL: `
|
||||
SELECT ticker, pinned_at
|
||||
FROM watchlist
|
||||
WHERE user_id = ?
|
||||
ORDER BY pinned_at DESC
|
||||
`,
|
||||
INSERT: `
|
||||
INSERT OR IGNORE INTO watchlist (ticker, user_id, pinned_at)
|
||||
VALUES (?, ?, ?)
|
||||
`,
|
||||
DELETE: `
|
||||
DELETE FROM watchlist WHERE ticker = ? AND user_id = ?
|
||||
`,
|
||||
EXISTS: `
|
||||
SELECT 1 FROM watchlist WHERE ticker = ? AND user_id = ?
|
||||
`,
|
||||
};
|
||||
|
||||
// ── Signal Snapshot Queries (P0.1 — signal track record) ────────────────────
|
||||
|
||||
export const SIGNAL_SNAPSHOT_QUERIES = {
|
||||
// One row per ticker per day — repeated screens the same day keep the latest
|
||||
UPSERT: `
|
||||
INSERT INTO signal_snapshots (
|
||||
ticker, snapshot_date, asset_type, price, signal,
|
||||
fundamental_tier, fundamental_score, fundamental_label,
|
||||
inflated_tier, inflated_score, inflated_label,
|
||||
coverage_active, coverage_total, risk_flags, rate_regime, created_at
|
||||
)
|
||||
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
||||
ON CONFLICT(ticker, snapshot_date) DO UPDATE SET
|
||||
asset_type = excluded.asset_type,
|
||||
price = excluded.price,
|
||||
signal = excluded.signal,
|
||||
fundamental_tier = excluded.fundamental_tier,
|
||||
fundamental_score = excluded.fundamental_score,
|
||||
fundamental_label = excluded.fundamental_label,
|
||||
inflated_tier = excluded.inflated_tier,
|
||||
inflated_score = excluded.inflated_score,
|
||||
inflated_label = excluded.inflated_label,
|
||||
coverage_active = excluded.coverage_active,
|
||||
coverage_total = excluded.coverage_total,
|
||||
risk_flags = excluded.risk_flags,
|
||||
rate_regime = excluded.rate_regime,
|
||||
created_at = excluded.created_at
|
||||
`,
|
||||
|
||||
// Full history for one ticker, oldest first (for trend/backtest views)
|
||||
SELECT_BY_TICKER: `
|
||||
SELECT * FROM signal_snapshots
|
||||
WHERE ticker = ?
|
||||
ORDER BY snapshot_date ASC
|
||||
`,
|
||||
|
||||
// All snapshots for one day (for daily diff jobs)
|
||||
SELECT_BY_DATE: `
|
||||
SELECT * FROM signal_snapshots
|
||||
WHERE snapshot_date = ?
|
||||
ORDER BY ticker ASC
|
||||
`,
|
||||
|
||||
// Latest snapshot per ticker on or before a given date (for change detection)
|
||||
SELECT_LATEST_BEFORE: `
|
||||
SELECT s.* FROM signal_snapshots s
|
||||
JOIN (
|
||||
SELECT ticker, MAX(snapshot_date) AS d
|
||||
FROM signal_snapshots
|
||||
WHERE snapshot_date < ?
|
||||
GROUP BY ticker
|
||||
) latest ON latest.ticker = s.ticker AND latest.d = s.snapshot_date
|
||||
`,
|
||||
};
|
||||
|
||||
export const DDL = `
|
||||
CREATE TABLE IF NOT EXISTS users (
|
||||
id TEXT PRIMARY KEY,
|
||||
@@ -167,6 +243,36 @@ export const DDL = `
|
||||
snapshot TEXT NOT NULL, -- JSON object
|
||||
created_at TEXT NOT NULL
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS watchlist (
|
||||
ticker TEXT NOT NULL,
|
||||
user_id TEXT NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
||||
pinned_at TEXT NOT NULL,
|
||||
PRIMARY KEY (ticker, user_id)
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS signal_snapshots (
|
||||
ticker TEXT NOT NULL,
|
||||
snapshot_date TEXT NOT NULL, -- YYYY-MM-DD
|
||||
asset_type TEXT NOT NULL, -- STOCK / ETF / BOND
|
||||
price REAL,
|
||||
signal TEXT NOT NULL, -- ✅ Strong Buy etc.
|
||||
fundamental_tier TEXT NOT NULL, -- PASS / HOLD / REJECT
|
||||
fundamental_score REAL,
|
||||
fundamental_label TEXT,
|
||||
inflated_tier TEXT NOT NULL,
|
||||
inflated_score REAL,
|
||||
inflated_label TEXT,
|
||||
coverage_active INTEGER,
|
||||
coverage_total INTEGER,
|
||||
risk_flags TEXT, -- JSON array
|
||||
rate_regime TEXT,
|
||||
created_at TEXT NOT NULL,
|
||||
PRIMARY KEY (ticker, snapshot_date)
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_snapshots_date ON signal_snapshots(snapshot_date);
|
||||
CREATE INDEX IF NOT EXISTS idx_snapshots_signal ON signal_snapshots(signal, snapshot_date);
|
||||
`;
|
||||
|
||||
// ── Runtime migrations (ALTER TABLE for existing DBs) ────────────────────────
|
||||
|
||||
Reference in New Issue
Block a user