--- id: "0094" title: "kanban: bocadillo del agente + PDF descargable en reporte diario" status: pendiente type: feature domain: - kanban scope: multi-app priority: media depends: [] blocks: [] related: [] created: 2026-05-17 updated: 2026-05-17 tags: [] --- ## Problema El reporte diario (issue 0093) muestra tablas y graficos pero no resume el dia en lenguaje natural ni permite compartir el listado de tareas con solicitantes externos. ## Solucion ### Backend Migration 013 anade: - `daily_summaries (date PK, summary, prompt, model, generated_at, generated_by)` para cachear el resumen del agente por dia. - `settings (key PK, value, updated_at, updated_by)` clave/valor con un seed `daily_report_prompt` por defecto. Funciones en `daily_summary.go`: - `GetDailySummary(date)` / `UpsertDailySummary(rec)`. - `GetSetting(key)` / `SetSetting(key, value, by)`. - `runClaudePrompt(ctx, prompt)` ejecuta `claude -p --model ` con stdin = prompt y devuelve stdout. Reutiliza `claudeBinary()` y `claudeModel()` del chat. - `BuildDailySummaryPrompt(template, report)` interpola la plantilla con el JSON del reporte. - `GenerateDailySummary(ctx, date, tz, actor)` orquesta: report + template + claude + persist. Endpoints: - `GET /api/reports/daily/summary?date=YYYY-MM-DD` -> {exists, summary, prompt, model, generated_at, generated_by}. - `POST /api/reports/daily/summary?date=...&tz=...` regenera y persiste. - `GET /api/settings/{key}` -> {key, value}. - `PUT /api/settings/{key}` body {value} -> 204. ### Frontend `DailyReportView` ahora: - Carga el resumen al abrir (`getDailySummary`). Si no existe, muestra placeholder "Aun no hay resumen del dia". - Bocadillo visual: `Paper` azul claro con borde izquierdo gordo + icono `IconSparkles`, texto del resumen, fecha de generacion + modelo. - Boton `IconRefresh` -> `generateDailySummary`. Loader durante la llamada. - Boton `IconSettings` abre modal con el prompt actual (cargado via `getSetting`). Botones Guardar, Cancelar, Restablecer por defecto. - Filtros nuevos en la tabla de tareas hechas: `Select` solicitante + `Select` asignado. La tabla y el contador "N k/total" reflejan el filtro. - Boton "PDF": abre ventana nueva con HTML print-ready (page A4, CSS inline) que incluye: * Cabecera + sub con filtros activos. * 4 KPIs (Hechas filtradas, Lead time avg, Deadlines on-time, Reabiertas). * Resumen del agente como blockquote azul (si existe). * Tabla con links absolutos `${origin}/?card=${id}` para que el solicitante pueda saltar a cada card. * Auto `window.print()` al cargar. ### Tests `e2e/daily-summary-pdf.spec.ts`: - CRUD roundtrip del setting `daily_report_prompt`. - GET summary del dia devuelve estructura coherente (exists, summary). - UI: modal del reporte expone boton PDF, boton Configurar prompt y boton Regenerar. No invocamos `claude -p` real en CI (depende del binario externo). El generador se prueba manualmente. ## Criterios de aceptacion - [ ] Migration 013 crea ambas tablas con seed del prompt por defecto. - [ ] Bocadillo del agente arriba de "Tareas hechas". - [ ] Boton Regenerar invoca al agente, persiste y actualiza la UI. - [ ] Modal de configuracion permite editar y guardar el prompt; reset. - [ ] Filtros solicitante/asignado actualizan tabla y PDF. - [ ] PDF con tabla, KPIs y enlaces internos a cada card. ## Rama / commits - Rama: `issue/0094-kanban-daily-summary-pdf` - Merge `--no-ff` a master.