package models /* The nutrition panel, as the customer app renders it. The figures come from the catalogue-intelligence service — the same one behind the health score card in the console — and this is the shape they reach the app in. See services/nutritionService.go for the fetch and the mapping. ── Why the field names are ugly ──────────────────────────────────────────── `servingsize`, not `serving_size` or `servingSize`. This is the shape the app developer asked for, and an API is a promise to a client already written against it. Consistency with the rest of Fiesta — itself inconsistent, `productid` beside `image_id` beside `sku_source` — is worth less than not breaking the caller. */ type NutritionPanel struct { // What the figures are measured against. "100g" for everything the service // returns today: its top-level values are per 100g, which is what the // console's own panel prints beneath them. Per string `json:"per,omitempty"` // What the pack calls one serving — "1 mini (11 g)". Absent when the // service did not state one, rather than defaulted: a serving size is a // claim about the food, and a guessed one is a false claim. Servingsize string `json:"servingsize,omitempty"` // Never nil when this panel exists — see HasValues. An app receiving // `items: null` has to branch; one receiving `[]` does not, and a panel with // no rows should not have been sent at all. Items []NutritionItem `json:"items"` } // NutritionItem is one line of the panel. type NutritionItem struct { Name string `json:"name"` // The figure. A float because saturated fat is 18.7g as often as it is 19g, // and rounding it to please a type would be editing a label. Value float64 `json:"value"` // "kcal", "g", "mg". Free text on purpose: `extended_nutrients` carries its // own units from the source, and a closed list here would mean refusing to // carry whatever the label actually says. Unit string `json:"unit,omitempty"` } // HasValues reports whether this panel is worth sending. // // A panel with no rows is not a panel — it is an empty box on a product page, // which a shopper reads as "this food has no nutrition" rather than "we do not // know yet". The endpoint omits it instead. func (p *NutritionPanel) HasValues() bool { return p != nil && len(p.Items) > 0 }