import { ScoringRules } from '../../../domains/shared/scoring/ScoringConfig'; import { MarketRegime } from '../../../domains/shared/scoring/MarketRegime'; import { SCORE_MODE } from '../../../domains/shared'; import type { AssetType, MarketContext, RuleSet } from '../../../domains/shared'; export class RuleMerger { static getRulesForAsset( type: AssetType, metrics: { sector?: string }, marketContext: Partial = {}, mode: string = SCORE_MODE.FUNDAMENTAL, ): RuleSet { const base = ScoringRules[type as keyof typeof ScoringRules]; if (!base) throw new Error(`No rules configured for asset type: ${type}`); // Deep clone to avoid mutating the source config const rules: RuleSet & { SECTOR_OVERRIDE?: unknown } = JSON.parse(JSON.stringify(base)); if (type === 'STOCK' && metrics.sector) { const stockBase = ScoringRules.STOCK; const override = stockBase.SECTOR_OVERRIDE?.[ metrics.sector.toUpperCase() as keyof typeof stockBase.SECTOR_OVERRIDE ]; if (override) { rules.gates = { ...rules.gates, ...override.gates }; rules.weights = { ...rules.weights, ...override.weights }; rules.thresholds = { ...rules.thresholds, ...override.thresholds }; } } delete rules.SECTOR_OVERRIDE; if (mode === SCORE_MODE.INFLATED) { const { gates, thresholds } = new MarketRegime( marketContext as MarketContext, ).getInflatedOverrides(type, metrics.sector); rules.gates = { ...rules.gates, ...gates }; rules.thresholds = { ...rules.thresholds, ...thresholds }; } return rules; } }