fad4006f60
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
80 lines
3.3 KiB
Markdown
80 lines
3.3 KiB
Markdown
---
|
|
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.
|