import Fastify from 'fastify'; import cors from '@fastify/cors'; import { ScreenerController } from './controllers/screener.controller'; import { FinanceController } from './controllers/finance.controller'; import { CallsController } from './controllers/calls.controller'; import { AnalyzeController } from './controllers/analyze.controller'; import { ScreenerEngine } from './services/ScreenerEngine'; import { LLMAnalyst } from './services/LLMAnalyst'; import { CatalystAnalyst } from './services/CatalystAnalyst'; import { YahooFinanceClient } from './clients/YahooFinanceClient'; import { MarketCallRepository } from './repositories/MarketCallRepository'; import { PortfolioRepository } from './repositories/PortfolioRepository'; import { noopLogger } from './utils/logger'; interface BuildAppOptions { logger?: boolean; } // ── Adding a new domain ─────────────────────────────────────────────────── // 1. server/types/.model.ts — define request/response shapes // 2. server/services/.ts — business logic // 3. server/controllers/.controller.ts — HTTP wiring (class + register) // 4. Register: new Controller(...).register(app) ← add below // ─────────────────────────────────────────────────────────────────────────── export async function buildApp({ logger = true }: BuildAppOptions = {}) { const app = Fastify({ logger }); await app.register(cors, { origin: process.env.CLIENT_ORIGIN ?? 'http://localhost:5173', }); const engine = new ScreenerEngine({ logger: noopLogger }); const yahoo = new YahooFinanceClient(); const llm = new LLMAnalyst({ logger: noopLogger }); const catalyst = new CatalystAnalyst({ logger: noopLogger }); new ScreenerController(engine).register(app); new FinanceController(engine, new PortfolioRepository()).register(app); new CallsController(new MarketCallRepository(), engine, yahoo).register(app); new AnalyzeController(catalyst, llm).register(app); app.get('/health', async () => ({ status: 'ok' })); return app; }