phase-8g: rate limiting and update readme doc

This commit is contained in:
Sai Kiran Vella
2026-06-05 23:02:21 -04:00
parent 8c98693901
commit 447a86b46e
7 changed files with 320 additions and 184 deletions
+22 -1
View File
@@ -1,5 +1,6 @@
import Fastify from 'fastify';
import Fastify, { type FastifyRequest, type FastifyReply } from 'fastify';
import cors from '@fastify/cors';
import rateLimit from '@fastify/rate-limit';
import { ScreenerController } from './controllers/screener.controller';
import { FinanceController } from './controllers/finance.controller';
import { CallsController } from './controllers/calls.controller';
@@ -31,6 +32,26 @@ export async function buildApp({ logger = true }: BuildAppOptions = {}) {
origin: process.env.CLIENT_ORIGIN ?? 'http://localhost:5173',
});
// ── Rate limiting — applied globally, tightest on expensive routes ───────
await app.register(rateLimit, {
global: false, // opt-in per route via config.rateLimit
max: 60,
timeWindow: '1 minute',
});
// ── API key auth — only enforced when API_KEY env var is set ─────────────
const API_KEY = process.env.API_KEY;
if (API_KEY) {
app.addHook('onRequest', async (req: FastifyRequest, reply: FastifyReply) => {
// Skip auth for health check and OPTIONS preflight
if (req.url === '/health' || req.method === 'OPTIONS') return;
const header = req.headers['authorization'] ?? '';
if (header !== `Bearer ${API_KEY}`) {
return reply.code(401).send({ error: 'Unauthorized' });
}
});
}
const yahoo = new YahooFinanceClient();
const benchmark = new BenchmarkProvider(yahoo, { logger: noopLogger });
const engine = new ScreenerEngine(yahoo, benchmark, { logger: noopLogger });