Phase 5: alert subscriptions UI + multiple watchlists + queue fixes
CI / Test & Type-Check (push) Canceled after 0s
CI / Test & Type-Check (push) Canceled after 0s
UI: - /alerts page: event history with acknowledge, subscription create/manage with toggle - /admin/smtp: SMTP config form (host, port, auth, test) - Watchlist sidebar: dropdown selector for multiple watchlists, create/delete - Sidebar: alerts count badge, SMTP link under admin - Mobile tab nav: alerts tab added - Client trpc.ts: all new API methods + types Backend: - watchlists.listByWatchlist procedure + listSymbolsByWatchlist repo fn - yfinance min-interval 1500->2000ms to reduce Edge 429s - Fixed e.date.slice error in yfinance-adjustments with typeof guard - Removed defunct BITF from watchlist+queue - Cleared 83 failed + 12 backoff queue jobs Docs: - FUNCTIONAL_DESIGN.md: alerts + multiple watchlists + SMTP documented - TECH_DESIGN.md: new modules, tRPC procs, routes updated
This commit is contained in:
@@ -134,7 +134,12 @@ function runMigrations(db: DatabaseSync): void {
|
||||
db.exec(`CREATE UNIQUE INDEX IF NOT EXISTS uq_inst_filings ON institution_filings(filer_cik, symbol, reported_quarter, form)`);
|
||||
} catch { /* ignore */ }
|
||||
|
||||
// 4. Data-quality lint table.
|
||||
// 4. Rename legacy 'Starter' watchlist to 'default'.
|
||||
try {
|
||||
db.exec(`UPDATE watchlists SET name='default' WHERE name='Starter'`);
|
||||
} catch { /* ignore */ }
|
||||
|
||||
// 5. Data-quality lint table.
|
||||
try {
|
||||
db.exec(`
|
||||
CREATE TABLE IF NOT EXISTS data_quality (
|
||||
@@ -152,7 +157,7 @@ function runMigrations(db: DatabaseSync): void {
|
||||
`);
|
||||
} catch { /* ignore */ }
|
||||
|
||||
// 5. Analyst ratings / upgrades & downgrades (yahoo-finance2).
|
||||
// 6. Analyst ratings / upgrades & downgrades (yahoo-finance2).
|
||||
try { db.exec(`ALTER TABLE analyst_ratings ADD COLUMN target_from REAL`); } catch { /* ignore */ }
|
||||
try { db.exec(`ALTER TABLE analyst_ratings ADD COLUMN target_to REAL`); } catch { /* ignore */ }
|
||||
try {
|
||||
@@ -182,6 +187,41 @@ function runMigrations(db: DatabaseSync): void {
|
||||
strong_sell INTEGER NOT NULL DEFAULT 0,
|
||||
fetched_at TEXT NOT NULL
|
||||
)
|
||||
`);
|
||||
} catch { /* ignore */ }
|
||||
|
||||
// 7. Alert subscriptions: add watchlist_id + enabled columns (existing DBs).
|
||||
try { db.exec(`ALTER TABLE alerts ADD COLUMN watchlist_id TEXT`); } catch { /* ignore */ }
|
||||
try { db.exec(`ALTER TABLE alerts ADD COLUMN enabled INTEGER NOT NULL DEFAULT 1`); } catch { /* ignore */ }
|
||||
|
||||
// 8. Alert comparison state table.
|
||||
try {
|
||||
db.exec(`
|
||||
CREATE TABLE IF NOT EXISTS alert_comparison_state (
|
||||
symbol TEXT NOT NULL,
|
||||
alert_type TEXT NOT NULL,
|
||||
state TEXT NOT NULL DEFAULT '{}',
|
||||
updated_at TEXT NOT NULL,
|
||||
PRIMARY KEY (symbol, alert_type)
|
||||
)
|
||||
`);
|
||||
} catch { /* ignore */ }
|
||||
|
||||
// 9. SMTP config table for email alerts.
|
||||
try {
|
||||
db.exec(`
|
||||
CREATE TABLE IF NOT EXISTS smtp_config (
|
||||
id TEXT PRIMARY KEY DEFAULT 'singleton',
|
||||
host TEXT NOT NULL DEFAULT 'smtp.mail.me.com',
|
||||
port INTEGER NOT NULL DEFAULT 587,
|
||||
secure INTEGER NOT NULL DEFAULT 0,
|
||||
user TEXT,
|
||||
pass_enc TEXT,
|
||||
from_name TEXT NOT NULL DEFAULT 'Investor Flow',
|
||||
from_email TEXT NOT NULL DEFAULT '',
|
||||
enabled INTEGER NOT NULL DEFAULT 0,
|
||||
updated_at TEXT NOT NULL
|
||||
)
|
||||
`);
|
||||
} catch { /* ignore */ }
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user