diff --git a/src/db.rs b/src/db.rs index 3289ff9..6681505 100644 --- a/src/db.rs +++ b/src/db.rs @@ -27,6 +27,14 @@ pub const TRACKED_NUTRIENTS: &[(&str, &str)] = &[ ("cholesterol", "cholesterol_100g"), ]; +/// Nutrients that OFF stores in grams but we track in milligrams. +/// When summing, these values are multiplied by 1000 to convert g → mg. +pub const MG_NUTRIENTS: &[&str] = &[ + "potassium_100g", + "calcium_100g", + "magnesium_100g", +]; + /// Default daily goals (gout + hypertension aware). /// Values are in grams or mg as appropriate (matches OFF _100g units). pub const DEFAULT_GOALS_JSON: &str = r#"{ diff --git a/src/tools.rs b/src/tools.rs index 9a30c52..df255bf 100644 --- a/src/tools.rs +++ b/src/tools.rs @@ -25,7 +25,7 @@ use sqlx::Row; use crate::api::{OffClient, Product}; use crate::config::Config; -use crate::db::{self, TRACKED_NUTRIENTS}; +use crate::db::{self, TRACKED_NUTRIENTS, MG_NUTRIENTS}; /// The MCP server handler. Each client session gets its own instance, /// but they share the same Config (which contains the DB path — the pool @@ -228,9 +228,11 @@ pub fn sum_nutriments(entries_nutriments: &[Value]) -> Value { for (display_key, tracked_key) in TRACKED_NUTRIENTS { let mut sum = 0.0; let mut has_data = false; + let is_mg = MG_NUTRIENTS.contains(tracked_key); for entry_nutriments in entries_nutriments { if let Some(val) = entry_nutriments.get(tracked_key).and_then(|v| v.as_f64()) { - sum += val; + // OFF stores potassium/calcium/magnesium in grams; convert to mg + sum += if is_mg { val * 1000.0 } else { val }; has_data = true; } } diff --git a/tests/integration_tests.rs b/tests/integration_tests.rs index 48af183..d42f6de 100644 --- a/tests/integration_tests.rs +++ b/tests/integration_tests.rs @@ -238,13 +238,14 @@ mod tests { #[test] fn test_sum_nutriments_partial_data() { - // One entry has potassium, another doesn't — should sum available + // One entry has potassium (in grams, as OFF stores it), another doesn't + // 0.1g = 100mg, 0.05g = 50mg → sum should be 150mg let entries = vec![ - json!({"potassium_100g": 100.0}), - json!({"potassium_100g": 50.0, "energy-kcal_100g": 200.0}), + json!({"potassium_100g": 0.1}), + json!({"potassium_100g": 0.05, "energy-kcal_100g": 200.0}), ]; let totals = tools::sum_nutriments(&entries); - assert_eq!(totals["potassium"], json!(150.0)); + assert_eq!(totals["potassium"], json!(150.0)); // 100mg + 50mg = 150mg assert_eq!(totals["energy_kcal"], json!(200.0)); }