fix: potassium/calcium/magnesium unit conversion (g → mg)
OFF stores potassium_100g, calcium_100g, magnesium_100g in grams. Goals are in mg. sum_nutriments now multiplies these by 1000. Before: potassium showed 0.7mg (was 0.0007g displayed as mg) After: potassium shows 691.2mg (banana: 0.32g/100g × 216g × 1000) Added MG_NUTRIENTS const to db.rs. Updated test assertions. 31 tests passing.
This commit is contained in:
parent
e8bdea78bb
commit
a072c6ba5e
3 changed files with 17 additions and 6 deletions
|
|
@ -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#"{
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue