Files
fn_registry/dev/issues/0130b-kanban-cpp-v2-backend.md
T
Egutierrez c468b24d2b feat(0130): kanban_cpp v2 — backend Go + 5 registry parser fns + epic/sub-issues
Registry (issue 0130a):
- 5 fns infra: parse_issue_md, write_issue_md, scan_issues_dir,
  scan_flows_dir, watch_dir_fsnotify
- 3 tipos: Issue, Flow, FsEvent
- Tests round-trip + scan reales + watcher fsnotify (all PASS)
- Capability group 'kanban' nuevo (docs/capabilities/kanban.md)

Apps:
- apps/kanban_cpp/ (sub-repo) — frontend ImGui: board drag-drop,
  flows, filters, detail con CSV editors
- apps/kanban_cpp/backend/ — Go service port 8487: REST + SSE +
  fsnotify watcher, parser bidireccional MD<->SQLite cache

Issues:
- dev/issues/0130-kanban-cpp-v2.md (epic)
- 0130a parser, 0130b backend, 0130c frontend

CMakeLists.txt: add_subdirectory apps/kanban_cpp (registrado por
init_cpp_app scaffolder).

End-to-end verde: backend devuelve 189 issues + 9 flows; PATCH a
/api/issues/{id} reescribe .md (solo frontmatter, body intacto);
frontend --self-test exit 0; tests Go infra 5/5 PASS.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-22 22:20:15 +02:00

3.4 KiB

id, title, status, type, domain, scope, priority, depends, blocks, related, created, updated, tags, flow
id title status type domain scope priority depends blocks related created updated tags flow
0130b Backend Go kanban_cpp v2: schema + handlers + watcher + SSE pendiente app
apps-infra
dev-ux
app-scoped alta
0130a
0130c
0130
2026-05-22 2026-05-22
service
kanban
go
sqlite
sse
0130

0130b — Backend Go kanban_cpp v2

Status: pendiente

Por que

Servicio HTTP local que sirve los issues + flows del proyecto al frontend C++. Es un wrapper fino sobre las funciones del registry de 0130a + SQLite cache + watcher.

Estructura

apps/kanban_cpp/backend/
  app.md                  # tag service
  go.mod
  main.go                 # entry: flags + run
  db.go                   # open + apply migrations + upsert helpers
  handlers.go             # endpoints REST
  sse_hub.go              # broadcaster
  watcher.go              # bind a watch_dir_fsnotify + re-ingesta + emit SSE
  ingest.go               # scan → upsert; usa 0130a
  migrations/
    001_init.sql
  operations.db           # creada en runtime

Endpoints

Verbo Path Notas
GET /api/health {ok:true, version, count_issues, count_flows}
GET /api/issues filtros: status, domain, priority, tag, scope
GET /api/issues/{id} issue + body
PATCH /api/issues/{id} partial update frontmatter → write_issue_md + re-ingesta + SSE
GET /api/flows filtros: status, kind
GET /api/flows/{id} flow + body
GET /api/meta enums leidos de dev/TAXONOMY.md
GET /api/sse stream {type, id, path}

CORS abierto local (*). Logger middleware.

Schema (migrations/001_init.sql)

CREATE TABLE IF NOT EXISTS issues (
    id           TEXT PRIMARY KEY,
    title        TEXT NOT NULL,
    status       TEXT NOT NULL,
    type         TEXT,
    scope        TEXT,
    priority     TEXT,
    domain_json  TEXT NOT NULL DEFAULT '[]',
    tags_json    TEXT NOT NULL DEFAULT '[]',
    depends_json TEXT NOT NULL DEFAULT '[]',
    blocks_json  TEXT NOT NULL DEFAULT '[]',
    related_json TEXT NOT NULL DEFAULT '[]',
    flow_id      TEXT,
    body         TEXT NOT NULL DEFAULT '',
    file_path    TEXT NOT NULL,
    mtime_ns     INTEGER NOT NULL,
    created_at   TEXT,
    updated_at   TEXT,
    completed    INTEGER NOT NULL DEFAULT 0  -- 1 si vive en completed/
);
CREATE INDEX IF NOT EXISTS idx_issues_status ON issues(status);
CREATE INDEX IF NOT EXISTS idx_issues_priority ON issues(priority);

CREATE TABLE IF NOT EXISTS flows (
    id           TEXT PRIMARY KEY,
    title        TEXT NOT NULL,
    status       TEXT,
    kind         TEXT,
    tags_json    TEXT NOT NULL DEFAULT '[]',
    body         TEXT NOT NULL DEFAULT '',
    file_path    TEXT NOT NULL,
    mtime_ns     INTEGER NOT NULL
);

DoD

  • curl http://localhost:8487/api/health devuelve 200 + counts.
  • curl http://localhost:8487/api/issues | jq 'length' >= 90.
  • curl -X PATCH /api/issues/0130 -d '{"status":"in-progress"}' reescribe dev/issues/0130-*.md (status updated, body intacto).
  • Despues del PATCH, suscriptor SSE recibe evento {type:"updated", id:"0130"}.
  • Tras mv dev/issues/0130-*.md dev/issues/completed/, watcher actualiza fila (completed=1).
  • go test ./... verde.

Anti-scope

  • No expone proposals ni capabilities (eso es MCP registry).
  • No autentica (local-only por ahora).
  • No persiste estado UI (eso lo hace el frontend).