# STATUS — Rachita > Estado vivo del desarrollo. **Actualizar al cerrar cada hito o sesión de trabajo.** > Si retomas en un chat nuevo: lee CLAUDE.md (arquitectura/convenciones), PRD-Rachita.md (requisitos) y este archivo (dónde vamos), en ese orden. **Última actualización:** 2026-07-04 (sesión 3) — **SPRINT 1 COMPLETO (3/3 módulos verificados en dispositivo)** --- ## Sprint 1 — progreso | Módulo | Estado | Notas | |---|---|---| | 1. Onboarding / Selección de avatar | ✅ **Hecho y verificado en dispositivo real** | Compose + MVVM + DataStore; mascotas 100 % Canvas | | 2. Dashboard de hábitos + racha | ✅ **Hecho y verificado en dispositivo real, punta a punta** | Toggle → contador → racha → XP → banner → persistencia tras force-stop | | 3. Monitoreo de batería (overlay <20 % + bloqueo en carga) | ✅ **Hecho y verificado en dispositivo real, punta a punta** | CA-01..05 y BA-01..03 validados con batería simulada (`dumpsys battery`) | ### Verificado en dispositivo (2026-07-03, Huawei HBP-LX9, Android 12) - Onboarding completo: título, 4 tarjetas, mascotas animadas, badge, CTA, persistencia y navegación. - Fuentes Baloo 2 / Nunito cargan vía Downloadable Fonts (el equipo tiene Google Play Services). - Dashboard punta a punta: gate de arranque, seed de 3 hábitos, tarjetas con check animado + "¡Hecho!", contador "te quedan N", racha 0→1 con V del viernes palomeada, banner "¡Racha asegurada hoy! 🔥", XP 0→30/500, mensaje celebratorio de la mascota, chip de batería real (verde cargando), singular/plural de racha, y persistencia completa tras force-stop + relanzamiento. ### 🔎 Lecciones EMUI de esta sesión (para futuras pruebas en este equipo) - El header original (Row con `Alignment.Bottom` + `SpaceBetween` + texto con composable-en-template) medía ~270 dp fantasma SOLO en este dispositivo → la lista quedaba en altura 0 y las tarjetas ni se componían. Diagnóstico vía `uiautomator dump` (bounds de semántica), no vía screenshots. - Los taps de `adb input tap` a <40 px del borde inferior se los come la zona de gestos de EMUI. - `adb shell settings put global stay_on_while_plugged_in 7` activado para que no se bloquee la pantalla durante desarrollo (revertir con valor 0 cuando termine el sprint). ## Decisiones de producto tomadas en sesión 2 - **Racha v1 (DA-11):** se pierde completa al fallar un día; congelador pospuesto a v1.1 (recomendación del PRD §16.1). - **Horarios por hábito:** el subtítulo ("A las 9:00 pm") es copy descriptivo; todo hábito cuenta antes de medianoche. - **XP:** derivado 100 % de logs (10 XP por hábito hecho, nivel cada 500) — reversible y sin drift, igual que la racha. Sin tabla de recompensas aún (pregunta abierta §16.5). - **Racha mostrada:** incluye hoy en cuanto se completa todo (feedback inmediato); desmarcar la revierte. ## Historial de commits relevantes - `6f5bca6` chore(android): scaffold Gradle KTS + version catalog + manifest + recursos base - `1b5a1f7` feat(theme): paleta PRD §6 + Baloo 2/Nunito + shapes - `ae8f6b7` feat(onboarding): pantalla de avatar + mascotas Canvas + DataStore + NavHost - `3f7602e` fix(nav): placeholder de Dashboard con contenido visible (un Surface vacío parecía "pantalla en blanco" en pruebas) - `28f2359` feat(habits): Room (Habit/HabitLog) + StreakCalculator + 6 tests - `33de656` feat(battery): BatteryStatusMonitor (callbackFlow sobre sticky broadcast) - `1d34b78` feat(dashboard): módulo 2 completo — 3 columnas, checks animados, confeti, gate - `0eb4133` fix(dashboard): header a prueba de EMUI + weight en lista + singular de racha - `5ca619b` feat(ui): layout adaptativo — portrait compacto (<600dp) verificado en teléfono; tablet conserva 3 columnas ## Entorno de build (esta Mac) - **NO hay Android Studio.** JDK: `/opt/homebrew/opt/openjdk@17` (el cask temurin@17 no registró bien; exportar `JAVA_HOME` explícito siempre). - SDK: `/opt/homebrew/share/android-commandlinetools` (platforms 34+35, build-tools 34, platform-tools). `app/local.properties` ya apunta ahí (no versionado). - Build: `cd app && JAVA_HOME=/opt/homebrew/opt/openjdk@17 ./gradlew assembleDebug` - Instalar en dispositivo: mismo comando con `installDebug`. adb en `/opt/homebrew/share/android-commandlinetools/platform-tools/adb`. - ⚠️ `installDebug` falla intermitente si el teléfono bloquea la pantalla → `adb shell input keyevent KEYCODE_WAKEUP` y reintentar. - `compileSdk 35` / `targetSdk 34` / `minSdk 26` — androidx.core 1.15 exige compilar contra 35; NO "corregirlo" a 34. ## Decisiones tomadas - Fuentes por Downloadable Fonts (Google Fonts provider), sin .ttf empaquetados. Ojo: `Font(googleFont=...)` se importa de `androidx.compose.ui.text.googlefonts.Font`. - Mascotas vectoriales por código en `MascotIllustrations.kt`; estados tired/sleep se agregan con el módulo de batería. - Avatar "Mi dibujo" usa Photo Picker (`PickVisualMedia`) — cero permisos de almacenamiento. Recorte orgánico (AV-02) pendiente de pulido. - AV-08 (nombre configurable): ViewModel ya persiste `childName`, pero el onboarding no tiene campo de texto (el prototipo lo trata como prop, default "Lucía"). ## Deuda / pulido pendiente 1. Avatar personalizado ("Mi dibujo") aún no se muestra como imagen (falta Coil o similar en el catálogo); hoy cae al marco punteado. Recorte orgánico AV-02 pendiente. 2. ~~Layout apretado en teléfono~~ → resuelto con layout adaptativo (breakpoint 600 dp): portrait compacto en una columna, tablet conserva el diseño del PRD. Nota: el PRD pedía landscape-only en tablet; la orientación quedó desbloqueada — si se quiere volver a fijar SOLO en tablets, hacerlo por configuración en runtime, no en manifest. Menú de navegación no aparece en el layout compacto (destinos aún placeholder). 3. `confettiOn` (DA-05) hoy está fijo en true; se conecta cuando exista pantalla de Ajustes con gate parental. Confeti no confirmado visualmente en captura (el trigger sí disparó — banner y mensaje aparecieron); confirmar a ojo en dispositivo. 4. Campo de nombre en onboarding (AV-08): el ViewModel ya lo persiste; falta el input en UI. ## Resultado de la prueba del módulo 3 en dispositivo (2026-07-04) - CA-01 ✓ candado aparece solo al conectar USB (verificado 2 veces). CA-02 ✓ mascota dormida (ojos cerrados + Z) en cápsula con glow y estrellas. CA-03 ✓ "Cargando · N%" real. - CA-04 ✓ "Ya la desconecté" nunca desbloquea con el cable puesto; con `dumpsys battery unplug` el candado cae solo (la verificación es estructural, no del botón). - BA-01/02 ✓ overlay al 18 % sobre el dashboard con mascota cansada y % en negritas coral. - BA-03 ✓ en vivo: descartado en banda 20 → reapareció al caer a 14 % (banda 15). - CA-05 ✓ al 100 %: mascota despierta + "¡Desperté a tope de energía!". - Escape "salir (debug)" ✓ (solo builds debug). Rollover de día ✓ ("Sábado 4 de julio", hábitos reseteados). - Comandos de simulación: `dumpsys battery unplug` / `set level N` / `reset`. ## Próximos pasos (en orden) 1. Pulido menor: texto "Conectar cargador" se parte en 2 líneas apretadas en portrait; sudor de la mascota cansada poco visible en tamaños chicos. 2. Sprint 2 (orden CLAUDE.md §3.1): Museo (subir dibujo) → Galería → Rachas en equipo → Alertas → Widgets. 3. Backend .NET 10 + deploy PapuTec (CLAUDE.md §4), CI Gitea Actions — necesario para Rachas en equipo. ## Detalles de implementación del módulo 3 (para retomar) - `ui/battery/`: `BatteryUxViewModel` (estados None/LowBattery/Charging), `LowBatteryOverlay`, `ChargingLockScreen`; host en `MainActivity.BatteryUxHost` sobre el NavHost. - CA-04 es estructural: la pantalla de bloqueo se quita SOLO cuando `BatteryStatusMonitor` emite desconexión real; el botón nunca desbloquea. - BA-03: `LowBatteryPolicy` (dominio puro, 7 tests) — descartar en banda 20 silencia hasta caer a 15, etc. Conectar el cargador resetea el ciclo. - Mascota: `MascotMood.Idle/Tired/Sleep` en `MascotIllustrations.kt` (sudor menta, Z's con stagger de 3). - Escape de desarrollo: "salir (debug)" solo `BuildConfig.DEBUG` (el equipo de pruebas vive conectado por USB).