chore: snapshot WIP previo + flow 0008 + 7 sub-issues (0112-0119)
Snapshot de WIP acumulado de sesiones previas antes de merge wave 1 del flow 0008 (kanban_cpp + agent_runner_api + DoD schema). Incluye: - dev/flows/0008-kanban-cpp-and-agent-workflows.md - dev/issues/0112-0119*.md (7 sub-issues) - WIP previo en cmd/fn/doctor.go, registry/*, modules/, cpp/, etc. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,169 @@
|
||||
---
|
||||
id: "0109m"
|
||||
title: "issues_api service: HTTP backend para issues+flows (skill_tree, kanban, dashboards)"
|
||||
status: pendiente
|
||||
type: feature
|
||||
domain:
|
||||
- meta
|
||||
- apps-infra
|
||||
scope: app-scoped
|
||||
priority: media
|
||||
depends: []
|
||||
blocks:
|
||||
- "0109h2"
|
||||
related:
|
||||
- "0109"
|
||||
- "0106"
|
||||
created: 2026-05-18
|
||||
updated: 2026-05-18
|
||||
tags:
|
||||
- service
|
||||
- go
|
||||
- http
|
||||
- issues
|
||||
- flows
|
||||
- api
|
||||
---
|
||||
|
||||
# 0109m — issues_api service
|
||||
|
||||
## Por que
|
||||
|
||||
`skill_tree.exe` corre en Windows nativo. Necesita leer `dev/issues/*.md` + `dev/flows/*.md` que viven en WSL `~/fn_registry/`. Opciones:
|
||||
|
||||
| Solucion | Pro | Contra |
|
||||
|---|---|---|
|
||||
| UNC `\\wsl.localhost\Ubuntu\home\lucas\fn_registry` | Cero infra extra | Hardcodea distro/user. No funciona si WSL caido. |
|
||||
| Service HTTP (este issue) | Robusto, reusable por otras apps (kanban, web dashboard) | Mas piezas que mantener |
|
||||
| Embeber YAML parser + nested fields | Self-contained | Mucha logica duplicada |
|
||||
|
||||
Fix UNC ya esta hecho (0109l). Pero el patron canonico del registry son services (services_api, sqlite_api, registry_api). Este issue formaliza `issues_api`.
|
||||
|
||||
## Spec
|
||||
|
||||
Service Go HTTP en puerto **8486**. Patron identico a `services_api` (issue 0106).
|
||||
|
||||
### Endpoints
|
||||
|
||||
- `GET /api/health` → `{"status":"ok"}`
|
||||
- `GET /api/issues` → array JSON con TODOS los issues (open + completed)
|
||||
- `GET /api/issues/:id` → un issue concreto con body markdown completo
|
||||
- `GET /api/flows` → array JSON con todos los flows
|
||||
- `GET /api/flows/:id` → un flow concreto
|
||||
- `GET /api/stats` → counts por status/domain/type (agregados para Dashboard)
|
||||
- `POST /api/issues` → crea nuevo issue (escribe `.md`). Body: `{id, title, type, domain, depends, body, dod}`. Devuelve `{path}`.
|
||||
- `POST /api/flows` → crea nuevo flow. Mismo shape adaptado a frontmatter de flows.
|
||||
|
||||
### Schema JSON issue
|
||||
|
||||
```json
|
||||
{
|
||||
"id": "0109",
|
||||
"title": "...",
|
||||
"status": "pendiente",
|
||||
"status_eff": "pendiente_unlocked",
|
||||
"type": "epic",
|
||||
"domain": ["meta", "cpp-stack"],
|
||||
"priority": "media",
|
||||
"depends": [],
|
||||
"blocks": [],
|
||||
"related": ["0085"],
|
||||
"tags": ["skill-tree"],
|
||||
"created": "2026-05-17",
|
||||
"updated": "2026-05-18",
|
||||
"file_path": "dev/issues/0109-skill-tree-app-roadmap.md",
|
||||
"body_md": "(opcional, solo en /api/issues/:id)",
|
||||
"dod": [{"text":"App existe","done":true}, ...]
|
||||
}
|
||||
```
|
||||
|
||||
### Implementacion
|
||||
|
||||
```go
|
||||
// apps/issues_api/main.go
|
||||
package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
"log"
|
||||
"os"
|
||||
// reusa funciones del registry:
|
||||
// - extract_frontmatter (Go port; existe extract_frontmatter_py_core, pero
|
||||
// en C++ existe parse_md_frontmatter_cpp_core — necesitamos Go port o
|
||||
// reusar yaml.v3 directo aqui).
|
||||
)
|
||||
|
||||
func main() {
|
||||
root := os.Getenv("FN_REGISTRY_ROOT")
|
||||
if root == "" { log.Fatal("FN_REGISTRY_ROOT not set") }
|
||||
mux := http.NewServeMux()
|
||||
mux.HandleFunc("/api/health", health)
|
||||
mux.HandleFunc("/api/issues", listIssues(root))
|
||||
mux.HandleFunc("/api/issues/", showIssue(root))
|
||||
mux.HandleFunc("/api/flows", listFlows(root))
|
||||
mux.HandleFunc("/api/flows/", showFlow(root))
|
||||
mux.HandleFunc("/api/stats", stats(root))
|
||||
log.Fatal(http.ListenAndServe(":8486", mux))
|
||||
}
|
||||
```
|
||||
|
||||
Frontmatter: existe `extract_frontmatter_py_core` (Python). Hace falta:
|
||||
- **Opcion A**: crear `parse_md_frontmatter_go_core` (port del C++). Reusable por otros services Go.
|
||||
- **Opcion B**: usar `gopkg.in/yaml.v3` directo dentro de `issues_api`.
|
||||
|
||||
Recomiendo **A** — Go port reusable. Pattern: header `parse_md_frontmatter.go` en `functions/core/`.
|
||||
|
||||
### Frontmatter service: block en app.md
|
||||
|
||||
```yaml
|
||||
service:
|
||||
port: 8486
|
||||
health_endpoint: /api/health
|
||||
health_timeout_s: 3
|
||||
systemd_unit: issues_api.service
|
||||
systemd_scope: user
|
||||
restart_policy: always
|
||||
runtime: systemd-user
|
||||
pc_targets:
|
||||
- aurgi-pc
|
||||
- home-wsl
|
||||
is_local_only: false
|
||||
```
|
||||
|
||||
### Skill_tree consume
|
||||
|
||||
Cambio en `skill_tree/main.cpp`:
|
||||
- Si `discover_registry_root()` falla, intentar HTTP `http://localhost:8486/api/issues`.
|
||||
- Si responde 200 → parsear JSON y poblar `g_scan.nodes`.
|
||||
- Fallback a UNC + file scan si no.
|
||||
|
||||
Cliente HTTP en C++:
|
||||
- Linux: `libcurl` (ya disponible) o `popen("curl ...")`.
|
||||
- Windows: WinHTTP nativo o curl.exe (Windows 10+ trae curl).
|
||||
- Mas simple: spawn `curl.exe -s http://...` y parsear stdout (nlohmann json — habria que vendor).
|
||||
|
||||
## Sub-issues
|
||||
|
||||
- **0109m1** — crear `parse_md_frontmatter_go_core` port del C++ (mismas semanticas, mismos tests).
|
||||
- **0109m2** — scaffolder `issues_api` app + service block + systemd unit.
|
||||
- **0109m3** — implementar endpoints GET (list, show, stats).
|
||||
- **0109m4** — implementar POST issues + POST flows (escribir .md valido).
|
||||
- **0109m5** — cliente HTTP en skill_tree + fallback chain (env > walk > UNC > HTTP).
|
||||
|
||||
## Beneficios cross-app
|
||||
|
||||
Una vez issues_api existe, reutilizan:
|
||||
- `kanban` (issue 0058 sync) podria leer/sync issues.
|
||||
- Frontend web dashboard ya tendria backend.
|
||||
- CI/automation puede crear issues via POST en lugar de editar .md a mano.
|
||||
- `services_monitor` mostrara `issues_api` como service mas (auto via `tag: service`).
|
||||
|
||||
## DoD
|
||||
|
||||
- [ ] `apps/issues_api/` scaffoldada via `/cpp-app` ?? no — Go service via `/app`.
|
||||
- [ ] Endpoints listed devuelven JSON valido.
|
||||
- [ ] systemd unit instalado (`issues_api.service`).
|
||||
- [ ] Visible en `services_monitor` como service activo.
|
||||
- [ ] skill_tree consume HTTP cuando esta disponible, cae a UNC/file si no.
|
||||
- [ ] Tests Go basicos (list, show, post).
|
||||
Reference in New Issue
Block a user