chore: untrack sqlite_api + registry.db, expand fn_monitoring docs
- sqlite_api se extrae a su propio repo Gitea (dataforge/sqlite_api), siguiendo la convencion de apps/*/ (cada app = su repo). - registry.db ya estaba en .gitignore (regenerable con fn index + fn sync), pero seguia tracked por historia. Destracked. - project.md de fn_monitoring ampliado con operacion completa: arranque del service (dev / start.sh / systemd user), flujo de datos dashboard, troubleshooting, como extender. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -7,18 +7,220 @@ repo_url: ""
|
||||
|
||||
## Apps
|
||||
|
||||
| App | Descripcion |
|
||||
|-----|-------------|
|
||||
| sqlite_api | API REST HTTP read-only para registry.db y operations.db (Go, net/http, puerto 8484) |
|
||||
| registry_dashboard | Dashboard ImGui con KPIs, charts y tablas del registry (C++, consume sqlite_api) |
|
||||
| App | Lang | Descripcion |
|
||||
|-----|------|-------------|
|
||||
| [sqlite_api](apps/sqlite_api/app.md) | Go | API REST HTTP read-only sobre `registry.db` y todas las `operations.db`. Puerto `8484`. |
|
||||
| [registry_dashboard](apps/registry_dashboard/app.md) | C++ / ImGui | Dashboard con KPIs, charts y tablas del registry. Consume `sqlite_api` (HTTP) con fallback a SQLite directo. |
|
||||
|
||||
Cada `app.md` es la referencia canonica del binario — endpoints completos, flags, dependencias. Este documento cubre **como operar el proyecto como un todo**: arranque, service, flujo de datos, troubleshooting.
|
||||
|
||||
---
|
||||
|
||||
## Arquitectura
|
||||
|
||||
```
|
||||
sqlite_api (Go, :8484)
|
||||
└── registry.db, apps/*/operations.db (read-only)
|
||||
↑
|
||||
registry_dashboard (C++/ImGui)
|
||||
└── HTTP GET/POST → sqlite_api
|
||||
└── Fallback: SQLite directo si API no disponible
|
||||
registry.db (raiz)
|
||||
apps/*/operations.db
|
||||
projects/*/apps/*/operations.db
|
||||
│ (read-only, mode=ro)
|
||||
▼
|
||||
┌──────────────────────────────────────────────┐
|
||||
│ sqlite_api (Go net/http, :8484) │
|
||||
│ /health │
|
||||
│ /api/databases │
|
||||
│ /api/databases/:db/tables │
|
||||
│ /api/databases/:db/schema │
|
||||
│ /api/databases/:db/query (POST, SELECT) │
|
||||
│ /api/databases/:db/fts │
|
||||
└──────────────────────────────────────────────┘
|
||||
▲
|
||||
│ HTTP GET/POST
|
||||
│ (cpp-httplib + nlohmann/json)
|
||||
│
|
||||
┌──────────────────────────────────────────────┐
|
||||
│ registry_dashboard (C++ / ImGui + ImPlot) │
|
||||
│ main.cpp → reload_data() │
|
||||
│ data_http.cpp (primario, HTTP) │
|
||||
│ data.cpp (fallback, SQLite C API) │
|
||||
│ views.cpp → KPI row, charts, tables │
|
||||
└──────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
**Separacion de responsabilidades:**
|
||||
|
||||
- `sqlite_api` **no conoce el dashboard**. Es una API generica: expone cualquier DB SQLite de `fn_registry/` read-only con FTS5.
|
||||
- `registry_dashboard` **no conoce la estructura de registry.db directamente**, solo a traves del JSON que devuelve la API. El modo SQLite directo es fallback para entornos sin red.
|
||||
|
||||
**Puerto `8484`** — elegido para no colisionar con Metabase (3000), Jupyter (8888) ni deploy_server (9090).
|
||||
|
||||
---
|
||||
|
||||
## Servicio sqlite_api
|
||||
|
||||
### Modos de arranque
|
||||
|
||||
| Modo | Comando | Cuando usarlo |
|
||||
|------|---------|---------------|
|
||||
| Dev (foreground, `go run`) | `cd projects/fn_monitoring/apps/sqlite_api && go run -tags fts5 .` | Iteracion rapida, ver logs en la terminal |
|
||||
| Dev (background) | `./start.sh` (dentro de `apps/sqlite_api/`) | Probar el dashboard rapido sin systemd. Escribe PID en `sqlite_api.pid` y log en `sqlite_api.log` |
|
||||
| Production (systemd) | `sudo systemctl start sqlite_api` | Arranque en boot, restart on failure, logs en journal |
|
||||
|
||||
### Variables de entorno
|
||||
|
||||
| Var | Valor | Proposito |
|
||||
|-----|-------|-----------|
|
||||
| `FN_REGISTRY_ROOT` | ruta absoluta a la raiz del registry | Evita que el binario busque `registry.db` subiendo por el cwd. Obligatoria bajo systemd. |
|
||||
|
||||
### Instalar como servicio systemd (local)
|
||||
|
||||
Usar el pipeline del registry `install_systemd_service_bash_pipelines`:
|
||||
|
||||
```bash
|
||||
cd /home/lucas/fn_registry
|
||||
|
||||
# 1. Build del binario
|
||||
CGO_ENABLED=1 go build -tags fts5 \
|
||||
-o projects/fn_monitoring/apps/sqlite_api/sqlite_api \
|
||||
./projects/fn_monitoring/apps/sqlite_api/
|
||||
|
||||
# 2. Instalar unit + enable + start (requiere sudo sin password para systemctl)
|
||||
source bash/functions/pipelines/install_systemd_service.sh
|
||||
install_systemd_service \
|
||||
--name sqlite_api \
|
||||
--exec "$(pwd)/projects/fn_monitoring/apps/sqlite_api/sqlite_api" \
|
||||
--workdir "$(pwd)" \
|
||||
--env "FN_REGISTRY_ROOT=$(pwd)" \
|
||||
--description "fn_registry SQLite HTTP API" \
|
||||
--after network.target \
|
||||
--restart on-failure
|
||||
```
|
||||
|
||||
### Operacion
|
||||
|
||||
```bash
|
||||
sudo systemctl status sqlite_api # estado + ultimas lineas del journal
|
||||
sudo systemctl restart sqlite_api # tras rebuild del binario
|
||||
sudo systemctl stop sqlite_api # parar
|
||||
journalctl -u sqlite_api -f # logs en vivo
|
||||
curl http://127.0.0.1:8484/health # health check
|
||||
```
|
||||
|
||||
### Redeploy tras cambios en el codigo Go
|
||||
|
||||
```bash
|
||||
cd /home/lucas/fn_registry
|
||||
CGO_ENABLED=1 go build -tags fts5 \
|
||||
-o projects/fn_monitoring/apps/sqlite_api/sqlite_api \
|
||||
./projects/fn_monitoring/apps/sqlite_api/
|
||||
sudo systemctl restart sqlite_api
|
||||
```
|
||||
|
||||
No hace falta reinstalar el unit — solo recompilar y reiniciar.
|
||||
|
||||
---
|
||||
|
||||
## Dashboard registry_dashboard
|
||||
|
||||
### Build
|
||||
|
||||
```bash
|
||||
cd cpp
|
||||
cmake -B build/linux -S .
|
||||
cmake --build build/linux --target registry_dashboard -j$(nproc)
|
||||
```
|
||||
|
||||
El binario queda en `cpp/build/linux/registry_dashboard` (o `projects/fn_monitoring/apps/registry_dashboard/registry_dashboard.exe` en Windows).
|
||||
|
||||
### Ejecucion
|
||||
|
||||
```bash
|
||||
# Modo API (por defecto, intenta localhost:8484)
|
||||
./registry_dashboard
|
||||
|
||||
# API remoto
|
||||
./registry_dashboard --api http://192.168.1.10:8484
|
||||
|
||||
# API + fallback SQLite
|
||||
./registry_dashboard --api http://127.0.0.1:8484 /home/lucas/fn_registry/registry.db
|
||||
|
||||
# Solo SQLite (sin API)
|
||||
./registry_dashboard /home/lucas/fn_registry/registry.db
|
||||
```
|
||||
|
||||
La UI muestra en la cabecera de donde vienen los datos (HTTP vs SQLite). `F5` recarga.
|
||||
|
||||
### Flujo de datos
|
||||
|
||||
1. `main.cpp::reload_data()` intenta HTTP primero via `load_registry_data_http()`.
|
||||
2. Si la API responde `200` y el JSON parsea, los datos pueblan `RegistryData`.
|
||||
3. Si falla la API (timeout, 5xx, JSON invalido) y hay `--db`, cae a `load_registry_data()` (SQLite directo).
|
||||
4. Si ninguno funciona, la UI muestra un mensaje de error y no hay reintento automatico — hay que pulsar reload.
|
||||
|
||||
### Vistas
|
||||
|
||||
| Seccion | Datos | Query subyacente |
|
||||
|---------|-------|------------------|
|
||||
| KPI row (8 cards) | totales y porcentajes | `SELECT COUNT(*)` sobre functions, types, apps, analysis, unit_tests, proposals + agregados tested/pure |
|
||||
| Charts (bar + pie) | funciones por lang/domain, reparto pure/impure, kind | `GROUP BY lang`, `GROUP BY domain`, `GROUP BY purity`, `GROUP BY kind` |
|
||||
| Tablas | ultimas 20 functions, apps, analysis, types | `ORDER BY updated_at DESC LIMIT 20` |
|
||||
|
||||
Detalle de composicion de componentes viz en `apps/registry_dashboard/app.md`.
|
||||
|
||||
---
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
| Sintoma | Causa probable | Verificacion / Fix |
|
||||
|---------|----------------|--------------------|
|
||||
| Dashboard dice "HTTP API failed, falling back to SQLite" | `sqlite_api` no esta corriendo | `curl http://127.0.0.1:8484/health` — si falla, `systemctl status sqlite_api` o `./start.sh` |
|
||||
| `sqlite_api` arranca y muere inmediatamente | No encuentra `registry.db` | Exportar `FN_REGISTRY_ROOT=/home/lucas/fn_registry` o correr desde la raiz del registry |
|
||||
| `systemctl start sqlite_api` pide password | Falta sudoers para systemctl | Ver `.claude/rules/deploy.md` — el usuario necesita `NOPASSWD` para `systemctl`, `mv` a `/etc/systemd/system/` |
|
||||
| Dashboard abre pero todas las cifras son 0 | API conecta pero devuelve DB vacia | `curl -X POST http://127.0.0.1:8484/api/databases/registry/query -d '{"sql":"SELECT COUNT(*) FROM functions"}'` |
|
||||
| API responde lento / timeout | Query pesada sobre FTS5 | Timeout hardcoded a 5s en `handlers.go`. Revisar la query en journal. |
|
||||
| Bind rechazado (`address already in use`) | Otro proceso en `8484` | `ss -tlnp | grep 8484` — matar el huerfano o cambiar `--bind` |
|
||||
|
||||
### Logs
|
||||
|
||||
```bash
|
||||
# systemd
|
||||
journalctl -u sqlite_api -n 100 --no-pager
|
||||
journalctl -u sqlite_api -f
|
||||
|
||||
# start.sh
|
||||
tail -f projects/fn_monitoring/apps/sqlite_api/sqlite_api.log
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Como extender
|
||||
|
||||
### Anadir un endpoint a sqlite_api
|
||||
|
||||
1. Registrar la ruta en `Server.Routes()` (`handlers.go`).
|
||||
2. Handler lee `r.URL.Path` / `r.Body`, delega en `DBPool` para resolver la DB, ejecuta SQL read-only.
|
||||
3. Test en `handlers_test.go` (patron: tabla de casos HTTP).
|
||||
4. Rebuild + `systemctl restart sqlite_api`.
|
||||
5. Documentar en `apps/sqlite_api/app.md` (tabla de endpoints).
|
||||
|
||||
### Anadir una vista al dashboard
|
||||
|
||||
1. Nuevo campo en `RegistryData` (`data.h`) + su equivalente en la respuesta JSON.
|
||||
2. Parseo en `data_http.cpp` y carga SQL en `data.cpp` (ambos paths, para mantener el fallback).
|
||||
3. Renderizado en `views.cpp` usando componentes del dominio `viz` (`kpi_card`, `bar_chart`, etc.) — ver regla `frontend_theming` analoga para C++: usar primitivos del registry antes que ImGui crudo.
|
||||
4. Rebuild con CMake.
|
||||
|
||||
### Anadir una DB nueva
|
||||
|
||||
La descubre automaticamente `DiscoverDatabases()` escaneando `apps/*/operations.db` y `projects/*/apps/*/operations.db`. No hay que registrar nada — al reiniciar `sqlite_api` aparecen con alias `ops:{app_name}`.
|
||||
|
||||
---
|
||||
|
||||
## Deploy en otros PCs
|
||||
|
||||
Este proyecto se instala identico en cualquier maquina con el registry clonado:
|
||||
|
||||
1. `fn sync` para traer los metadatos del proyecto.
|
||||
2. Build + systemd install (seccion "Instalar como servicio systemd" arriba).
|
||||
3. Build del dashboard.
|
||||
|
||||
Los datos son los `.db` locales — cada PC ve su propio estado del registry y sus propias `operations.db`. No hay sincronizacion remota de datos en este servicio: para eso existe `fn sync` contra `registry_api` (proyecto diferente, ver memoria `project_registry_api`).
|
||||
|
||||
Reference in New Issue
Block a user