What happened?
The Tandoor connector returns 0 for all nutrition values (calories, protein, carbs, fat) when the Tandoor Property Type names are not in English (e.g. German: "Kalorien", "Proteine", "Fett", "Kohlenhydrate"). The open_data_slug (e.g. property-calories) is set correctly in Tandoor but is not visible to the mapper because it is missing from the food_properties payload returned by Tandoor.
This appears to be a regression in the language-agnostic mapping introduced by #877 (Issue #461). The fix correctly checks for open_data_slug, but Tandoor's top-level food_properties does not include that field — only name. As a result, non-English Tandoor instances always fall through to a no-match.
Tandoor recipe detail payload (relevant excerpt):
"food_properties": {
"1": {
"id": 1,
"name": "Kalorien",
"description": null,
"unit": "kcal",
"order": 0,
"food_values": { ... },
"total_value": 309.1,
"missing_value": false
}
}
There is no open_data_slug field on entries in food_properties. Tandoor only exposes that field on /api/property-type/ and inside the per-ingredient food_properties array. So slugNorm in the mapper is always empty, and nameNorm only matches if Tandoor is in English.
Server log (SPARKY_FITNESS_LOG_LEVEL=debug):
Steps to reproduce
- Set up a Tandoor instance with localized Property Type names (e.g. German: "Kalorien", "Proteine", "Fett", "Kohlenhydrate"). Ensure
open_data_slug is correctly set (property-calories, property-proteins, property-fats, property-carbohydrates) and fdc_id is set (1008, 1003, 1004, 1005).
- Connect Tandoor to SparkyFitness as External Provider with a valid API token.
- Create a recipe in Tandoor with ingredients that have nutrition data (e.g. via Open Food Facts). Verify in Tandoor's UI that the recipe shows correct aggregated values.
- Verify via curl that
/api/recipe/<id>/ returns correct values under food_properties.<id>.total_value.
- In SparkyFitness, search for the recipe via the Tandoor provider.
- Click "Edit & Add" — all nutrition fields are
0.
Expected behavior
Nutrition fields should be populated with the per-serving values from Tandoor (calories, protein, carbs, fat at minimum), regardless of the language of the Property Type names in Tandoor, as long as open_data_slug and/or fdc_id are correctly set on the property types in Tandoor.
In my test recipe ("Spinat-Feta-Omelett"):
- Calories: 309.1 kcal
- Protein: 34.6 g
- Fat: 14.7 g
- Carbohydrates: 9.7 g
Tandoor's UI shows these values correctly. SparkyFitness shows 0 for all of them until the property types are renamed to English.
How are you running SparkyFitness?
Docker Compose
SparkyFitness version
v0.16.6.1
Which area is affected?
No response
Relevant logs or screenshots
Server log with SPARKY_FITNESS_LOG_LEVEL=debug during a recipe search via the Tandoor provider:
[DEBUG] searchTandoorFoods: query: spinat, baseUrl: http://tandoor.local:8002, ...
[DEBUG] Tandoor search HTTP status: 200 OK
[DEBUG] Tandoor search response type: object, keys: ["count","next","previous","results"]
[DEBUG] Found 1 recipes for query: spinat
[DEBUG] Successfully retrieved details for recipe: 2
[DEBUG] [Tandoor Mapping] Starting mapping for recipe ID: 2 ("Spinat-Feta-Omelett")
[DEBUG] [Tandoor Mapping] Searching for "calories" (Candidates: calories, cal, kcal, energy, kcalories, property-calories, property-energy, calorias)
[DEBUG] [Tandoor Mapping] No Match: Could not find value for "calories"
[DEBUG] [Tandoor Mapping] Searching for "protein" (Candidates: protein, proteins, protein_g, proteins_g, property-proteins, proteinas)
[DEBUG] [Tandoor Mapping] No Match: Could not find value for "protein"
[DEBUG] [Tandoor Mapping] Searching for "carbs" (Candidates: carbohydrates, carbohydrate, carbs, carb, property-carbohydrates, carbohidratos)
[DEBUG] [Tandoor Mapping] No Match: Could not find value for "carbs"
[DEBUG] [Tandoor Mapping] Searching for "fat" (Candidates: fat, fats, totalfat, total_fat, total fat, property-fats, grasas)
[DEBUG] [Tandoor Mapping] No Match: Could not find value for "fat"
[DEBUG] [Tandoor Mapping] Recipe makes 1 servings. Data is per-serving.
Tandoor API returns the data correctly under /api/recipe/<id>/ in the food_properties top-level field with total_value populated, but no open_data_slug is present on those entries — only on /api/property-type/.
Anything else?
Tandoor recipe detail payload (relevant excerpt) showing missing open_data_slug:
"food_properties": {
"1": {
"id": 1,
"name": "Kalorien",
"description": null,
"unit": "kcal",
"order": 0,
"food_values": { ... },
"total_value": 309.1,
"missing_value": false
}
}
There is no open_data_slug field on entries in food_properties. Tandoor only exposes that field on /api/property-type/ and inside the per-ingredient food_properties array. So slugNorm in the mapper is always empty, and nameNorm only matches if Tandoor is in English.
Workaround: Renaming the Property Type names in Tandoor to English ("Calories", "Protein", "Fat", "Carbohydrates") via the Django admin (/admin/cookbook/propertytype/) resolves the issue, because then nameNorm === candNorm matches.
Suggested fix: In tandoorService.ts, fetch /api/property-type/ once (or cached) and join open_data_slug and fdc_id into the food_properties entries by their numeric key (which equals the property type ID). Alternatively, match by fdc_id (Calories=1008, Protein=1003, Fat=1004, Carbohydrates=1005), which is also locale-independent and already present on /api/property-type/. The current food_properties payload does not carry fdc_id either, so this would still require the property-type lookup. Either approach makes the existing matching work regardless of language.
Environment:
- Tandoor: 2.6.9
- Browser: Chrome (also reproduced in Safari) on macOS
- Database: postgres:16-alpine
- Property types in test space have correct
open_data_slug values (property-calories, property-proteins, property-fats, property-carbohydrates) and fdc_id values (1008, 1003, 1004, 1005), verified via /api/property-type/ direct call.
What happened?
The Tandoor connector returns
0for all nutrition values (calories, protein, carbs, fat) when the Tandoor Property Type names are not in English (e.g. German: "Kalorien", "Proteine", "Fett", "Kohlenhydrate"). Theopen_data_slug(e.g.property-calories) is set correctly in Tandoor but is not visible to the mapper because it is missing from thefood_propertiespayload returned by Tandoor.This appears to be a regression in the language-agnostic mapping introduced by #877 (Issue #461). The fix correctly checks for
open_data_slug, but Tandoor's top-levelfood_propertiesdoes not include that field — onlyname. As a result, non-English Tandoor instances always fall through to a no-match.Tandoor recipe detail payload (relevant excerpt):
There is no
open_data_slugfield on entries infood_properties. Tandoor only exposes that field on/api/property-type/and inside the per-ingredientfood_propertiesarray. SoslugNormin the mapper is always empty, andnameNormonly matches if Tandoor is in English.Server log (
SPARKY_FITNESS_LOG_LEVEL=debug):Steps to reproduce
open_data_slugis correctly set (property-calories,property-proteins,property-fats,property-carbohydrates) andfdc_idis set (1008, 1003, 1004, 1005)./api/recipe/<id>/returns correct values underfood_properties.<id>.total_value.0.Expected behavior
Nutrition fields should be populated with the per-serving values from Tandoor (calories, protein, carbs, fat at minimum), regardless of the language of the Property Type names in Tandoor, as long as
open_data_slugand/orfdc_idare correctly set on the property types in Tandoor.In my test recipe ("Spinat-Feta-Omelett"):
Tandoor's UI shows these values correctly. SparkyFitness shows
0for all of them until the property types are renamed to English.How are you running SparkyFitness?
Docker Compose
SparkyFitness version
v0.16.6.1
Which area is affected?
No response
Relevant logs or screenshots
Anything else?
Tandoor recipe detail payload (relevant excerpt) showing missing open_data_slug:
There is no
open_data_slugfield on entries infood_properties. Tandoor only exposes that field on/api/property-type/and inside the per-ingredientfood_propertiesarray. SoslugNormin the mapper is always empty, andnameNormonly matches if Tandoor is in English.Workaround: Renaming the Property Type names in Tandoor to English ("Calories", "Protein", "Fat", "Carbohydrates") via the Django admin (
/admin/cookbook/propertytype/) resolves the issue, because thennameNorm === candNormmatches.Suggested fix: In
tandoorService.ts, fetch/api/property-type/once (or cached) and joinopen_data_slugandfdc_idinto thefood_propertiesentries by their numeric key (which equals the property type ID). Alternatively, match byfdc_id(Calories=1008, Protein=1003, Fat=1004, Carbohydrates=1005), which is also locale-independent and already present on/api/property-type/. The currentfood_propertiespayload does not carryfdc_ideither, so this would still require the property-type lookup. Either approach makes the existing matching work regardless of language.Environment:
open_data_slugvalues (property-calories,property-proteins,property-fats,property-carbohydrates) andfdc_idvalues (1008, 1003, 1004, 1005), verified via/api/property-type/direct call.