Files
h-bitosInfantiles/CLAUDE.md
T
2026-07-03 17:36:19 -06:00

11 KiB
Raw Blame History

CLAUDE.md — Guía de desarrollo de Rachita

Este archivo orienta a cualquier agente de IA (Claude, Copilot, etc.) o desarrollador humano que trabaje en este repositorio. Contiene las decisiones de arquitectura ya tomadas, las convenciones a seguir y el estado/plan del proyecto. Léelo antes de escribir código.

El producto y sus requisitos completos están en PRD-Rachita.md. Este documento (CLAUDE.md) es el complemento técnico: cómo se construye, no qué se construye.


1. Resumen del proyecto

Rachita es una app de hábitos y creatividad para tablet Android, dirigida a niñas/niños de 610 años. Mascota virtual + hábitos diarios + rachas + museo de dibujos + sistema de monitoreo de batería (la mascota "se cansa" con poca batería y "duerme" mientras la tablet carga, bloqueando el uso).

Prototipo de referencia visual/UX: Rachita.html (bundle React exportado, no es el código fuente final — úsalo solo como referencia de diseño, animaciones, copy y flujos, ver §9).


2. Decisiones de arquitectura (confirmadas)

Decisión Valor
Plataforma cliente Android nativo (Kotlin) — sin iOS en v1
UI Android Jetpack Compose
Build system Android Gradle con Kotlin DSL (build.gradle.kts)
SDK mínimo Android API 26 (Android 8.0) — minSdk = 26
Package name mx.paputec.rachita
Backend ASP.NET Core Web API, .NET 10
Arquitectura backend REST clásico versionado (/api/v1/...) con capas Controller → Service → Repository
ORM Entity Framework Core (Code First + Migrations)
Base de datos PostgreSQL
Autenticación Sin login para la niña. Perfil local vinculado a un código de familia (family code) para emparejar Rachas en equipo. Gate parental simple (no es "auth" real) para pantallas sensibles (Ajustes, invitaciones)
Persistencia local Android v1: la app funciona con almacenamiento local simple (DataStore/Room mínimo) para hábitos/museo offline-first; sincronización real con backend se agrega cuando se implemente "Rachas en equipo". Room completo con sync es deseable, no bloqueante
Hosting backend Servidor Ubuntu propio, vía Docker (contenedor de la API) + Nginx como reverse proxy + systemd para gestionar el stack
Repositorio Monorepo único: git.paputec.mx/johannvelazquez/h-bitosInfantiles con carpetas /app (Android) y /backend (.NET)
CI/CD No configurado todavía. Se agrega más adelante (posible runner de build dedicado, ver skill migrate-ci-build-runner si aplica)
Testing Sí, desde el inicio: JUnit/Compose UI tests en Android, xUnit en .NET
Assets de la mascota Se mantiene el enfoque ilustrativo por código (formas vectoriales/Compose Canvas), igual que el prototipo HTML — no hay assets de diseño gráfico todavía

2.1 Alcance del primer sprint (MVP real, no todo el PRD)

Construir solo estos 3 módulos primero, de punta a punta (UI + lógica + persistencia local, sin backend aún):

  1. Onboarding / Selección de compañero (Avatar)
  2. Dashboard principal de hábitos y rachas
  3. Sistema de Monitoreo de Batería (overlay batería baja + pantalla de bloqueo en carga)

Los demás módulos del PRD (Museo, Galería, Rachas en equipo, Alertas/notificaciones, Widgets) se abordan en sprints posteriores, en ese orden de prioridad salvo indicación contraria.


3. Estructura del repositorio (monorepo)

h-bitosInfantiles/
├── CLAUDE.md                 ← este archivo
├── PRD-Rachita.md             ← requisitos de producto completos
├── Rachita.html                ← prototipo visual (referencia, no se ejecuta en prod)
├── README.md
├── app/                        ← proyecto Android (Kotlin + Jetpack Compose)
│   ├── build.gradle.kts
│   ├── settings.gradle.kts
│   └── app/
│       └── src/main/java/mx/paputec/rachita/
│           ├── ui/            ← pantallas Compose por feature
│           ├── data/          ← repos locales, DataStore/Room, modelos
│           ├── domain/        ← casos de uso / lógica de negocio
│           └── di/            ← inyección de dependencias (Hilt)
└── backend/                    ← proyecto .NET 10 Web API
    ├── Rachita.sln
    ├── src/
    │   ├── Rachita.Api/           ← Controllers, Program.cs, DI, middlewares
    │   ├── Rachita.Application/   ← Services, DTOs, interfaces
    │   ├── Rachita.Domain/        ← Entidades, reglas de negocio puras
    │   └── Rachita.Infrastructure/ ← EF Core, DbContext, Repositories, Migrations
    └── tests/
        └── Rachita.Api.Tests/

Regla: el código Android nunca depende directamente de EF Core ni del backend; se comunica solo vía API REST (DTOs propios en el cliente).


4. Convenciones de código

4.1 Android / Kotlin

  • Arquitectura por feature dentro de ui/ (ej. ui/onboarding, ui/dashboard, ui/battery), no por tipo de archivo.
  • Patrón MVVM: Screen.kt (Composable) + ViewModel.kt (StateFlow de UI state) + UiState data class.
  • Inyección de dependencias con Hilt.
  • Nombres: PascalCase para Composables y clases, camelCase para funciones/variables, UPPER_SNAKE_CASE para constantes.
  • Un Composable por archivo cuando sea una pantalla completa; sub-componentes pequeños pueden compartir archivo si son privados (private fun).
  • Preview de Compose (@Preview) obligatorio en componentes visuales reutilizables.
  • Colores, tipografías y espaciados centralizados en ui/theme/ (Color.kt, Type.kt, Shape.kt) siguiendo la guía de estilo del PRD (§6).
  • Animaciones con animateFloatAsState, rememberInfiniteTransition, etc. — replicar timings del prototipo (ver PRD §6.4).

4.2 Backend / .NET

  • Separación estricta de capas: Api (controllers, DTOs de request/response) → Application (servicios, interfaces IXxxService) → Domain (entidades y reglas puras, sin dependencias externas) → Infrastructure (EF Core, DbContext, implementaciones de repositorios).
  • Controllers delgados: solo reciben request, llaman al service, devuelven response. Nada de lógica de negocio en el controller.
  • Repositorios detrás de interfaces (IHabitRepository, etc.) definidas en Application o Domain, implementadas en Infrastructure.
  • DTOs distintos de las entidades de dominio (nunca exponer entidades EF directamente en la API).
  • Migraciones EF Core versionadas y con nombre descriptivo (dotnet ef migrations add AddTeamStreaks).
  • Endpoints versionados: /api/v1/....
  • Convención REST: sustantivos en plural, verbos HTTP correctos (GET /api/v1/habits, POST /api/v1/habits/{id}/complete).

4.3 General

  • Idioma del código (nombres de variables, clases): inglés. Idioma de la UI/copy visible al usuario: español (MX), tal como en el PRD y el prototipo.
  • Commits: mensajes claros en español o inglés consistente por PR, formato libre (Conventional Commits deseable pero no obligatorio).
  • No se necesita documentar cada cambio en archivos markdown nuevos salvo que se pida explícitamente.

5. Modelo de datos de referencia

Basado en PRD §9, adaptado a EF Core (backend) y su equivalente local (Android):

Profile        (childName, avatarKind, customAvatarUri, level, xp, streak, familyCode)
Habit          (id, name, subtitle, icon, color, active, createdAt)
HabitLog       (habitId, date, done)              -- 1 registro por hábito por día
Artwork        (id, date, imageUri, title, note, medium)
TeamStreak     (id, ownerProfileId, partnerProfileId, sharedHabitId, streak, week[7])
TeamStreakDay  (teamStreakId, date, myDone, theirDone, nudgedByMe, nudgedByThem)
Settings       (profileId, notifyLowBattery, notifyWhileCharging, habitReminderAt, confettiOn)

Reglas clave a implementar (ver PRD §5.2 y §5.7):

  • La racha global sube +1 solo si todos los hábitos activos del día quedaron done = true antes de medianoche.
  • En TeamStreak, la racha crece solo si myDone && theirDone el mismo día calendario.

6. Sistema de Monitoreo de Batería — notas técnicas

  • Usar BatteryManager / Intent.ACTION_BATTERY_CHANGED (o registerReceiver con IntentFilter(Intent.ACTION_BATTERY_CHANGED)) para leer nivel y estado de carga en tiempo real — no hacer polling manual.
  • Umbral batería baja: < 20% → mostrar overlay (Composable con Dialog o superposición a pantalla completa), no bloqueante, con opción "Ahora no".
  • Detección de carga: BatteryManager.EXTRA_STATUS == BATTERY_STATUS_CHARGING (o plugged != 0) → activar pantalla de bloqueo total (Activity/Composable a pantalla completa, sin back button funcional, ver PRD CA-01).
  • El botón "Ya la desconecté" debe verificar el estado real del sistema antes de desbloquear (no confiar ciegamente en el tap del usuario) — mitigación de riesgo listada en PRD §13.
  • Evaluar Screen Pinning (modo kiosco, PRD D-24) cuando se implemente el bloqueo, para impedir salir de la app durante la carga.

7. Cómo ejecutar el proyecto (a completar conforme se construya)

Android

cd app
./gradlew assembleDebug

Pendiente: confirmar si se usará emulador Android Studio o tablet física para pruebas (no definido aún).

Backend

cd backend
dotnet restore
dotnet ef database update --project src/Rachita.Infrastructure --startup-project src/Rachita.Api
dotnet run --project src/Rachita.Api

Docker (backend, producción)

docker build -t rachita-api ./backend
docker run -d -p 5000:8080 --env-file .env rachita-api

Pendiente definir: variables de entorno exactas, configuración de Nginx (dominio/subdominio), certificados TLS y compose file cuando se llegue al sprint de despliegue.


8. Pendientes / decisiones abiertas

Estas preguntas del PRD (§16) siguen sin resolver y pueden afectar el modelo de datos o la UX; confirmarlas antes de implementar el módulo correspondiente:

  1. ¿La racha global se pierde por completo al fallar un día, o hay "congelador" desde v1?
  2. ¿Los hábitos tienen horario límite individual?
  3. ¿Quién etiqueta el "medio" del dibujo (crayón/acuarela/…)?
  4. ¿Reporte/panel para el adulto en v1 o se pospone?
  5. Dominio/subdominio exacto y configuración de Nginx para el backend en el servidor Ubuntu (pendiente de confirmar con el usuario).
  6. Estrategia exacta de sincronización offline↔backend para hábitos y museo (más allá de "Rachas en equipo") aún no definida.

9. Uso del prototipo Rachita.html

Es un bundle exportado de una herramienta de diseño (contiene un manifiesto base64 + template comprimido), no es código fuente Kotlin/React reutilizable directamente. Úsalo solo para:

  • Extraer valores exactos de la guía de estilo (colores, radios, sombras, timings de animación).
  • Confirmar el copy exacto en español de cada pantalla.
  • Revisar el flujo de estados (showDash, isLow, isCharging, etc.) como referencia de máquina de estados al implementar el ViewModel de Compose.

Si necesitas inspeccionar su contenido interno, ya fue desempaquetado una vez en _extracted/ (carpeta temporal, no versionar en git — agregar a .gitignore si se conserva).