PWA mono-usuario, 100% en Cloudflare. Coach IA propio con vida propia (cron + Web Push). Registra nutrición por foto/dictado, gym guiado con plan versionado, ciclismo con GPS/HR, peso, sueño y entrenos de Garmin Connect. Pensado para que un solo usuario (tú) lo use como compañero diario en móvil.
URLs:
- Frontend (Cloudflare Pages): HTML + Alpine.js vanilla + Service Worker. Sin build, sin framework.
- Backend (Cloudflare Workers): D1 (SQLite), cifrado AES-GCM para credenciales, cron cada 30 min, Web Push.
- Auth: bearer token único, configurado en cliente la primera vez. Sin login UI clásico.
- LLM: configurable en Ajustes → IA (Anthropic / OpenAI / DeepSeek / Gemini vía OpenRouter). DeepSeek por defecto para texto nutricional (barato y preciso); modelos vision para fotos.
web/ → frontend PWA (deploy → Cloudflare Pages "evolvea")
api/ → Worker HTTP + cron (deploy → "evolvea-api")
d1/ → schema SQLite (aplicar manualmente tras cada ALTER)
_plan/ → notas internas de roadmap, no se despliega
Asume wrangler login hecho y Node 20+.
Existe ya una base llamada internamente rjj-trainer (legado, no se renombra). El
database_id en api/wrangler.toml es el que importa.
Para una BD nueva:
cd api
npx wrangler d1 create evolvea
# pega el database_id en wrangler.toml
npx wrangler d1 execute evolvea --remote --file ../d1/schema.sqlapi/.dev.vars tiene los secrets locales (ACCESS_TOKEN, ENCRYPTION_KEY, VAPID,
OPENROUTER_API_KEY). Sube todos al worker en producción:
./upload-secrets.sh# Backend
cd api && npx wrangler deploy
# Frontend
cd ../web && npx wrangler pages deploy . --project-name evolvea --commit-dirty=trueCada vez que hay un ALTER TABLE nuevo en d1/schema.sql, aplicar manualmente:
npx wrangler d1 execute evolvea --remote --command "ALTER TABLE … ADD COLUMN …"Nunca deploy de código sin aplicar primero las migraciones que ese código asume.
Cada release toca:
web/sw.js→const CACHE = 'evolvea-vNN'web/js/app.js→window.APP_VERSION = { version: 'vNN', builtAt: 'ISO' }web/index.html→?v=NNen los imports de CSS y JS
Visible en la app en Ajustes → Acerca de.
El repo es público; los datos no. Ver SECURITY.md para el modelo completo (bearer token, CORS allowlist, rate limiting, cifrado de credenciales Garmin, rotación de tokens).
- Idioma de la UI: español.
- Móvil primero, responsive desktop. La mayoría de pantallas se diseñan en mobile y
se ajustan con
@media (min-width: 720px)cuando hace falta. - Sin frameworks: Alpine.js gestiona el estado reactivo, fetch nativo para HTTP, CSS custom (no Tailwind).
- Iconos: SVG silueta con
fill="currentColor", no emojis en chrome de la app (verhumanization_protocol.mden_plan/si quieres aplicar el sweep completo).