/** * One-shot news poll — for cron users who don't run the server 24/7. * Fetches EDGAR + PR-wire feeds once, runs the pipeline, runs retention, * prints stats, exits. * * Usage: * npm run news:poll * * Crontab example (every 15 min, market hours, weekdays): * *\/15 9-16 * * 1-5 cd /path/to/market_screener && npm run news:poll * * If the server runs continuously, its built-in scheduler covers this — * set NEWS_POLL=off on the server if you prefer cron-driven polling. */ import 'dotenv/config'; import { createDb, DatabaseConnection, QueryAudit, noopLogger } from '../server/domains/shared'; import { NewsRepository, NewsPipeline, UniverseProvider, NewsScheduler, EdgarPoller, PrWirePoller, } from '../server/domains/news'; const db = new DatabaseConnection(createDb(process.env.DB_PATH ?? './market-screener.db'), { audit: new QueryAudit(), logSlowQueries: 100, }); const consoleLogger = { log: (...args: unknown[]) => console.log(...args), // eslint-disable-line no-console warn: (...args: unknown[]) => console.warn(...args), write: (msg: string) => process.stdout.write(msg), }; const universe = new UniverseProvider(db); const pipeline = new NewsPipeline(new NewsRepository(db)); const scheduler = new NewsScheduler( pipeline, universe, new EdgarPoller(noopLogger), new PrWirePoller(noopLogger), consoleLogger, ); const size = universe.getUniverse().size; if (size === 0) { console.log('Universe is empty (no watchlist, holdings, or recent screens) — nothing to poll.'); // eslint-disable-line no-console process.exit(0); } console.log(`Polling news for a ${size}-ticker universe…`); // eslint-disable-line no-console try { const { edgar, prwire } = await scheduler.runOnce(); const retention = pipeline.runRetention(); /* eslint-disable no-console */ console.log('\nEDGAR :', JSON.stringify(edgar)); console.log('PR-wire:', JSON.stringify(prwire)); console.log('Retention:', JSON.stringify(retention)); /* eslint-enable no-console */ process.exit(0); } catch (err) { console.error('News poll failed:', (err as Error).message); process.exit(1); }