import type { FastifyInstance, FastifyRequest } from 'fastify'; import { ScreenerEngine, CatalystAnalyst } from '../services/index'; import { noopLogger } from '../utils/logger'; import type { LiveAssetResult } from '../types'; import { screenSchema } from '../types/schemas'; export class ScreenerController { constructor(private readonly engine: ScreenerEngine) {} register(app: FastifyInstance): void { app.post('/api/screen', { schema: screenSchema }, this.screen.bind(this)); app.get('/api/screen/catalysts', this.catalysts.bind(this)); } private static serializeAssets(arr: LiveAssetResult[]) { return arr.map((r) => ({ ...r, asset: { ticker: r.asset.ticker, type: r.asset.type, currentPrice: r.asset.currentPrice, metrics: r.asset.metrics, displayMetrics: r.asset.getDisplayMetrics(), }, })); } private async screen(req: FastifyRequest) { const tickers = (req.body as { tickers: string[] }).tickers.map((t) => t.toUpperCase()); const results = await this.engine.screenTickers(tickers); return { ...results, STOCK: ScreenerController.serializeAssets(results.STOCK as LiveAssetResult[]), ETF: ScreenerController.serializeAssets(results.ETF as LiveAssetResult[]), BOND: ScreenerController.serializeAssets(results.BOND as LiveAssetResult[]), }; } private async catalysts() { const catalyst = new CatalystAnalyst({ logger: noopLogger }); const { tickers, stories } = await catalyst.run(); return { tickers, stories }; } }