--- id: "0089" title: "kanban: tiempo maximo por columna con borde rojo" status: pendiente type: feature domain: - kanban scope: multi-app priority: media depends: [] blocks: [] related: [] created: 2026-05-17 updated: 2026-05-17 tags: [] --- ## Problema No hay forma de marcar visualmente cards que llevan demasiado tiempo en una columna. Cards estancadas se diluyen entre el resto. El campo `card.time_in_column_ms` ya existe en `/api/board`, falta el limite por columna y el borde visual. ## Solucion ### Migration (preserva datos) `apps/kanban/backend/migrations/011_column_max_time.sql` — `ALTER TABLE columns ADD COLUMN max_time_minutes INTEGER NOT NULL DEFAULT 0`. 0 = sin limite. ### Backend - `Column` struct: `MaxTimeMinutes int json:"max_time_minutes"`. - `ColumnPatch` + `UpdateColumn`: soporte para el nuevo campo, clamp a >= 0. - `handleUpdateColumn` (PATCH `/api/columns/:id`): acepta `max_time_minutes` opcional. - `ListColumns`: incluye el nuevo campo en el SELECT. ### Frontend - `Column` TS interface + `UpdateColumnInput`: nuevo campo. - `KanbanColumn` menu contextual: "Tiempo maximo" via `window.prompt` (idempotente, sin nuevo modal). Muestra valor actual en la entrada del menu si > 0. - `KanbanColumn` -> `KanbanCard`: prop nueva `columnOverdue` calculada como `!is_done && max_time_minutes > 0 && time_in_column_ms > max_time_minutes * 60_000`. - `KanbanCard`: cuando `columnOverdue` y NO highlighted ni locked, pinta `border-color: var(--mantine-color-red-6)` + `border-width: 2` + halo rojo. data-attribute `data-column-overdue` para tests. - Columnas con `is_done=true` nunca disparan overdue (regla del usuario). ### Tests - Backend Go: `TestColumnMaxTimeMinutes_Defaults`, `TestColumnMaxTimeMinutes_Update` (default 0, clamp negativo, no toca otros campos). - Frontend: testing visual del borde rojo via Playwright queda fuera de scope automatizado (requiere control de reloj o cards reales con > N min). Cubierto con verificacion manual al finalizar. ## Criterios de aceptacion - [ ] Migration aplica sin perder datos. - [ ] Menu contextual "Tiempo maximo" disponible en cada columna. - [ ] Borde rojo aparece en cards `time_in_column_ms > max_time_minutes * 60s` cuando `is_done=false`. - [ ] Columnas Done nunca muestran borde rojo aunque tengan limite configurado. - [ ] Tests Go pasan (2). ## Rama / commits - Rama: `issue/0089-kanban-column-max-time` - Merge `--no-ff` a master.