Arquitectura
Estructura de carpetas
Sección titulada «Estructura de carpetas»emawell/├── src/│ ├── client/ # React SPA│ │ ├── pages/ # Routes principales (dashboard, checkin, programa, semana)│ │ ├── components/ # Componentes reusables (shadcn/ui base)│ │ ├── lib/ # Helpers cliente (api, auth, etc.)│ │ ├── hooks/ # React hooks custom│ │ └── styles/ # Tailwind + design tokens│ ├── api/ # Hono routes — 14 módulos│ │ ├── auth.ts│ │ ├── pilares.ts│ │ ├── checkins.ts│ │ ├── stats.ts│ │ ├── pagos.ts│ │ └── …│ └── lib/ # Business logic│ ├── streak-engine.ts # Cálculo de racha + freeze (Pro)│ ├── achievement-engine.ts # Detección de achievements unlock│ ├── fhir-observations.ts # Generación de FHIR Observation por check-in│ ├── payment-gateway.ts # Webhooks Stripe│ ├── loops.ts # Email transaccional + nurture│ └── constants.ts # LOINC codes, tipos de pilar, etc.├── docs/ # SPEC v0.1, TASK (8 sprints, 82 features), ADRs├── public/ # PWA manifest, service worker└── scripts/ # Build y deploy[Usuario navega well.emahealth.io] ↓[React SPA en Cloudflare Pages] ↓ (fetch)[API Hono en Cloudflare Workers] ↓[Supabase REST con RLS] ↓[Postgres: schemas public + fhir]Patrón de routing
Sección titulada «Patrón de routing»- API: Hono bajo
/api/*(ruteo modular por archivo). - Frontend: React Router con páginas en
src/client/pages/.
Flujo principal — check-in diario
Sección titulada «Flujo principal — check-in diario»Usuario abre /checkin ↓Marca pilares done + valor opcional + energía + mood + notas ↓POST /api/checkins ├─→ Inserta daily_log + daily_log_entries (schema public) ├─→ fhir-observations.ts genera 1 Observation por pilar (schema fhir) │ códigos LOINC (vitales) o SNOMED (energy/mood) ├─→ streak-engine.ts actualiza streaks (general + por pilar) ├─→ achievement-engine.ts detecta unlocks (streak_7, phase_1, etc.) └─→ loops.ts triggerea nurture si aplica ↓Frontend muestra insight progresivo + nueva rachaCrons (Cloudflare Workers)
Sección titulada «Crons (Cloudflare Workers)»| Cron | Cuándo | Qué hace |
|---|---|---|
| Weekly summary | Domingo 00:00 UTC | Email resumen semanal vía Loops.so |
| Streak at risk | Diario 20:00 UTC | Email/push si user no hizo check-in del día |