# CLAUDE.md Guía para trabajar en **Mis 8 horas**: dashboard personal de ClickUp (NestJS + Angular) para cumplir 8 horas diarias de tareas completadas. La especificación completa está en `README.md`; léela antes de implementar algo nuevo. Este archivo solo recoge lo que no debe romperse. ## Estado del proyecto Fase de planificación: el prototipo `prototipo-html/` es la referencia de comportamiento. `backend/`, `frontend/` y `contracts/` se crean siguiendo el plan de la sección 10 del README (empezar por `contracts/` y `MetricsService` con sus pruebas). ## Estructura - `backend/`: NestJS. Único lugar con la API key y con las reglas de negocio. - `frontend/`: Angular 18+, standalone, signals, `@if`/`@for`. Solo muestra y envía acciones. - `contracts/`: tipos TypeScript compartidos, importados con `@contracts/*`. - `prototipo-html/`: respaldo autónomo. No tocar salvo que se pida. ## Reglas que no se negocian - **La API key de ClickUp vive solo en `backend/.env`.** Nunca en Angular, en respuestas de `/api/*`, en logs ni en git. `prototipo-html/config.js` también la contiene: no subirlo ni mostrarlo. - **Las métricas se calculan solo en el backend** (`MetricsService`). Angular no recalcula HPC, deuda ni rendimiento. - **`MetricsService` es puro:** sin HTTP, sin leer el reloj. "Hoy" entra como parámetro para que las pruebas sean deterministas. - **Fechas con Luxon y zona `America/Lima`** (`TZ`). Nunca `new Date()` sin zona para agrupar por día. - **El día de una tarea es su `due_date`.** `start_date` no se usa. La tarea se cuenta completa en ese día. - **Día libre:** meta, hueco y deuda en 0, y no cuenta como día transcurrido en el rendimiento semanal. Feriado y vacaciones se tratan igual. - **Sprint de un día:** se saca del **nombre** de la lista (`Sprint 19 (10/5 - 10/19)`), nunca de `start_date`/`due_date` de la lista. En un día límite gana el Sprint que empieza más tarde. - **Al mover o crear una tarea,** fijar las 12:00 hora local con `due_date_time: false`. - **Crear tarea:** estado `asignado`, estimado > 0, y Clientes, Jefatura, Sprint y asignado obligatorios. Los avisos (día libre, pasarse de la meta) no bloquean. - **Custom Field "Jefatura" es de tipo `users`:** se escribe como `{ add: [id], rem: [] }`. Una lista simple da `400 Invalid Value`. - Sin "deshacer" en las acciones sobre tareas; los errores se corrigen en ClickUp. ## Convenciones - **Idioma:** textos de interfaz, mensajes de error, commits y documentación en español. Identificadores de código en inglés. Textos en minúsculas tipo oración, sin mayúsculas sostenidas. - **Horas:** siempre `H:MM` en pantalla; los campos aceptan `2:30`, `2.5` o `2`. Internamente, milisegundos (`...Ms`). - **Frontend:** los componentes leen signals de `PlannerStore` y llaman a sus acciones; no usan `ApiService` directamente. Respetar los tokens de color del README (sección 9) y `prefers-color-scheme`. - **Backend:** validar entradas con `class-validator`; errores con formato Nest (`{ statusCode, message }`) y los códigos 401/400/502/429 del README. Caché con `@nestjs/cache-manager`, invalidada al crear, mover, estimar o cerrar. - Los ajustes y días libres se guardan en `backend/data/settings.json` y `backend/data/days-off.json`. ## Pruebas - Jest. `MetricsService` debe tener todas las pruebas de la sección 5.4 del README antes de pasar al resto del backend. - `SprintsService` y `ClickupClient` (paginación, mapeo de Clientes, envío de Jefatura) también tienen pruebas obligatorias. - Probar contra ClickUp real solo con tareas de prueba que se borren después. ## Pendiente de confirmar (no asumir) Estas decisiones dependen de quien mantiene el dashboard de la empresa; no cambiar el comportamiento sin confirmarlo (README, 2.2): - Qué estados cuentan como completados (hoy `closed` o `done`, lo que incluye `cancelado`). - Si las subtareas suman por separado o se descuentan del padre. - Si las horas cerradas en un día libre suman como extra o se excluyen. - Día por fecha de vencimiento o de inicio.