EcoTracker-II / backend /src /services /scoringService.js
Akash-Dragon's picture
refactor: restructure project as a monorepo and implement backend API
7e49c4d
Raw
History Blame Contribute Delete
3.11 kB
/**
* Sustainability Scoring Service
* Scores are 0–100 based on total annual CO₂ emissions
*/
// Reference points (kg CO₂ per year)
const BENCHMARKS = {
target: 2000, // Paris Agreement 2050 target per person
excellent: 3000, // 90+ score threshold
good: 5000, // 70+ score threshold
moderate: 7500, // 50+ score threshold
poor: 12000, // 0 score threshold (12 tonnes = very high footprint)
};
/**
* Calculate sustainability score (0-100) from total annual emissions
* Uses piecewise linear interpolation between benchmarks
* @param {number} totalEmissionKg - annual CO₂ in kg
* @returns {number} score 0-100
*/
export function calculateScore(totalEmissionKg) {
const kg = Math.max(0, totalEmissionKg);
if (kg <= BENCHMARKS.target) return 100;
if (kg <= BENCHMARKS.excellent) {
return Math.round(
90 + ((BENCHMARKS.excellent - kg) / (BENCHMARKS.excellent - BENCHMARKS.target)) * 10
);
}
if (kg <= BENCHMARKS.good) {
return Math.round(
70 + ((BENCHMARKS.good - kg) / (BENCHMARKS.good - BENCHMARKS.excellent)) * 20
);
}
if (kg <= BENCHMARKS.moderate) {
return Math.round(
50 + ((BENCHMARKS.moderate - kg) / (BENCHMARKS.moderate - BENCHMARKS.good)) * 20
);
}
if (kg >= BENCHMARKS.poor) return 0;
return Math.round(((BENCHMARKS.poor - kg) / (BENCHMARKS.poor - BENCHMARKS.moderate)) * 50);
}
/**
* Get score label and metadata
* @param {number} score - 0-100
* @returns {{ label: string, description: string, color: string }}
*/
export function getScoreLabel(score) {
if (score >= 90) {
return {
label: 'Excellent',
description:
"Your carbon footprint is well below global targets. You're making a real difference!",
color: '#10b981',
tier: 'excellent',
};
}
if (score >= 70) {
return {
label: 'Good',
description:
"You're doing better than most. A few targeted changes could get you to excellent.",
color: '#06b6d4',
tier: 'good',
};
}
if (score >= 50) {
return {
label: 'Moderate',
description:
"Your footprint is around the global average. There's meaningful room to improve.",
color: '#f59e0b',
tier: 'moderate',
};
}
return {
label: 'Needs Improvement',
description:
'Your footprint is above average. The recommendations below will help you reduce it significantly.',
color: '#ef4444',
tier: 'poor',
};
}
/**
* Compare footprint against benchmarks
* @param {number} totalEmissionKg
* @returns {Object} comparison object
*/
export function compareToAverages(totalEmissionKg) {
const globalAvg = 4700;
const ukAvg = 5500;
const parisTarget = 2000;
return {
vsGlobalAverage: parseFloat((((totalEmissionKg - globalAvg) / globalAvg) * 100).toFixed(1)),
vsUkAverage: parseFloat((((totalEmissionKg - ukAvg) / ukAvg) * 100).toFixed(1)),
vsParisTarget: parseFloat((((totalEmissionKg - parisTarget) / parisTarget) * 100).toFixed(1)),
globalAverage: globalAvg,
ukAverage: ukAvg,
parisTarget,
};
}
export { BENCHMARKS };