platos: segundo plato por comida (ensalada + salmon)

- MealSlot.secondaryDishId (opcional, aditivo CloudKit); se limpia al
  sustituir/quitar/vaciar/marcar comer fuera y viaja en swaps, copia de
  semana anterior, undo y snapshot KV de iCloud (retrocompatible)
- Picker de hueco lleno: toggle "anadir como segundo plato" + boton para
  quitarlo; HomeViewModel.assignSecondaryDish/removeSecondaryDish
- Se muestra "Plato + Segundo" en calendario, widget y export; la lista
  de la compra incluye los ingredientes del segundo; stats lo cuentan
- Evento analytics secondary_dish_added; strings en 6 idiomas

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013H6bXqGX1ygwib1Dm3n3UG
This commit is contained in:
alexandrev-tibco
2026-09-01 11:37:23 +02:00
parent 7193234024
commit a0f9fa63d3
15 changed files with 128 additions and 13 deletions
+5
View File
@@ -8,6 +8,9 @@ final class MealSlot {
var dayOfWeek: Int = 0 // 0=Monday, 6=Sunday
var mealType: String = MealType.dinner.rawValue
var dishId: UUID?
/// Optional companion dish ("ensalada + salmón"). Only meaningful while
/// `dishId` is set; cleared together with it.
var secondaryDishId: UUID?
var calendarEventId: String?
var isRuleOverridden: Bool = false
var isEatingOut: Bool = false
@@ -19,6 +22,7 @@ final class MealSlot {
dayOfWeek: Int,
mealType: String,
dishId: UUID? = nil,
secondaryDishId: UUID? = nil,
calendarEventId: String? = nil,
isRuleOverridden: Bool = false,
isEatingOut: Bool = false
@@ -27,6 +31,7 @@ final class MealSlot {
self.dayOfWeek = dayOfWeek
self.mealType = mealType
self.dishId = dishId
self.secondaryDishId = secondaryDishId
self.calendarEventId = calendarEventId
self.isRuleOverridden = isRuleOverridden
self.isEatingOut = isEatingOut