mirror of
https://github.com/kuhyx/diet-guard.git
synced 2026-11-10 18:07:20 +01:00
The phone is getting its own Kuchnia Wikinga importer so the feature works with the PC switched off. That turns a risk `_kuchnia_spread.py` called "theoretical" into a live one: two implementations must now agree exactly on which dishes are dropped, which slot each lands on, and the JSON a banked record encodes to. Disagreement means each device re-adds what the other dropped, and since `add_manual_entry` restamps `t` unconditionally, the whole curated bank republishes to every peer on every refresh. A slot mismatch is worse -- a checkpoint one device offers and the other does not can never be satisfied. So the port lands with its gate rather than after it. One shared fixture, `tests/fixtures/kuchnia_day.json`, is asserted by both `pytest` and `flutter test`: same input, same expected dishes, drops, slots, bank keys and records. Two suites written independently from the same prose is not a gate. The fixture is five real dishes (a scrubbed 2026-08-22 capture) plus synthetic meals that each pin one drop or fallback path -- a per-100 g mix-up, an absurd portion, a stringly-typed number, a non-dict entry, a missing `nutrition`, a missing `mealPriority`, and a twin-dish pair. Without those, "the same meals are dropped" is a vacuous assertion against an all-happy-path capture. Both halves were mutation-checked: flipping an expected slot, drop count or record value fails each suite, and flipping `435.0` to `435` fails the byte-identity test while the value comparison still passes, which is why both exist. Three traps the port had to survive, each caught before it shipped: - `_ENERGY_TOLERANCE` is **0.35**. The prose said "~1%", which describes how closely the captured day agreed, not the threshold; porting 0.01 would drop dishes the PC keeps. That paragraph now says so. - `jsonEncode(435)` emits `435` where Python emits `435.0`, so every Dart macro is forced to `double` and a canonical-encoding test pins it. - Dart's `List.sort` is unstable where Python's `sorted` is stable, so the Dart comparator carries the payload index as a final tiebreak. The real dishes live in their own file rather than as a literal in the generator: transcribing them by hand corrupted three of the five, and the error was invisible until the generated fixture was diffed against the capture. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QQpCiPaSbyRpwsLkH3dgsX
88 lines
2.0 KiB
JSON
88 lines
2.0 KiB
JSON
[
|
|
{
|
|
"deliveryMealId": 1001,
|
|
"mealName": "Śniadanie",
|
|
"mealPriority": 1,
|
|
"menuMealName": "Marchewkowe pancakes, twarożek cynamonowy, sos truskawkowy",
|
|
"nutrition": {
|
|
"calories": 435.0,
|
|
"carbohydrate": 54.64,
|
|
"dietaryFiber": 2.03,
|
|
"fat": 12.01,
|
|
"protein": 25.86,
|
|
"salt": 0.52,
|
|
"saturatedFattyAcids": 1.92,
|
|
"sugar": 22.4,
|
|
"weight": 270.0
|
|
}
|
|
},
|
|
{
|
|
"deliveryMealId": 1002,
|
|
"mealName": "II śniadanie",
|
|
"mealPriority": 2,
|
|
"menuMealName": "Hummus paprykowy, mini wafle kukurydziane, warzywa",
|
|
"nutrition": {
|
|
"calories": 367.0,
|
|
"carbohydrate": 41.67,
|
|
"dietaryFiber": 9.18,
|
|
"fat": 17.26,
|
|
"protein": 10.86,
|
|
"salt": 1.27,
|
|
"saturatedFattyAcids": 1.59,
|
|
"sugar": 3.77,
|
|
"weight": 205.0
|
|
}
|
|
},
|
|
{
|
|
"deliveryMealId": 1003,
|
|
"mealName": "Obiad",
|
|
"mealPriority": 3,
|
|
"menuMealName": "Makaron farfalle z indykiem w sosie z batatów z suszonymi pomidorami, ser włoski",
|
|
"nutrition": {
|
|
"calories": 594.0,
|
|
"carbohydrate": 53.23,
|
|
"dietaryFiber": 3.83,
|
|
"fat": 23.21,
|
|
"protein": 42.47,
|
|
"salt": 1.08,
|
|
"saturatedFattyAcids": 7.03,
|
|
"sugar": 4.88,
|
|
"weight": 465.0
|
|
}
|
|
},
|
|
{
|
|
"deliveryMealId": 1004,
|
|
"mealName": "Podwieczorek",
|
|
"mealPriority": 4,
|
|
"menuMealName": "Fit ciasto, jak twix white",
|
|
"nutrition": {
|
|
"calories": 268.0,
|
|
"carbohydrate": 25.18,
|
|
"dietaryFiber": 0.36,
|
|
"fat": 17.36,
|
|
"protein": 5.85,
|
|
"salt": 0.15,
|
|
"saturatedFattyAcids": 10.76,
|
|
"sugar": 8.3,
|
|
"weight": 90.0
|
|
}
|
|
},
|
|
{
|
|
"deliveryMealId": 1005,
|
|
"mealName": "Kolacja",
|
|
"mealPriority": 5,
|
|
"menuMealName": "Kaszotto grzybowe z pieczonym kurczakiem i serem włoskim",
|
|
"nutrition": {
|
|
"calories": 391.0,
|
|
"carbohydrate": 35.56,
|
|
"dietaryFiber": 3.69,
|
|
"fat": 13.02,
|
|
"protein": 32.51,
|
|
"salt": 1.3,
|
|
"saturatedFattyAcids": 6.53,
|
|
"sugar": 1.99,
|
|
"weight": 318.0
|
|
}
|
|
}
|
|
]
|