Fix nutrition amounts to match the displayed food serving - #135
Merged
Conversation
Contributor
There was a problem hiding this comment.
🟢 Approval recommended
The normalization logic matches the stated requirements and is covered by focused new tests for the key mismatch and edge cases.
Pull request overview
This PR fixes a mismatch in Open Food Facts search results where nutrient values were taken per 100 g/ml while the UI displayed a per-serving amount, ensuring the displayed serving/reference amount and all four macro fields (calories, protein, fat, carbohydrates) always share the same basis.
Changes:
- Normalize Open Food Facts products to use per-serving macros only when the serving label is present/usable and all four per-serving values are complete; otherwise fall back to a clearly labeled 100 g/ml reference basis.
- Add targeted backend tests covering serving-vs-reference selection rules, invalid/missing data, oversized labels, and zero-value macros.
- Document the normalization and the non-retrospective behavior for existing food logs.
File summaries
| File | Description |
|---|---|
| docs/public/data-safety.md | Documents the new “single nutrition basis” rule and clarifies that existing logs are not rescaled. |
| backend/tests/test_food_nutrition_basis.py | Adds regression tests for basis selection and edge cases (missing/invalid values, unusable labels, zero macros). |
| backend/app/services/open_food_facts.py | Implements basis-consistent normalization (serving when complete + usable label, else explicit 100 g/ml reference). |
Review details
- Files reviewed: 3/3 changed files
- Comments generated: 0
- Review effort level: Lite
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Food search used Open Food Facts values per 100 g/ml while displaying the packaging serving size. As a result, selecting 50% of a displayed 250 ml serving could save half of the reference values instead of half of the serving values.
This PR makes the displayed amount and all four nutrient values use the same basis:
The existing portion picker scales this consistent amount. Existing food logs remain as recorded; this change does not retrospectively correct them. The deployment is backend-only and requires no WordPress plugin upload or database migration.
Validation: 160 targeted backend tests passed, including 18 new nutrition-basis cases. The new cases cover the reported serving/reference mismatch using synthetic representative data, missing and invalid values, missing or oversized labels, and zero macros. Whitespace, legal-boundary and tracked-secret checks passed.
Reference: Open Food Facts nutrition schema.