---
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 <m>` 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.
