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:
@@ -0,0 +1,37 @@
|
||||
import type { DatabaseSync } from 'node:sqlite';
|
||||
import type { Alert } from '../AlertEngine.ts';
|
||||
import type { AlertProducer, ProducerFrequency } from './types.ts';
|
||||
|
||||
export type { AlertProducer, ProducerFrequency } from './types.ts';
|
||||
|
||||
const producers: AlertProducer[] = [];
|
||||
|
||||
/** Register a producer (called once at startup). */
|
||||
export function registerProducer(p: AlertProducer): void {
|
||||
producers.push(p);
|
||||
}
|
||||
|
||||
/** Run all producers for a given frequency tier. */
|
||||
export async function runProducers(
|
||||
db: DatabaseSync,
|
||||
frequency: ProducerFrequency,
|
||||
): Promise<Alert[]> {
|
||||
const results: Alert[] = [];
|
||||
const tier = producers.filter((p) => p.frequency === frequency);
|
||||
|
||||
for (const producer of tier) {
|
||||
try {
|
||||
const alerts = await producer.check(db);
|
||||
results.push(...alerts);
|
||||
} catch (err) {
|
||||
console.error(`[alert:${producer.alertType}] check failed:`, err);
|
||||
}
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
/** Get all registered producer types. */
|
||||
export function registeredAlertTypes(): string[] {
|
||||
return producers.map((p) => p.alertType);
|
||||
}
|
||||
Reference in New Issue
Block a user