App web familiar de rutinas visuales para niños con TDAH: muestra cada día el material del cole y las rutinas de tarde, con gamificación por monedas y tienda de recompensas. Multi-niño y bilingüe ES/CA. Uso doméstico/homelab. Backend (Spring Boot 3.5 / Java 21 / Gradle): - Dominio por capas, PostgreSQL + Liquibase, datos semilla. - API REST con DTOs: /today, toggle con monedas y bonos de bloque/día, monedero, tienda/canje, ajustes y CRUD del panel de padres. - Seguridad ligera por PIN (BCrypt + sesion en memoria), sin Keycloak. - Tests JUnit: generacion del dia, monedas/bonos con reversion, canje, seguridad. Frontend (Angular 19, standalone + signals): - Perfiles, Home (Tablero y Foco), Tienda y panel de padres (5 pestañas). - Tipografia OpenDyslexic conmutable (accesibilidad), i18n ES/CA, TTS y sonido. - Tokens de diseño fieles al handoff (paleta, animaciones, monedas voladoras). Empaquetado: - Docker multi-stage + docker-compose (PostgreSQL + backend + Nginx). - Decisiones de arquitectura documentadas en docs/adr.
2.4 KiB
ADR 0003 — Decisiones de dominio y seguridad (Fase 2 backend)
- Estado: aceptada
- Fecha: 2026-06-21
- Fase: 2 (dominio + API + seguridad)
Contexto
El contrato de backend deja varias decisiones "a tu criterio". Se documentan aquí las tomadas al implementar el dominio, la lógica de negocio y la seguridad.
Decisiones
-
i18n por columnas embebidas
label_es/label_ca(no tabla de traducciones). Encaja con el shape de los DTOs y simplifica las consultas. -
Capas, sin hexagonal completa. Entidad JPA como modelo de dominio (con comportamiento donde aporta: monedero en
Child, marcado enDailyTask), DTOs tiporecorden el borde. Nunca se exponen entidades. -
Mañana vs. tarde. La mañana se modela con
Activity(catálogo) +WeeklyTemplateEntry(asignación por día). La tarde conAfternoonRoutinedirecta por día. Se evita una FK polimórfica. -
Eventos = banner, no tareas. Los
SpecialEvent(examen/deberes) se muestran en el banner informativo del día (specialEvents[]), NO se materializan comoDailyTaskmarcables (coherente con el prototipo). El enumTaskOrigin.EVENTqueda disponible por si se decide lo contrario más adelante. -
Bonos reconciliables. El bono de bloque y el de día se modelan como transacciones de monedas con el mismo motivo: +importe al otorgar, -importe al revertir. "Suma neta > 0" indica bono activo. Hace el marcar/desmarcar robusto ante cualquier secuencia.
-
Seguridad ligera. PIN de padres con hash BCrypt; al validarlo se abre una sesión en memoria identificada por un valor opaco (cabecera
X-Parent-Session)./api/parents/**exige rol PARENT; el resto (kiosko del niño) es abierto. Todo encapsulado en el paquetesecuritypara poder sustituirlo por Keycloak. -
Semilla por
DataSeeder(ApplicationRunner, solo si la BD está vacía), no por Liquibase. Más mantenible y tipado. Desactivable conrecordalexia.seed.enabled=false(lo usan los tests). -
Tests sobre H2 (modo PostgreSQL) con Liquibase. Se valorará Testcontainers en una iteración posterior para fidelidad total con PostgreSQL.
Consecuencias
- Los textos visibles siempre viajan en ES y CA; el frontend elige idioma.
- Cambiar a Keycloak no afecta a controladores ni servicios de negocio.
- La zona horaria del negocio (Europe/Madrid) se centraliza en un
Clockinyectable.