From 4ceb64877fcf054cdd8fa6a6013fabd58d797b0b Mon Sep 17 00:00:00 2001 From: brobert Date: Mon, 13 Oct 2025 01:15:23 +0200 Subject: [PATCH] docs: actualiza README.md y docs/operations.md y plan-interfaz-web.md Co-authored-by: aider (openrouter/openai/gpt-5) --- README.md | 8 +++++--- docs/operations.md | 15 ++++++++++++--- docs/plan-interfaz-web.md | 21 +++++++++++++-------- 3 files changed, 30 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index ce9aef9..16e2820 100644 --- a/README.md +++ b/README.md @@ -17,7 +17,7 @@ Taskbot ayuda a coordinar grupos en WhatsApp: crea y asigna tareas, recuerda pen - Control de acceso por grupos: modos off, discover y enforce; aprobación y bloqueo por admins. - Sincronización de grupos y miembros con cachés y schedulers configurables. - Alias de identidad con normalización de IDs. -- Acceso web por token mágico (/t web), tokens de 10 min de un solo uso (migración y emisión implementadas). +- Acceso web por token mágico (/t web) con página intermedia anti-preview y sesión por cookie (idle 2h); tokens de 10 min de un solo uso. - Métricas listas para Prometheus en el endpoint /metrics. - Rate limiting por usuario para evitar abuso. - Persistencia simple con SQLite, migraciones automáticas y PRAGMAs seguros (WAL, FK, etc.). @@ -27,7 +27,7 @@ Taskbot ayuda a coordinar grupos en WhatsApp: crea y asigna tareas, recuerda pen - No es un framework general de bots ni un CRM. - No conecta directamente con WhatsApp: requiere Evolution API. - No gestiona flujos conversacionales complejos ni multimedia avanzada. -- Panel web en desarrollo (MVP de login en marcha); hoy la interacción principal es vía WhatsApp. +- Panel web en progreso: login operativo y vista básica de tareas; la interacción principal sigue siendo WhatsApp. - Está optimizado para un despliegue por comunidad/instancia (no multi-tenant masivo). ## Cómo funciona (alto nivel) @@ -38,6 +38,7 @@ Taskbot ayuda a coordinar grupos en WhatsApp: crea y asigna tareas, recuerda pen 4. Las respuestas se encolan y envían a través de Evolution API. 5. Schedulers ejecutan sincronización de grupos/miembros, recordatorios y tareas de mantenimiento. 6. Las métricas se exponen en /metrics (Prometheus o JSON). +7. Un proxy interno en Bun sirve web y bot bajo el mismo dominio: /webhook y /metrics → bot; el resto → web. ## Uso básico @@ -93,7 +94,8 @@ Consulta: - Nombre provisional: “Taskbot”. - Licencia por definir (software libre; se evaluará GPLv3/AGPL/MIT/Apache-2.0). -- Progreso Etapa 1 (autenticación web): migración v10 (web_tokens/web_sessions) y comando /t web implementados; pendiente /login en la web y gestión de sesión (idle 2h). +- Progreso Etapa 1 (autenticación web): completada. /login (GET intermedio + POST), sesión con idle 2h, logout y ruta /app protegida; desplegado con proxy interno en Bun. +- Primer MVP de lectura: endpoint /api/me/tasks y listado básico en /app. - Roadmap y contribuciones: pendientes de publicación. ## Enlaces diff --git a/docs/operations.md b/docs/operations.md index d869a53..17cee69 100644 --- a/docs/operations.md +++ b/docs/operations.md @@ -6,7 +6,9 @@ Variables de entorno (principales) - EVOLUTION_API_KEY: API key para peticiones salientes (contacts, etc.). - WEBHOOK_URL: URL pública del webhook (puede usarse para auto-registro/config). - WHATSAPP_COMMUNITY_ID: comunidad cuyos grupos se sincronizan. -- PORT: puerto HTTP (por defecto 3007). +- PORT: puerto HTTP del proxy interno (por defecto 3000). +- BOT_PORT: puerto interno del bot (por defecto 3007). +- WEB_PORT: puerto interno de la web SvelteKit (por defecto 3008). - NODE_ENV: 'development' | 'test' | 'production'. - METRICS_ENABLED: 'true'|'false'|'1'|'0' (por defecto habilitado salvo en test). Ej.: METRICS_ENABLED='true' - RATE_LIMIT_PER_MIN: tokens por minuto por usuario (default 15). @@ -29,9 +31,14 @@ Endpoints operativos - GET /metrics - 200 si Metrics.enabled() y formato Prometheus por defecto. - 404 si métricas deshabilitadas; 405 si método no permitido. +- GET /health + - 200 siempre (proxy interno), útil para healthcheck del contenedor. Arranque y servicios -- src/server.ts::start() +- src/server.ts::start() (bot) +- proxy.ts y startup.sh (contenedor único con Bun): + - El proxy escucha en PORT (3000 por defecto) y enruta /webhook y /metrics → BOT_PORT; el resto → WEB_PORT. + - startup.sh normaliza DB_PATH/DATA_DIR a absolutas, arranca bot, espera tablas web_tokens/web_sessions y arranca la web antes del proxy. - Valida entorno (logs de variables presentes/faltantes). - Aplica migraciones up-only. - Inicia HTTP y (según entorno) schedulers. @@ -46,7 +53,8 @@ Schedulers - Tarea diaria; borra miembros inactivos según retención. Datos y backups -- Data path: data/tasks.db (por defecto). +- Data path: /app/data/tasks.db (por defecto). +- startup.sh normaliza DB_PATH y DATA_DIR a rutas absolutas para que bot y web apunten al mismo archivo, y espera a que existan web_tokens/web_sessions antes de iniciar la web. - Migraciones con backup opcional (withBackup=false por defecto en initializeDatabase). - Recomendación: planificar copia de seguridad periódica del directorio data/ y retención externa. - DB_PATH permite aislar BD por rama/entorno sin tocar DATA_DIR; útil para pruebas en CapRover. @@ -66,6 +74,7 @@ Métricas de referencia Buenas prácticas - No arrancar schedulers en test salvo que FORCE_SCHEDULERS='true'. - Validar nuevas env en src/server.ts::validateEnv() y documentarlas aquí. +- En apps/web, kit.csrf.checkOrigin=false debido al proxy interno; considerar alternativas si se elimina el proxy. Formato de fechas en comandos - Se aceptan únicamente YYYY-MM-DD y YY-MM-DD (YY se expande a 20YY). diff --git a/docs/plan-interfaz-web.md b/docs/plan-interfaz-web.md index 1fdae28..9155209 100644 --- a/docs/plan-interfaz-web.md +++ b/docs/plan-interfaz-web.md @@ -4,7 +4,7 @@ Este documento define el plan para añadir una interfaz web al sistema, mantenie ## 1) Decisiones fijadas -- Arquitectura: dos procesos (apps/bot y apps/web). SvelteKit para la web (SSR, rutas de API, cookies). +- Arquitectura: dos procesos (apps/bot y apps/web) ejecutándose en la misma app de CapRover, con un proxy interno en Bun (puerto 3000) que enruta /webhook y /metrics al bot (3007) y el resto a la web (3008). SvelteKit para la web (SSR, rutas de API, cookies). - Acceso: enlace mágico por DM con token de 10 minutos, de un solo uso. Sin “recordarme”. - Sesión: cookie de sesión (HttpOnly, SameSite=Lax, Secure en prod) + expiración por inactividad de servidor de 2 horas. - Orden por defecto: tareas por creación descendente (más recientes primero). @@ -45,8 +45,8 @@ Este documento define el plan para añadir una interfaz web al sistema, mantenie - En /t web por DM: crear token aleatorio, guardar hash (no el token en claro), TTL 10 min, uso único, rate-limit por usuario. - Devolver URL del tipo: https://app.example.com/login?token=XYZ - Canje (web): - - GET /login muestra una página intermedia con formulario (y auto-submit JS) para evitar que los “link preview bots” canjeen el token. - - POST /login valida hash y caducidad; si ok, invalida el token (marcar usado). + - GET /login muestra una página intermedia sin auto-submit; requiere interacción mínima. Un script establece una cookie efímera login_intent y habilita el botón. + - POST /login valida hash y caducidad y comprueba la cookie login_intent; si ok, invalida el token (marcar usado). - Crea sesión en DB (web_sessions) y emite cookie de sesión (solo cookie de sesión, sin persistencia en disco). - Redirige a /app (sin token en la URL). - Expiración: @@ -55,6 +55,7 @@ Este documento define el plan para añadir una interfaz web al sistema, mantenie - Cookies: HttpOnly, SameSite=Lax, Secure (en prod), path acotado. - Rate limit en /login para evitar bruteforce de tokens. - Redirección inmediata tras canje para evitar fugas por Referer. + - CSRF: checkOrigin desactivado en SvelteKit debido al proxy interno que reenvía las peticiones (mismo dominio). ## 5) Calendario ICS @@ -100,7 +101,8 @@ Notas: ## 8) Endpoints (apps/web) - Autenticación: - - GET /login?token=… (canjea token, crea sesión, redirige a /app) + - GET /login?token=… (página intermedia con gate de JS) + - POST /login (canjea token, crea sesión, redirige a /app) - POST /api/logout (revoca sesión actual) - APIs (todas requieren sesión válida): - GET /api/me/tasks?status=open&search=...&page=...&limit=... @@ -164,8 +166,11 @@ Notas: - Build: - SvelteKit con adapter-node; ejecución con Bun o Node en producción. - Reverse proxy: - - apps/web servido en app.example.com (o /app). - - apps/bot mantiene su endpoint de webhook. Compartir .env según necesidad. + - Un solo contenedor con proxy interno en Bun: + - /webhook y /metrics → bot (puerto interno 3007). + - Resto de rutas → web (puerto interno 3008, SvelteKit adapter-node). + - CapRover debe exponer el puerto 3000 del contenedor (PORT). + - WEBHOOK_URL debe apuntar a https:///webhook (mismo dominio). - Schedulers: - Permanecen en el proceso del bot. apps/web no arranca ningún scheduler. @@ -179,10 +184,10 @@ Etapa 0 — Preparación Etapa 1 — Autenticación - Migraciones: web_tokens, web_sessions. — HECHO - Bot: emisión de token de 10 min (hash, rate limit) en /t web. — HECHO -- Web: endpoint /login, cookie de sesión, redirect limpio; hooks de sesión con idle timeout 2h. — SIGUIENTE +- Web: endpoint /login (GET intermedio + POST canje), cookie de sesión, redirect limpio; hooks de sesión con idle timeout 2h; gate de JS; CSRF checkOrigin desactivado por proxy interno. — HECHO - Páginas de error/expiración. -Etapa 2 — Lectura de datos (MVP) +Etapa 2 — Lectura de datos (MVP) — EN PROGRESO (API /api/me/tasks y UI básica en /app listas) - APIs: /api/me/tasks, /api/me/groups, /api/groups/:id/tasks, /api/me/preferences (GET). - UI: “Mis tareas” y “Grupos” (solo lectura). - Orden de creación desc, filtros básicos, búsqueda.