Files
fn_registry/dev/issues/completed/0119-kanban-cpp-issues-flows-sync.md
T
egutierrez 7913116a8e chore: auto-commit (129 archivos)
- .claude/agents/fn-analizador/SKILL.md
- .claude/agents/fn-constructor/SKILL.md
- .claude/agents/fn-executor/SKILL.md
- .claude/agents/fn-mejorador/SKILL.md
- .claude/agents/fn-orquestador/SKILL.md
- .claude/agents/fn-recopilador/SKILL.md
- .claude/commands/app.md
- .claude/commands/compile.md
- .claude/commands/cpp-app.md
- .claude/commands/create_functions.md
- ...

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-06-01 22:23:12 +02:00

103 lines
4.4 KiB
Markdown

---
id: "0119"
title: "kanban_cpp: leer dev/issues + dev/flows como cards (sync layer)"
status: pendiente
type: feature
domain:
- cpp-stack
- kanban
- dev-loop
scope: app
priority: alta
depends:
- "0112"
blocks: []
related:
- "0008"
- "0109m"
- "0114"
created: 2026-05-18
updated: 2026-05-18
tags: [kanban, issues, flows, sync, frontmatter]
flow: "0008"
---
# 0119 — kanban_cpp sync layer: issues + flows como cards
## Problema
kanban_cpp (0112) clona el backend de kanban_web con `operations.db` vacia. Pero la intencion del flow 0008 es **gestionar issues y flows directamente desde kanban_cpp**. Sin sync con `dev/issues/*.md` + `dev/flows/*.md`, el board nace vacio y el usuario tendria que recrear cards a mano.
## Decision
Anadir endpoint al backend de kanban_cpp que lee frontmatter de los `.md` y los expone como cards/columnas virtuales. Lectura directa de filesystem (no via `issues_api` 0109m — el API service aun no existe; cuando exista, swap).
### Mapping `.md` -> card
| Frontmatter | Campo card |
|---|---|
| `id` | `card.external_id` |
| `title` | `card.title` |
| `status` (`pendiente`/`en-curso`/`done`/`deferred`) | `column` (mapping) |
| `priority` (alta/media/baja) | `card.priority` |
| `type` (feature/bug/chore/app) | `card.tag` |
| `tags` | `card.tags` |
| `flow` | `card.flow_id` |
| `dod_evidence_schema` (0114) | `card.dod_items[]` |
| body `## Problema` + `## Decision` | `card.description` |
### Mapping status -> columna kanban
```
pendiente -> Backlog
en-curso -> Doing
en-revisión -> Review
done -> Done
deferred -> Deferred
```
### Tableros separados
- Board `issues`: source = `dev/issues/*.md`.
- Board `flows`: source = `dev/flows/*.md`, columnas distintas (Pending / Running / Done / Deferred). flow body trae `## Definition of Done (user-facing, 4 surfaces obligatorios)`.
### Endpoints nuevos backend kanban_cpp
- `GET /api/boards/issues/cards` — lee `dev/issues/*.md`, cachea 30s.
- `GET /api/boards/flows/cards` — lee `dev/flows/*.md`, cachea 30s.
- `PATCH /api/boards/<board>/cards/<id>` — escribe vuelta al `.md` (cambia `status` en frontmatter). Usa `edit_yaml_frontmatter_go_core` del registry (verificar existe; si no, crear via fn-constructor).
- `POST /api/boards/<board>/cards/<id>/launch` — proxy a `agent_runner_api:8486/api/runs`.
### Watcher de cambios
`fsnotify` sobre `dev/issues/` + `dev/flows/`. Cuando hay write -> invalida cache + push SSE a UI -> kanban_cpp refresca board.
## Criterios de aceptacion
- [ ] `apps/kanban_cpp/backend/issues_source.go` parsea frontmatter via funcion del registry.
- [ ] `apps/kanban_cpp/backend/flows_source.go` idem para flows.
- [ ] Endpoints arriba implementados con tests.
- [ ] `fsnotify` watcher activo; cambio en `.md` propaga a UI en < 2s.
- [ ] PATCH actualiza solo el campo `status` del frontmatter, preserva resto.
- [ ] Round-trip: PATCH `/cards/0113` status=`en-curso` -> file mtime cambia -> `dev/issues/0113-*.md` tiene `status: en-curso`.
- [ ] Click `Launch` en card invoca `agent_runner_api` con `issue_id` + DoD items extraidos del frontmatter.
- [ ] Tag taxonomy issue 0103 respetada — solo statuses canonicos.
- [ ] kanban_cpp UI muestra ambos boards (tabs `Issues` / `Flows`) con cards reales del repo al arrancar.
- [ ] e2e_check: crear `.md` dummy -> aparece en board en <5s.
## Gotchas
- Frontmatter mal formado (yaml invalid): card aparece con badge `parse-error` + tooltip detalle. NO crashea backend.
- Cambios concurrentes: humano edita `.md` con vim mientras agente lo PATCHea via API. Usar lock file `.md.lock` corto + retry.
- `fsnotify` no funciona bien en WSL para `/mnt/c/` paths. Backend corre en WSL, lee paths nativos (`$HOME/fn_registry/dev/...`). Verificar.
- Issue / flow grandes (>500 lineas body): NO mandar full body en `/cards` (lento). Devolver solo frontmatter + primeras 5 lineas. Body completo via `/cards/<id>` on demand.
- Cards sin `status` (frontmatter incompleto): default `pendiente`.
- Reordenamiento manual: drag-and-drop en UI cambia status (cruzar columna) PERO no orden vertical persistente — no hay campo `order` en frontmatter. Decision: orden por `updated` desc dentro de cada columna.
## Out of scope
- Sync bidireccional con `issues_api` (0109m) — cuando exista, swap filesystem por API call.
- Conflict resolution manual (3-way merge UI).
- Edicion inline del body markdown desde la card (solo PATCH de `status` + `priority` por ahora).
- Bulk operations (mover N cards a la vez).