Commit Graph

162 Commits

Author SHA1 Message Date
alexandrev-tibco 75c41b12ec comprobar el esquema de CloudKit antes de publicar
Un campo que esta en el @Model pero no en el esquema desplegado no sincroniza,
y no falla nada: los datos se quedan en el dispositivo que los escribio. Asi se
colaron nueve campos fuera de Production entre la 2.0 y la 2.1.2 sin que nadie
lo notara, incluidas las reglas de dia de las etiquetas y el desayuno/merienda
activados.

scripts/check_cloudkit_schema.py compara las propiedades almacenadas de cada
@Model con los CD_<campo> del esquema real (exportado con cktool), saltando
relaciones, computadas y el sufijo _ckAsset de los binarios.

fastlane submit y release abortan si falta algo; beta solo avisa, porque en
TestFlight es normal que el deploy a Production aun no se haya hecho. La lane
check_schema lo ejecuta suelto.

El deploy a Production sigue siendo manual: cktool no tiene subcomando y Apple
bloquea el endpoint de esquema en ese entorno.

Refs #38

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013su1ttRiMeMYxkZJ1Y3246
2026-09-14 17:23:22 +02:00
alexandrev-tibco 8b75f496f8 2.1.2: release notes en 6 idiomas
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013su1ttRiMeMYxkZJ1Y3246
2026-09-14 17:05:20 +02:00
alexandrev-tibco f289165eae 2.1.2: build 92 subida a TestFlight
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013su1ttRiMeMYxkZJ1Y3246
2026-09-13 21:51:57 +02:00
alexandrev-tibco bc684a099c watch: semanas navegables y los dias que no se planifican
Dos cosas que faltaban, las dos visibles en domingo con el fin de semana
desactivado:

El envio al reloj solo llevaba la semana en curso, asi que no habia forma de
ver las semanas ya planificadas por delante. Ahora viajan cuatro (la anterior,
la actual y las dos siguientes) y la vista de semana se desliza entre ellas,
arrancando en la actual.

Y un dia fuera del plan dejaba al reloj sin nada que enseñar: el domingo no
existe en el payload si no planificas fines de semana, asi que la complicacion
salia vacia y la app decia "abre MealMood en el iPhone", como si fuera un
problema de sincronizacion. Ahora se distingue: si hoy no se planifica se dice,
y se enseña el proximo dia que si tiene comidas — que es lo util en el reloj.

De paso, las semanas se comparan con el calendario alineado a lunes. Con el del
sistema, en las regiones donde la semana empieza en domingo, un domingo caia en
otra semana que su propio lunes y un envio recien hecho parecia caducado.

Refs #36, #37

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013su1ttRiMeMYxkZJ1Y3246
2026-09-13 21:48:31 +02:00
alexandrev-tibco 4008eb7fa0 2.1.2: build 91 subida a TestFlight
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013su1ttRiMeMYxkZJ1Y3246
2026-09-12 18:06:51 +02:00
alexandrev-tibco 4579b9bb69 watch: enviar la semana aunque todavia no este planificada
Faltaba la otra mitad del "no se actualiza": makePayload devolvia nil cuando la
semana en curso no tenia plan creado, asi que el iPhone no mandaba nada — ni
respondia cuando el reloj pedia datos — y el reloj se quedaba con el ultimo
snapshot, el del miercoles. Ahora la semana viaja igualmente, vacia, y el reloj
dice que no hay nada planificado en vez de enseñar lo de hace dias.

Ademas el reloj muestra cuando se actualizo por ultima vez. Sin eso, un
snapshot viejo y uno recien llegado se ven igual, y no hay forma de saber si
el problema es el envio o lo que se pinta.

Refs #34, #35

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013su1ttRiMeMYxkZJ1Y3246
2026-09-12 16:32:34 +02:00
alexandrev-tibco 649fe6d453 2.1.2: build 90 subida a TestFlight
2.1.1 ya estaba READY_FOR_SALE con el build 88, asi que Apple rechazo el 89 por
version repetida (90062). La 2.x continua en 2.1.2, que es lo que llevan ahora
los tres Info.plist con version hardcodeada y MARKETING_VERSION.

Incluye la configuracion de dias y comidas por semana (premium) y el arreglo del
Apple Watch, que enseñaba el dia en que se genero el envio en vez de hoy.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013su1ttRiMeMYxkZJ1Y3246
2026-09-12 13:34:25 +02:00
alexandrev-tibco a049e4f74b watch: el dia de hoy se resuelve al pintar, no al generar el envio
El iPhone marcaba isToday al construir el snapshot y el reloj se creia esa
marca para siempre. Como el snapshot sobrevive en el app group, un sabado
seguia enseñando la cena del miercoles: el dia que era cuando se genero.

Ahora cada dia viaja con su fecha real y el reloj busca hoy cuando dibuja. Si
el snapshot es de otra semana no hay "hoy" que enseñar, asi que en vez de
colar la comida de otro dia lo dice y pide abrir el iPhone. Para snapshots
guardados por versiones anteriores, que no traen fecha, solo se confia en el
indice del dia mientras el propio snapshot sea de esta semana.

Ademas el reloj pide datos al abrirse y el iPhone, en vez de responder con lo
ultimo que cacheo, reconstruye la semana desde el store — que es la otra mitad
del "no se actualiza": el cache podia ser de hace dias.

Y cuando no hay nada planificado se dice, que antes era un guion indistinguible
de una comida marcada como no planificada: "Hoy no hay nada planificado" para
el dia entero y "Sin planificar" por comida, en los 6 idiomas (el bundle del
reloj no tiene cadenas propias, viajan en el envio).

Refs #34, #35

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013su1ttRiMeMYxkZJ1Y3246
2026-09-12 13:21:21 +02:00
alexandrev-tibco d8345a5b20 Revert "hogar compartido: colaboracion entre cuentas sobre Firestore"
El hogar compartido cambia donde viven los datos, asi que se va a la 3.0 y la
2.x queda para correcciones. El trabajo sigue vivo en la rama 3.0.0 (163fd60).

Importante para esta rama: esto tambien retira el entitlement
com.apple.developer.applesignin, que sin la capability marcada en el App ID
habria roto la firma al subir la 2.1.1 a TestFlight.

This reverts commit 163fd60.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013su1ttRiMeMYxkZJ1Y3246
2026-09-12 13:08:27 +02:00
alexandrev-tibco 163fd6026a hogar compartido: colaboracion entre cuentas sobre Firestore
CloudKit sincroniza la base privada de un Apple ID: ni llega a Android ni deja
que dos cuentas editen el mismo plan (CKShare sigue sin existir en SwiftData).
El contenido de un hogar pasa por tanto a Firestore, y un dispositivo que entra
en un hogar construye el store local sin CloudKit — dos espejos escribiendo los
mismos objetos se pelean, que es justo lo que ya obligó a apagar el sync por
iCloud KV.

SwiftData sigue siendo el store local y el modo offline; HouseholdSyncService es
lo unico que habla con la red. Detecta cambios comparando una huella del
contenido de cada documento con la ultima sincronizada (el "shadow"), asi que no
hace falta instrumentar con updatedAt las treinta vistas que mutan modelos. Los
borrados van como tombstone: un borrado duro volveria desde cualquier miembro
que estuviera sin conexion.

Semanas y slots usan id derivado del contenido (2026-09-14, 5-dinner) para que
dos miembros que abren la misma semana escriban el mismo documento en vez de
crear dos, y para que los conflictos se resuelvan por slot y no por semana.

Incluye reglas de seguridad (solo miembros; los codigos de invitacion se pueden
leer por id pero no listar), pantalla de hogar en Ajustes con Sign in with Apple,
invitacion por codigo de 6 caracteres sin vocales ni 0/O/1/I, y la eleccion al
unirse entre llevarse los platos propios o adoptar los del hogar.

Fuera de esta fase: fotos de platos (necesitan Storage) y el cliente Android.

Refs #33

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013su1ttRiMeMYxkZJ1Y3246
2026-09-12 13:00:38 +02:00
alexandrev-tibco 66128e7a5c premium: configurar días y comidas de una semana concreta
Hasta ahora includeWeekends y activeMealTypes vivían solo en AppSettings y
aplicaban a todo el calendario. WeekPlan puede ahora sobreescribirlos para su
semana (includeWeekendsOverride / mealTypesOverrideRaw) y WeekSchedule resuelve
qué manda en cada semana: su override si lo tiene, los ajustes globales si no.

Todo lo que pintaba días y comidas —planificador, exports, compartir texto,
widget, watch— pasa por settings.schedule(for:), así que una semana con fin de
semana añadido o con desayuno activo se ve igual en todas partes.

Crear o editar el override es premium; los ya guardados se respetan aunque la
suscripción caduque, para no borrar comidas ya planificadas. La hoja avisa y
pide confirmación cuando quitar un día o una comida se lleva por delante algo
ya planificado.

Refs #32

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013su1ttRiMeMYxkZJ1Y3246
2026-09-12 12:05:34 +02:00
alexandrev-tibco e58227a113 2.1.1: release notes en 6 idiomas
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013H6bXqGX1ygwib1Dm3n3UG
2026-09-10 22:29:26 +02:00
alexandrev-tibco 2d8c303f81 2.1.1: build 88 subida a TestFlight
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013H6bXqGX1ygwib1Dm3n3UG
2026-09-10 21:58:06 +02:00
alexandrev-tibco 24a6743ed2 reglas: los avisos se calculan del plan actual, no de una marca guardada
Un plato aparecia en la lista de incumplimientos sin explicacion (captura
del usuario: "Ensalada campera"): findViolations listaba los slots con
isRuleOverridden, una marca puesta al asignar que quedaba obsoleta cuando
el conflicto ya se habia resuelto. Y al reves, editar una regla despues
de planificar no detectaba nada.

- findViolations recorre el plan y reporta solo lo que incumple AHORA,
  siempre con sus razones (nunca una entrada vacia)
- MealSlot.isRuleIgnored: "Ignorar" pasa a ser persistente, porque si no
  el aviso recalculado volveria enseguida; se resetea al cambiar o
  quitar el plato del hueco
- El triangulo del calendario usa tambien el estado real
- Campo en el payload KV (opcional, retrocompatible) y en el esquema
  CloudKit de Development
- 3 tests: marca obsoleta no se lista, regla endurecida despues se
  detecta, y lo ignorado no reaparece

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013H6bXqGX1ygwib1Dm3n3UG
2026-09-10 21:54:37 +02:00
alexandrev-tibco 7b340be305 2.1.1: build 87 subida a TestFlight
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013H6bXqGX1ygwib1Dm3n3UG
2026-09-10 21:17:39 +02:00
alexandrev-tibco ff5c6c7895 home: aviso visible de incumplimientos con acceso al detalle
El panel de avisos solo se alcanzaba desde el menu "..." de la barra, asi
que los incumplimientos pasaban desapercibidos. Ahora, cuando la semana
rompe reglas, aparece un banner bajo el selector de semana con el numero
de comidas afectadas, un resumen de donde estan (Lun - Cena, Mie -
Comida) y un boton Ver que abre el panel con la explicacion y el arreglo.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013H6bXqGX1ygwib1Dm3n3UG
2026-09-10 21:14:49 +02:00
alexandrev-tibco 1c62182f61 2.1.1: build 86 subida a TestFlight
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013H6bXqGX1ygwib1Dm3n3UG
2026-09-10 21:10:07 +02:00
alexandrev-tibco 718eef16bf reglas: el panel explica que se incumple y como arreglarlo; stats por etiqueta
- RuleViolation.reasons: el motor devuelve ahora QUE regla rompe cada
  asignacion (repetido en la semana, maximo por semana superado, no
  consecutivo, no mismo dia, solo comida/cena, solo entre semana o fin
  de semana) con su etiqueta y limite
- Panel de avisos: bloque con cada regla rota en lenguaje claro + una
  sugerencia de que hacer, y boton nuevo "Cambiar plato" que abre el
  selector de ese hueco (antes solo se podia quitar o ignorar)
- Estadisticas: matriz "Etiquetas por tipo de comida" (p.ej. cuantas
  cenas son de pescado) y "Platos por etiqueta" del catalogo
- Tests: 4 casos de las razones de incumplimiento; harness que renderiza
  las secciones nuevas de stats a /tmp/stats_render.png
- Strings en 6 idiomas

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013H6bXqGX1ygwib1Dm3n3UG
2026-09-10 21:06:42 +02:00
alexandrev-tibco 9406c3f8e7 2.1.1: build 85 subida a TestFlight
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013H6bXqGX1ygwib1Dm3n3UG
2026-09-10 20:56:09 +02:00
alexandrev-tibco 4894c8b6eb home: el selector de semana sale de la toolbar a su propia barra
En premium la barra de navegacion lleva cuatro botones a la izquierda y
mas a la derecha; el ToolbarItem(.principal) se comprimia y iOS
recortaba las flechas, dejando solo el titulo — por eso no aparecian en
el iPhone del usuario aunque en el simulador (modo free, dos botones) se
vieran bien. Ahora el selector es una barra propia bajo la navegacion:
flechas en circulo blanco con borde coral y el rango de semana con
chevron.down al centro. Verificado con captura forzando los botones
premium.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013H6bXqGX1ygwib1Dm3n3UG
2026-09-10 20:53:12 +02:00
alexandrev-tibco 3a4314d6ce 2.1.1: build 84 subida a TestFlight
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013H6bXqGX1ygwib1Dm3n3UG
2026-09-10 20:32:06 +02:00
alexandrev-tibco c3b2b632ca 2.1.1: bump de version (2.1.0 aprobada y publicada con Apple Watch)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013H6bXqGX1ygwib1Dm3n3UG
2026-09-10 20:21:45 +02:00
alexandrev-tibco 22e65148a3 home: navegacion de semanas visible (flechas en circulo + hint en titulo)
Los chevrons finos coral sobre la barra ya coral eran invisibles en la
practica — un usuario premium no encontraba como planificar la semana
siguiente. Ahora son botones circulares blancos con chevron en negrita,
y el titulo lleva un chevron.down que delata que abre el selector de
semana. UI test de regresion: navegar a la semana siguiente debe
renderizar sus huecos sin paywall (la creacion del plan al navegar ya
funcionaba, verificado con captura).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013H6bXqGX1ygwib1Dm3n3UG
2026-09-10 20:11:44 +02:00
alexandrev-tibco e77d1c2f80 2.1.0: release notes en 6 idiomas
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013H6bXqGX1ygwib1Dm3n3UG
2026-09-10 06:40:59 +02:00
alexandrev-tibco df449705e8 2.1.0: build 82 subida a TestFlight
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013H6bXqGX1ygwib1Dm3n3UG
2026-09-09 09:50:06 +02:00
alexandrev-tibco 0067a807ea watch: texto de la complicacion proporcional y complicacion de 3 dias
- La rectangular de hoy escala el texto segun comidas: 1 comida -> 17pt
  (hasta 3 lineas), 2 -> 15pt, 3 -> 12pt; antes 12pt fijo y con dos
  comidas quedaba enano
- Nueva complicacion "MealMood - 3 dias": hoy + los dos siguientes en
  una linea por dia (abreviatura en coral si es hoy + platos)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013H6bXqGX1ygwib1Dm3n3UG
2026-09-09 09:47:38 +02:00
alexandrev-tibco 653aa75264 2.1.0: build 81 subida a TestFlight
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013H6bXqGX1ygwib1Dm3n3UG
2026-09-08 23:35:17 +02:00
alexandrev-tibco bd8090c845 watch: fix del sync que nunca llegaba y rediseno estilo Calendar/Weather
- El primer push se descartaba: updateApplicationContext se llamaba antes
  de que WCSession terminara de activarse (activacion asincrona). Ahora
  la sesion se activa al arrancar la app (ContentView), el payload
  pendiente se envia al completarse la activacion, y ademas el reloj
  PIDE los datos al abrirse (sendMessage despierta al iPhone en segundo
  plano y responde con el snapshot del app group)
- Rediseno: Hoy con cabecera del dia en coral y tarjetas degradadas por
  comida (estilo Weather); Semana con circulo de dia a la izquierda y
  hoy relleno en coral (estilo Calendar); complicacion con iconos
  tintados por comida y widgetAccentable
- Verificado con capturas en simulador de Watch sembrando el app group

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013H6bXqGX1ygwib1Dm3n3UG
2026-09-08 23:32:55 +02:00
alexandrev-tibco db36054df0 2.1.0: build 80 subida a TestFlight (primera con Apple Watch)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013H6bXqGX1ygwib1Dm3n3UG
2026-09-08 23:16:12 +02:00
alexandrev-tibco 7ad1033a76 fastlane: destination en vez de sdk global y widgets a build 80
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013H6bXqGX1ygwib1Dm3n3UG
2026-09-08 23:13:35 +02:00
alexandrev-tibco 639afb7303 2.1.0: bump a build 79 (la subida fallo por el sdk global de gym)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013H6bXqGX1ygwib1Dm3n3UG
2026-09-08 23:13:17 +02:00
alexandrev-tibco c8b3e7d28d 2.1.0: firma de distribucion para los targets watch
- App IDs registrados via API (watchkitapp Y94D5WRDTA, widget 42DL286P8H)
  con capability App Groups; perfiles AppStore creados e instalados
- Release de los targets watch en firma Manual con sus perfiles;
  EXPORT_OPTIONS de fastlane con los 4 bundle ids
- Pendiente (tarea Vikunja): asignar el grupo concreto a los App IDs en
  el portal (la API publica no lo permite) y regenerar perfiles

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013H6bXqGX1ygwib1Dm3n3UG
2026-09-08 17:47:29 +02:00
alexandrev-tibco c0b485387d 2.1.0: app de Apple Watch, complicacion y widget semanal en iOS
- Target MealMoodWatch (watchOS 10, SwiftUI): vista de hoy y de la
  semana en TabView vertical; recibe el snapshot del iPhone por
  WatchConnectivity (updateApplicationContext) y lo guarda en su app
  group para la complicacion
- Target MealMoodWatchWidget: complicacion accessoryRectangular/
  Circular/Inline con las comidas de hoy (heuristica comida/cena por
  hora); icono del watch generado desde el logo
- WatchWeekPayload compartido entre iOS app, widget iOS, watch app y
  complicacion — llega ya localizado desde el iPhone
- Widget iOS nuevo "Semana" (systemMedium/Large) con los 7 dias;
  el widget de hoy pasa a WidgetBundle
- Targets creados via gema xcodeproj (sin abrir Xcode); embed del watch
  antes del script de Crashlytics para evitar ciclo de build

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013H6bXqGX1ygwib1Dm3n3UG
2026-09-08 16:38:58 +02:00
alexandrev-tibco a9a9d6bdf0 2.0.5: build 78 subida a TestFlight
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013H6bXqGX1ygwib1Dm3n3UG
2026-09-07 08:07:20 +02:00
alexandrev-tibco b4c8dab850 2.0.5: widget a build 78 antes de fastlane beta
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013H6bXqGX1ygwib1Dm3n3UG
2026-09-07 08:04:54 +02:00
alexandrev-tibco 0b57812a6e premium: enlaces a privacidad y terminos (EULA) en los flujos de compra
Guideline 3.1.2(c): Apple rechazo la 2.0.5 (77) por no tener enlaces
funcionales a la politica de privacidad y los terminos de uso dentro
del paywall. Anadidos en PremiumView y en el paywall del onboarding
(mealmood.app/privacy.html y terms.html), y ambos enlaces al final de
la descripcion del App Store en los 6 idiomas.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013H6bXqGX1ygwib1Dm3n3UG
2026-09-07 08:04:39 +02:00
alexandrev-tibco 62c5febcbf 2.0.5: release notes en 6 idiomas
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013H6bXqGX1ygwib1Dm3n3UG
2026-09-05 14:30:46 +02:00
alexandrev-tibco 76349c8a6b 2.0.5: build 77 subida a TestFlight
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013H6bXqGX1ygwib1Dm3n3UG
2026-09-01 16:19:24 +02:00
alexandrev-tibco cdafc5c640 2.0.5: widget a build 77 antes de fastlane beta
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013H6bXqGX1ygwib1Dm3n3UG
2026-09-01 16:16:54 +02:00
alexandrev-tibco 6fe16d8e29 huecos sin planificar y exclusiones en la lista de la compra
- MealSlot.isSkipped: opcion "No planificar esta comida" en el picker de
  hueco vacio — cuenta como resuelto (semana completa, notificaciones,
  stats) y el autocompletado lo respeta; vista gris con guion, tap para
  desmarcar; viaja en undo, snapshot KV (junto con isEatingOut, que
  faltaba en el payload) y exports (— en imagen, omitido en texto)
- ShoppingItem.isDismissed: "Ya lo tengo" por ingrediente (swipe
  izquierdo) y "Ya esta hecho" por plato entero (boton en la cabecera de
  su seccion); van a la seccion "Ya en casa" con restauracion de un tap,
  y quedan fuera del export de texto. No se borran porque reconcile los
  recrearia
- Esquema CloudKit Development: CD_isSkipped, CD_isDismissed y el record
  type CD_ShoppingItem entero, que no existia — la lista de la compra no
  estaba sincronizando entre dispositivos (mismo bug que photoData)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013H6bXqGX1ygwib1Dm3n3UG
2026-09-01 16:16:34 +02:00
alexandrev-tibco ed1a0f566f 2.0.5: build 76 subida a TestFlight
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013H6bXqGX1ygwib1Dm3n3UG
2026-09-01 16:07:02 +02:00
alexandrev-tibco 025c8ab53d 2.0.5: widget a build 76 antes de fastlane beta
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013H6bXqGX1ygwib1Dm3n3UG
2026-09-01 16:04:38 +02:00
alexandrev-tibco 715dd4ec5e export: revision UX de estilos, 2 estilos nuevos y copia como texto
- Header elegante: logo fijado a la izquierda y titulo centrado de verdad
  (ZStack), fecha a la derecha
- School transpuesto: dias como columnas y comidas como filas — antes con
  1-2 comidas quedaba media pagina A4 apaisada en blanco
- Default: las celdas del grid se expanden para llenar la pagina (mismo
  sintoma de hueco que el school)
- Estilo nuevo "Story" (9:16, 2160x3840) para stories de IG/WhatsApp y
  "Minimal (imprimir)" en A4 con lineas finas sin fondos (ahorro tinta)
- Picker del preview pasa de segmentado a chips desplazables (5 estilos)
- WeekPlanTextExporter + boton "Copiar como texto (WhatsApp)" en el
  preview: menu semanal con *negritas* y emojis listo para pegar en
  WhatsApp/Telegram (evento analytics format=text)
- Harness de render en tests: genera PNG de los 5 estilos con datos de
  ejemplo en /tmp/mealmood-export-previews para revisar el diseno
- Nombres de estilos en espanol corregidos (estaban en ingles)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013H6bXqGX1ygwib1Dm3n3UG
2026-09-01 16:04:07 +02:00
alexandrev-tibco dc1a76275b 2.0.5: build 75 subida a TestFlight
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013H6bXqGX1ygwib1Dm3n3UG
2026-09-01 13:35:37 +02:00
alexandrev-tibco 8e7e849e26 2.0.5: widget a build 75 antes de fastlane beta
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013H6bXqGX1ygwib1Dm3n3UG
2026-09-01 13:33:08 +02:00
alexandrev-tibco 729239c6ef export: logo del header elegante a la izquierda (estilo membrete)
En school/vertical el logo centrado sobre el titulo quedaba mal; ahora
va a la izquierda con el rango de semana y el titulo alineados al lado,
y la fecha de export a la derecha.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013H6bXqGX1ygwib1Dm3n3UG
2026-09-01 13:32:23 +02:00
alexandrev-tibco 98820c5564 2.0.5: build 74 subida a TestFlight
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013H6bXqGX1ygwib1Dm3n3UG
2026-09-01 13:10:58 +02:00
alexandrev-tibco cd0b2588ad 2.0.5: widget a build 74 antes de fastlane beta
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013H6bXqGX1ygwib1Dm3n3UG
2026-09-01 13:08:23 +02:00
alexandrev-tibco 41cb8b4c50 export: branding en los tres estilos (logo, wordmark degradado, tagline)
- Logo real de la app en el header de los 3 estilos (antes solo en el
  default, y pequeno) y en el footer junto a un wordmark MealMood en
  degradado coral->verde con tagline localizada en cursiva
- "Powered by MealMood" y "Scan me" estaban hardcodeados en ingles;
  ahora share_footer_tagline y share_footer_scan en 6 idiomas
- Titulo del header default con el mismo degradado; QR con borde coral

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013H6bXqGX1ygwib1Dm3n3UG
2026-09-01 13:08:00 +02:00
alexandrev-tibco e5252a3fd8 export: vista previa con selector de estilo en la propia pantalla de export
- WeekExportPreviewSheet: preview renderizado del export con picker
  segmentado de los 3 estilos (cachea cada render); compartir usa el
  estilo elegido sin tocar el predeterminado (salvo primera vez)
- Sustituye al WeekExportStylePickerSheet de thumbnails y al doble
  sheet picker+share de HomeView; strings nuevas en 6 idiomas

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013H6bXqGX1ygwib1Dm3n3UG
2026-09-01 13:06:21 +02:00