@ -13,7 +13,7 @@ Taskbot ayuda a coordinar grupos en WhatsApp: crea y asigna tareas, recuerda pen
## Características
- Gestión de tareas: crear, asignar, reclamar/soltar, fechas límite y código corto de referencia.
- Edición desde la web: reclamar/soltar y actualizar fecha de vencimiento desde /app.
- Edición desde la web: reclamar/soltar, editar descripción y actualizar fecha de vencimiento desde /app; completar tareas y ver “Completadas (24 h)”.
- Recordatorios configurables por usuario (frecuencia y hora, respetando zona horaria).
- 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.
@ -28,7 +28,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: login operativo, lista de tareas con acciones básicas (reclamar/soltar y editar fecha), vista de grupos (contadores "abiertas" y "sin responsable" con lista sin límite y botón “Reclamar”; tarjetas ordenadas por cantidad de “sin responsable”) y página de preferencias de recordatorios; la interacción principal sigue siendo WhatsApp.
- Panel web: login operativo, lista de tareas con acciones básicas (reclamar/soltar, editar texto y fecha, completar; sección “Completadas (24 h)”), vista de grupos (contadores "abiertas" y "sin responsable" con lista sin límite y botón “Reclamar”; tarjetas ordenadas por cantidad de “sin responsable”) y página de preferencias de recordatorios; la interacción principal sigue siendo WhatsApp.
- Está optimizado para un despliegue por comunidad/instancia (no multi-tenant masivo).
## Cómo funciona (alto nivel)
@ -104,7 +104,7 @@ Consulta:
- 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.
- Etapa 2 (lectura de datos - MVP): completada. GET /api/me/tasks (orden por due_date asc con NULL al final, búsqueda con ESCAPE, filtros soonDays/dueBefore, paginación page/limit), GET /api/me/groups (contadores open/unassigned) y GET /api/groups/:id/tasks (unassignedFirst, onlyUnassigned, limit). UI: /app (Mis tareas, filtros/búsqueda/paginación) y /app/groups (bloque “sin responsable” con prefetch).
- Etapa 3 (preferencias): completada. GET/POST /api/me/preferences y página /app/preferences con cálculo de “próximo recordatorio” coherente con la TZ y semántica del bot.
- Edición de tareas en web: completada. Reclamar/soltar y editar fecha desde /app y reclamar desde /app/groups; lista "sin responsable" sin límite y fichas ordenadas por cantidad de "sin responsable" (con gating y validación).
- Edición de tareas en web: completada. Reclamar/soltar, editar fecha y descripción desde /app; completar tareas y mostrar “Completadas (24 h)”; reclamar desde /app/groups; lista "sin responsable" sin límite y fichas ordenadas por cantidad de "sin responsable" (con gating y validación).
- Roadmap y contribuciones: pendientes de publicación.
- 200 siempre (proxy interno), útil para healthcheck del contenedor.
- APIs web (requieren sesión)
- GET /api/me/tasks?status=open&search=...
- Orden por fecha de vencimiento ascendente (NULL al final). Aplica gating por AllowedGroups + membresía activa (group_members). Búsqueda por descripción con LIKE y ESCAPE '\'. Filtros dueBefore y soonDays (en días). Paginación page/limit y campos hasMore/total en la respuesta.
- GET /api/me/tasks?status=open|recent&search=...
- status=open (por defecto): orden por due_date asc (NULL al final). Aplica gating por AllowedGroups + membresía activa (group_members). Búsqueda con LIKE ESCAPE '\'. Filtros dueBefore y soonDays (días). Paginación page/limit y hasMore/total.
- status=recent: tareas asignadas al usuario completadas en las últimas 24 h; orden por completed_at DESC; incluye campos completed y completed_at; mismo gating y búsqueda.
- GET /api/me/groups
- Devuelve solo grupos permitidos donde el usuario está activo. Incluye counts.open y counts.unassigned por grupo.
- GET /api/groups/:id/tasks?unassignedFirst=true
@ -48,8 +49,10 @@ Endpoints operativos
- Reclama la tarea para el usuario actual (idempotente). Requiere sesión; valida que la tarea esté abierta y aplica gating: t.group_id IS NULL o (grupo permitido y membresía activa).
- POST /api/tasks/:id/unassign
- Elimina la asignación del usuario actual (idempotente) si existe. Requiere sesión; tarea abierta y gating equivalente.
- POST /api/tasks/:id/complete
- Marca como completada (idempotente). Gating: si tiene group_id, cualquier miembro activo del grupo de un grupo allowed; si no tiene group_id, solo un asignado. Devuelve la tarea con completed y completed_at.
- PATCH /api/tasks/:id
- Actualiza campos básicos; actualmente solo admite { due_date: 'YYYY-MM-DD' | null }. Valida formato; requiere sesión, tarea abierta y gating.
- Actualiza { due_date: 'YYYY-MM-DD' | null, description?: string }. Valida due_date y normaliza/sanea description (texto plano, 1–1000 chars, colapsa espacios). Requiere sesión, tarea abierta y gating.
@ -13,7 +13,7 @@ Este documento define el plan para añadir una interfaz web al sistema, mantenie
- Calidad: tests de /app/preferences actualizados; resuelto warning de export no usado en TaskItem.
- Incidencia de producción resuelta: la causa era Content-Encoding (brotli/gzip) no compatible en la cadena. Se desactivó la compresión end-to-end: SvelteKit se construye con precompress=false y, en el proxy Bun, se fuerza Accept-Encoding: identity hacia la web y se eliminan Content-Encoding/Vary/Content-Length en las respuestas al cliente.
- Verificación: los assets /_app/* sirven 200 sin Content-Encoding y con Content-Type correcto. Estilos y JavaScript cargan correctamente.
- Edición de tareas en web integrada: reclamar/soltar y edición de fecha (PATCH /api/tasks/:id), con gating por AllowedGroups + membresía activa.
- Edición de tareas en web integrada: reclamar/soltar, edición de fecha y descripción (PATCH /api/tasks/:id), completar (POST /api/tasks/:id/complete) y sección “Completadas (24 h)” en /app; con gating por AllowedGroups + membresía activa.
- Grupos: botón “Reclamar” en tarjetas; listado "sin responsable" sin límite; fichas ordenadas por número de "sin responsable".
## 1) Decisiones fijadas
@ -120,7 +120,7 @@ Notas:
- 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=...
- GET /api/me/tasks?status=open|recent&search=...&page=...&limit=...
- GET /api/me/groups (grupos en los que está activo; solo allowed)
- GET /api/groups/:id/tasks?unassignedFirst=true (respeta gating y membresía)