feat: cuentas de familia (multi-tenant), registro/login y preferencias

Convierte recordaLexia de una sola familia a multi-familia, con cuentas
propias y persistencia de preferencias.

Backend:
- Tenant Family (email único + contraseña BCrypt + PIN + prefs de cuenta);
  family_id en child/activity/material_item/reward; aislamiento por familia
  (acceso cruzado responde 404).
- Auth propia (sin Keycloak): registro/login email+contraseña, sesiones de
  familia persistidas en BD (sobreviven a reinicios), panel de padres tras PIN.
- Liquibase 002-multitenant; seeder crea una familia demo.
- Tests de aislamiento entre familias, registro/login y gate del panel.

Frontend:
- Login, registro y pantalla de cuenta; guards (sesion + PIN) e interceptor
  de sesion global; perfiles scopeados a la familia.

Preferencias:
- OpenDyslexic persistida por nino (child.dyslexiaFont) y default de cuenta.

Decisiones en docs/adr/0004.
This commit is contained in:
Jaume Garriga Maestre
2026-06-21 13:11:34 +02:00
parent 52e559a159
commit 24a0c8a0dd
72 changed files with 1959 additions and 647 deletions

View File

@@ -26,6 +26,7 @@ export interface ChildInfo {
language: Language;
soundEnabled: boolean;
ttsEnabled: boolean;
dyslexiaFont: boolean;
}
/** Tarea del día (mañana o tarde). Lleva texto ES y CA. */
@@ -94,6 +95,7 @@ export interface SettingsRequest {
soundEnabled?: boolean;
ttsEnabled?: boolean;
language?: Language;
dyslexiaFont?: boolean;
departureTime?: string;
}
@@ -185,6 +187,15 @@ export interface GamificationView {
coinsPerDay: number;
}
// ----- Auth / cuenta de familia -----
export interface MeResponse {
familyId: number;
email: string;
name: string;
uiLanguage: string;
defaultDyslexiaFont: boolean;
}
// ----- Panel de padres: peticiones -----
export interface ChildRequest {
name?: string;