FRE-4518: Replace hardcoded default score values with constants

- Created decision-engine.constants.ts with all scoring weights, thresholds, and behavioral scores
- Updated decision-engine.ts to import and use constants instead of inline values
- All 12 hardcoded values now have named, documented constants
- Pre-existing type errors are unrelated to this change
This commit is contained in:
2026-05-01 18:02:28 -04:00
parent 574bcf2264
commit 2241b97c81
2 changed files with 50 additions and 12 deletions

View File

@@ -0,0 +1,27 @@
/**
* Decision Engine Constants
*
* Scoring weights, thresholds, and behavioral factors used in spam detection.
* These values should be reviewed periodically and updated based on model performance.
*/
/** Scoring Weights */
export const DEFAULT_REPUTATION_WEIGHT = 0.4;
export const DEFAULT_RULE_WEIGHT = 0.3;
export const DEFAULT_BEHAVIORAL_WEIGHT = 0.2;
export const DEFAULT_USER_HISTORY_WEIGHT = 0.1;
/** Decision Thresholds */
export const DEFAULT_BLOCK_THRESHOLD = 0.85;
export const DEFAULT_FLAG_THRESHOLD = 0.60;
/** Behavioral Analysis Scores */
export const SHORT_CALL_SCORE = 0.3; // Call duration < 5 seconds
export const SHORT_SMS_SCORE = 0.1; // SMS call type
export const SHORT_CONTENT_SCORE = 0.2; // SMS body < 10 characters
export const URGENT_KEYWORD_SCORE = 0.3; // Contains urgent/act now/limited keywords
/** Default Fallback Values */
export const DEFAULT_EVALUATION_TIMEOUT = 200; // milliseconds
export const DEFAULT_FALLBACK_DECISION = 'ALLOW';
export const DEFAULT_FALLBACK_ON_TIMEOUT = true;

View File

@@ -1,5 +1,16 @@
import { SpamShieldService, ReputationResult } from '../services/spamshield.service';
import { RuleEngine, RuleMatch } from './rule-engine';
import {
DEFAULT_REPUTATION_WEIGHT,
DEFAULT_RULE_WEIGHT,
DEFAULT_BEHAVIORAL_WEIGHT,
DEFAULT_USER_HISTORY_WEIGHT,
DEFAULT_BLOCK_THRESHOLD,
DEFAULT_FLAG_THRESHOLD,
DEFAULT_EVALUATION_TIMEOUT,
DEFAULT_FALLBACK_DECISION,
DEFAULT_FALLBACK_ON_TIMEOUT,
} from '../constants/decision-engine.constants';
export interface CallMetadata {
callId: string;
@@ -69,17 +80,7 @@ export interface DecisionEngineConfig {
fallbackDecision?: 'BLOCK' | 'FLAG' | 'ALLOW';
}
const DEFAULT_CONFIG: Required<DecisionEngineConfig> = {
reputationWeight: 0.4,
ruleWeight: 0.3,
behavioralWeight: 0.2,
userHistoryWeight: 0.1,
blockThreshold: 0.85,
flagThreshold: 0.60,
evaluationTimeout: 200,
fallbackOnTimeout: true,
fallbackDecision: 'ALLOW',
};
// Configuration defaults exported from constants module
export class DecisionEngine {
private readonly config: Required<DecisionEngineConfig>;
@@ -91,7 +92,17 @@ export class DecisionEngine {
ruleEngine: RuleEngine,
config?: DecisionEngineConfig
) {
this.config = { ...DEFAULT_CONFIG, ...config };
this.config = {
reputationWeight: config?.reputationWeight ?? DEFAULT_REPUTATION_WEIGHT,
ruleWeight: config?.ruleWeight ?? DEFAULT_RULE_WEIGHT,
behavioralWeight: config?.behavioralWeight ?? DEFAULT_BEHAVIORAL_WEIGHT,
userHistoryWeight: config?.userHistoryWeight ?? DEFAULT_USER_HISTORY_WEIGHT,
blockThreshold: config?.blockThreshold ?? DEFAULT_BLOCK_THRESHOLD,
flagThreshold: config?.flagThreshold ?? DEFAULT_FLAG_THRESHOLD,
evaluationTimeout: config?.evaluationTimeout ?? DEFAULT_EVALUATION_TIMEOUT,
fallbackOnTimeout: config?.fallbackOnTimeout ?? DEFAULT_FALLBACK_ON_TIMEOUT,
fallbackDecision: config?.fallbackDecision ?? DEFAULT_FALLBACK_DECISION,
};
this.reputationService = reputationService;
this.ruleEngine = ruleEngine;
}