diff --git a/src/features/matching/scoreCalculator.ts b/src/features/matching/scoreCalculator.ts index 5b7bab9..4369b32 100644 --- a/src/features/matching/scoreCalculator.ts +++ b/src/features/matching/scoreCalculator.ts @@ -362,11 +362,12 @@ export function calculateScore(need: Need, property: Property): MatchEngineOutpu const hardMatchScore = hardWeightSum > 0 ? Math.min(100, Math.round(hardRaw / hardWeightSum)) : 0 // ── Soft factor scoring ──────────────────────────────────────────────────── - const softFactors: ScoreFactor[] = SOFT_FACTOR_KEYS - .filter(k => (profile[k] ?? 0) > 0) - .map(k => scoreSoftFactor(k, profile[k], property)) + // All 9 factors always included in output so breakdown is always complete. + // Only weighted factors (weight > 0) contribute to the score calculation. + const allSoftDisplay: ScoreFactor[] = SOFT_FACTOR_KEYS + .map(k => scoreSoftFactor(k, profile[k] ?? 0, property)) const softWeightSum = SOFT_FACTOR_KEYS.reduce((s, k) => s + (profile[k] ?? 0), 0) - const softRaw = softFactors.reduce((s, f) => s + f.contribution, 0) + const softRaw = allSoftDisplay.filter(f => f.weight > 0).reduce((s, f) => s + f.contribution, 0) const softFactorScore = softWeightSum > 0 ? Math.min(100, Math.round(softRaw / softWeightSum)) : 50 // ── Modifiers ────────────────────────────────────────────────────────────── @@ -379,8 +380,9 @@ export function calculateScore(need: Need, property: Property): MatchEngineOutpu const rawFinal = baseScore + dqMod + confMod - hardFilter.severePenalty const finalScore = Math.round(Math.min(100, Math.max(0, rawFinal))) - // ── Factor classification ────────────────────────────────────────────────── - const allFactors = [...hardFactors, ...softFactors] + // ── Factor classification — only use weighted soft factors for positive/negative ── + const weightedSoftFactors = allSoftDisplay.filter(f => f.weight > 0) + const allFactors = [...hardFactors, ...weightedSoftFactors] const THRESHOLD_POSITIVE = 70 const THRESHOLD_NEGATIVE = 45 const positiveFactors = allFactors @@ -392,7 +394,7 @@ export function calculateScore(need: Need, property: Property): MatchEngineOutpu .sort((a, b) => a.contribution - b.contribution) .slice(0, 4) - const tradeOffs = analyzeTradeOffs(hardFactors, softFactors, need, property) + const tradeOffs = analyzeTradeOffs(hardFactors, weightedSoftFactors, need, property) const risks = analyzeRisks(property, hardFactors) const missingData = identifyMissingData(property, need) @@ -408,7 +410,7 @@ export function calculateScore(need: Need, property: Property): MatchEngineOutpu positiveFactors, negativeFactors, allHardFactors: hardFactors, - allSoftFactors: softFactors, + allSoftFactors: allSoftDisplay, tradeOffs, risks, missingData,