Skip to content

Commit 6dfaf5c

Browse files
Copilotankurrera
andcommitted
Address code review feedback: improve documentation and robustness
Co-authored-by: ankurrera <186232326+ankurrera@users.noreply.github.com>
1 parent ef440e0 commit 6dfaf5c

3 files changed

Lines changed: 49 additions & 7 deletions

File tree

src/hooks/useCoreMetrics.ts

Lines changed: 33 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -71,19 +71,47 @@ function mapSkillToContributionData(skill: {
7171
};
7272
}
7373

74+
/**
75+
* Normalized mapping of characteristic names to Core Metric names
76+
* Handles naming variations (e.g., 'Foreign Languages' -> 'Foreign Language')
77+
*/
78+
const CHARACTERISTIC_TO_METRIC_MAP: Record<string, CoreMetricName> = {
79+
'programming': 'Programming',
80+
'learning': 'Learning',
81+
'erudition': 'Erudition',
82+
'discipline': 'Discipline',
83+
'productivity': 'Productivity',
84+
'foreign language': 'Foreign Language',
85+
'foreign languages': 'Foreign Language',
86+
'language': 'Foreign Language',
87+
'languages': 'Foreign Language',
88+
'fitness': 'Fitness',
89+
'drawing': 'Drawing',
90+
'hygiene': 'Hygiene',
91+
'reading': 'Reading',
92+
'communication': 'Communication',
93+
'cooking': 'Cooking',
94+
'meditation': 'Meditation',
95+
'swimming': 'Swimming',
96+
'running': 'Running',
97+
'math': 'Math',
98+
'mathematics': 'Math',
99+
'music': 'Music',
100+
'cleaning': 'Cleaning',
101+
};
102+
74103
/**
75104
* Map characteristic data to contribution format
76-
* Characteristics contribute to their namesake metric if it exists
105+
* Uses a predefined mapping for reliable characteristic-to-metric matching
77106
*/
78107
function mapCharacteristicToContributionData(char: {
79108
id: string;
80109
name: string;
81110
xp: number;
82111
}): CharacteristicContributionData {
83-
// Check if the characteristic name matches a Core Metric
84-
const metricName = PHYSICAL_BALANCE_METRICS.find(
85-
m => m.toLowerCase() === char.name.toLowerCase()
86-
);
112+
// Use normalized lowercase name for lookup
113+
const normalizedName = char.name.toLowerCase().trim();
114+
const metricName = CHARACTERISTIC_TO_METRIC_MAP[normalizedName];
87115

88116
return {
89117
id: char.id,

src/lib/coreMetricCalculation.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,14 @@ export interface ComputedCoreMetric extends CoreMetric {
5656
/**
5757
* Calculate level from XP using the standard formula
5858
* Level = floor(sqrt(XP / 100)) + 1
59+
*
60+
* XP Thresholds:
61+
* - Level 1: 0-99 XP
62+
* - Level 2: 100-399 XP
63+
* - Level 3: 400-899 XP
64+
* - Level 4: 900-1599 XP
65+
* - Level 5: 1600-2499 XP
66+
* - Level 10: 8100-9999 XP
5967
*/
6068
export function calculateMetricLevel(xp: number): number {
6169
return Math.floor(Math.sqrt(xp / 100)) + 1;

src/lib/coreMetrics.ts

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -97,14 +97,20 @@ export function getDefaultMapping(area: string | null): Partial<Record<CoreMetri
9797
return { 'Learning': 0.5, 'Discipline': 0.3, 'Productivity': 0.2 };
9898
}
9999

100+
/**
101+
* Floating point comparison tolerance for weight validation
102+
* Used to account for JavaScript floating-point arithmetic imprecision
103+
*/
104+
const WEIGHT_SUM_TOLERANCE = 1.0001;
105+
100106
/**
101107
* Validate that contribution weights sum to ≤ 1
102108
*/
103109
export function validateContributionWeights(
104110
contributions: Partial<Record<CoreMetricName, number>>
105111
): boolean {
106112
const sum = Object.values(contributions).reduce((acc, weight) => acc + (weight || 0), 0);
107-
return sum <= 1.0001; // Small epsilon for floating point errors
113+
return sum <= WEIGHT_SUM_TOLERANCE;
108114
}
109115

110116
/**
@@ -116,7 +122,7 @@ export function normalizeContributionWeights(
116122
const result: Partial<Record<CoreMetricName, number>> = {};
117123
const sum = Object.values(contributions).reduce((acc, weight) => acc + (weight || 0), 0);
118124

119-
if (sum <= 1.0001) {
125+
if (sum <= WEIGHT_SUM_TOLERANCE) {
120126
// Already valid, just copy
121127
for (const [key, value] of Object.entries(contributions)) {
122128
result[key as CoreMetricName] = value || 0;

0 commit comments

Comments
 (0)