fix(C3): validate screener sector filters
Reject unsupported /api/screener sector values before building the FMP query so only known sector labels reach the upstream stock screener. Refs: docs/AUDIT_REDESIGN.md item C3. Co-Authored-By: GPT-5 Codex <noreply@openai.com>
This commit is contained in:
parent
222d101a7e
commit
c173aeb87a
@ -97,6 +97,20 @@ interface RuntimeHealth {
|
||||
canonicalLifecycleOrderRows?: number;
|
||||
}
|
||||
|
||||
const ALLOWED_SCREENER_SECTORS = new Set([
|
||||
'Technology',
|
||||
'Financial Services',
|
||||
'Healthcare',
|
||||
'Consumer Cyclical',
|
||||
'Consumer Defensive',
|
||||
'Industrials',
|
||||
'Energy',
|
||||
'Utilities',
|
||||
'Real Estate',
|
||||
'Communication Services',
|
||||
'Basic Materials',
|
||||
]);
|
||||
|
||||
interface TradeAuditEvent {
|
||||
event: string;
|
||||
userId?: string;
|
||||
@ -2818,7 +2832,13 @@ RULES:
|
||||
try {
|
||||
const apiKey = process.env.FMP_API_KEY || 'demo';
|
||||
const qs = new URLSearchParams();
|
||||
if (req.query.sector) qs.set('sector', String(req.query.sector));
|
||||
const sector = String(req.query.sector || '').trim();
|
||||
if (sector && sector !== 'All') {
|
||||
if (!ALLOWED_SCREENER_SECTORS.has(sector)) {
|
||||
return res.status(400).json({ error: 'Unsupported sector filter' });
|
||||
}
|
||||
qs.set('sector', sector);
|
||||
}
|
||||
if (req.query.marketCapMoreThan) qs.set('marketCapMoreThan', String(req.query.marketCapMoreThan));
|
||||
if (req.query.marketCapLessThan) qs.set('marketCapLessThan', String(req.query.marketCapLessThan));
|
||||
if (req.query.betaMoreThan) qs.set('betaMoreThan', String(req.query.betaMoreThan));
|
||||
|
||||
@ -168,6 +168,14 @@ function testFmpProxyContracts() {
|
||||
'https://financialmodelingprep.com/api/v3/stock-screener?${qs.toString()}',
|
||||
'/api/screener must call FMP stock-screener',
|
||||
);
|
||||
assertSourceIncludes(
|
||||
'const ALLOWED_SCREENER_SECTORS = new Set([',
|
||||
'/api/screener must keep an explicit sector allow-list',
|
||||
);
|
||||
assertSourceMatches(
|
||||
/if \(sector && sector !== 'All'\)[\s\S]*!ALLOWED_SCREENER_SECTORS\.has\(sector\)[\s\S]*status\(400\)\.json\(\{ error: 'Unsupported sector filter' \}\)[\s\S]*qs\.set\('sector', sector\)/,
|
||||
'/api/screener must reject unsupported sector values before building the FMP query',
|
||||
);
|
||||
assertSourceIncludes(
|
||||
"qs.set('isEtf', 'false')",
|
||||
'/api/screener must exclude ETFs by default',
|
||||
|
||||
Loading…
Reference in New Issue
Block a user