feat: main.cpp intenta HTTP API primero, fallback a SQLite

Nuevo flujo: por defecto conecta a sqlite_api en localhost:8484.
Si la API no responde, cae a SQLite directo. Flag --api para URL
custom. Launcher PowerShell actualizado con --api. app.md refleja
la nueva arquitectura dual HTTP/SQLite y dir_path del proyecto.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-04-13 01:37:09 +02:00
parent 0ef3da3bf5
commit 3de6b05357
3 changed files with 101 additions and 38 deletions
+36 -19
View File
@@ -2,8 +2,8 @@
name: registry_dashboard
lang: cpp
domain: tui
description: "Dashboard ImGui para visualizar el estado del fn_registry: KPIs, charts, tablas, desglose por lenguaje/dominio/pureza"
tags: [dashboard, imgui, visualization, registry]
description: "Dashboard ImGui para visualizar el estado del fn_registry. Consume datos via sqlite_api HTTP (fallback a SQLite directo). KPIs, charts, tablas, desglose por lenguaje/dominio/pureza."
tags: [dashboard, imgui, visualization, registry, http]
uses_functions:
- kpi_card_cpp_viz
- bar_chart_cpp_viz
@@ -17,24 +17,27 @@ uses_functions:
uses_types: []
framework: "imgui"
entry_point: "main.cpp"
dir_path: "apps/registry_dashboard"
dir_path: "projects/fn_monitoring/apps/registry_dashboard"
repo_url: "https://gitea-dgg044oo04woo4ggcsws4gk0.organic-machine.com/dataforge/registry_dashboard"
---
## Arquitectura
Dashboard C++ que lee `registry.db` directamente via SQLite C API y visualiza el estado completo del fn_registry.
Dashboard C++ con dos modos de acceso a datos:
**Data layer** (`data.cpp`): Carga todas las stats, desgloses y listas en un solo paso desde SQLite. Soporte para reload en caliente.
1. **HTTP API** (primario): Conecta a `sqlite_api` via HTTP para obtener datos de registry.db. No requiere acceso al filesystem.
2. **SQLite directo** (fallback): Lee registry.db directamente si la API no esta disponible.
**Data layers:**
- `data_http.cpp`: Carga datos via HTTP POST a sqlite_api (cpp-httplib + nlohmann/json)
- `data.cpp`: Carga directa desde SQLite C API
**Views** (`views.cpp`): Compone funciones del registry C++ para renderizar:
- 6 KPI cards: total functions, types, apps, analysis, tested%, pure%
- Bar charts: funciones por lenguaje, por dominio, actividad ultimos 30 dias
- Pie charts: pureza (pure/impure), kind (function/pipeline/component), tested/untested
- 8 KPI cards: functions, types, apps, analysis, unit tests, proposals, tested%, pure%
- Bar charts: funciones por lenguaje, por dominio
- Pie charts: pureza (pure/impure), kind (function/pipeline/component)
- Tablas: ultimas 20 funciones, apps, analysis, tipos
**Entrada**: Paths a `registry.db` como argumentos con fallback encadenado.
## Build
```bash
@@ -48,23 +51,37 @@ cd cpp && cmake -B build/windows -S . -DCMAKE_TOOLCHAIN_FILE=toolchains/mingw-w6
## Ejecucion
```bash
# Linux
./cpp/build/linux/apps/registry_dashboard/registry_dashboard /home/lucas/fn_registry/registry.db
# Via API (default, intenta conectar a localhost:8484)
./registry_dashboard
# Windows (PowerShell) — intenta WSL mount, luego local
# API explicita
./registry_dashboard --api http://192.168.1.10:8484
# Con SQLite fallback
./registry_dashboard --api http://127.0.0.1:8484 /path/to/registry.db
# Solo SQLite (sin API)
./registry_dashboard /path/to/registry.db
# Windows (PowerShell)
.\registry_dashboard.ps1
# Otra maquina — copiar .exe + .db al mismo dir
registry_dashboard.exe .\registry.db
```
## Dependencias vendored
| Libreria | Version | Archivo |
|----------|---------|---------|
| cpp-httplib | v0.18.3 | vendor/httplib.h |
| nlohmann/json | v3.11.3 | vendor/nlohmann/json.hpp |
## Roadmap
- [ ] Integrar Go runtime (CGo) para ejecutar comandos `fn` desde el GUI
- [ ] Filtros interactivos por lenguaje/dominio en sidebar
- [ ] Busqueda FTS5 integrada
- [ ] Busqueda FTS5 integrada via API
- [ ] Detalles de funcion al hacer click en tabla
## Notas
SQLite compilado estaticamente en Windows via amalgamation vendoreada. En Linux usa libsqlite3 del sistema.
- Por defecto intenta conectar a sqlite_api en `http://127.0.0.1:8484`. Si falla, usa SQLite directo.
- SQLite compilado estaticamente en Windows via amalgamation vendoreada. En Linux usa libsqlite3 del sistema.
- cpp-httplib usa sockets nativos (no OpenSSL) — solo HTTP, no HTTPS.
+59 -14
View File
@@ -2,23 +2,42 @@
#include "imgui.h"
#include "core/fullscreen_window.h"
#include "data.h"
#include "data_http.h"
#include "views.h"
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <string>
#include <fstream>
static RegistryData g_data;
static std::string g_db_path;
static std::string g_api_url;
static bool g_loaded = false;
static bool g_using_http = false;
static void reload_data() {
g_data = RegistryData{};
// Try HTTP API first
if (!g_api_url.empty()) {
g_loaded = load_registry_data_http(g_api_url, g_data);
if (g_loaded) {
g_using_http = true;
return;
}
fprintf(stderr, "HTTP API failed, falling back to SQLite\n");
}
// Fallback to direct SQLite
g_using_http = false;
if (!g_db_path.empty()) {
g_loaded = load_registry_data(g_db_path.c_str(), g_data);
if (!g_loaded) {
fprintf(stderr, "Failed to load registry data from: %s\n", g_db_path.c_str());
}
}
}
static void render() {
@@ -30,11 +49,17 @@ static void render() {
if (!g_loaded) {
fullscreen_window_begin("##error");
ImGui::TextColored(ImVec4(1, 0.3f, 0.3f, 1),
"Could not open registry.db");
"Could not load registry data");
ImGui::Spacing();
ImGui::Text("Tried: %s", g_db_path.c_str());
if (!g_api_url.empty())
ImGui::Text("API: %s (unreachable)", g_api_url.c_str());
if (!g_db_path.empty())
ImGui::Text("DB: %s", g_db_path.c_str());
ImGui::Spacing();
ImGui::TextWrapped("Usage: registry_dashboard <path1> [path2] [path3] ...");
ImGui::TextWrapped(
"Usage: registry_dashboard [--api URL] [db_path ...]\n"
" --api URL Connect to sqlite_api (default: http://127.0.0.1:8484)\n"
" db_path Direct SQLite path(s) as fallback");
ImGui::Spacing();
if (ImGui::Button("Retry")) {
reload_data();
@@ -47,26 +72,46 @@ static void render() {
}
int main(int argc, char** argv) {
if (argc < 2) {
fprintf(stderr, "Usage: registry_dashboard <db_path> [fallback_path ...]\n");
fprintf(stderr, " Tries each path in order until one opens successfully.\n");
return 1;
// Parse --api flag
std::vector<std::string> db_candidates;
bool api_explicit = false;
for (int i = 1; i < argc; i++) {
if (strcmp(argv[i], "--api") == 0 && i + 1 < argc) {
g_api_url = argv[++i];
api_explicit = true;
} else if (strncmp(argv[i], "--api=", 6) == 0) {
g_api_url = argv[i] + 6;
api_explicit = true;
} else {
db_candidates.push_back(argv[i]);
}
}
// Try each argument in order
for (int i = 1; i < argc; i++) {
std::string candidate = argv[i];
// Default: try localhost API if no --api given
if (!api_explicit) {
g_api_url = "http://127.0.0.1:8484";
}
// Resolve SQLite fallback path
for (auto& candidate : db_candidates) {
if (std::ifstream(candidate).good()) {
g_db_path = candidate;
fprintf(stdout, "Using: %s\n", g_db_path.c_str());
fprintf(stdout, "SQLite fallback: %s\n", g_db_path.c_str());
break;
}
fprintf(stderr, "Not found: %s\n", candidate.c_str());
}
if (g_db_path.empty()) {
// None found, use last arg so error screen shows something useful
g_db_path = argv[argc - 1];
if (g_api_url.empty() && g_db_path.empty() && db_candidates.empty()) {
fprintf(stderr, "Usage: registry_dashboard [--api URL] [db_path ...]\n");
fprintf(stderr, " --api URL Connect to sqlite_api (default: http://127.0.0.1:8484)\n");
fprintf(stderr, " db_path Direct SQLite path(s) as fallback\n");
return 1;
}
if (g_db_path.empty() && !db_candidates.empty()) {
g_db_path = db_candidates.back();
}
reload_data();
+3 -2
View File
@@ -1,5 +1,6 @@
$exe = Join-Path $PSScriptRoot "registry_dashboard.exe"
# Try API first (default), with SQLite fallback via WSL mount
& $exe `
"\\wsl.localhost\Ubuntu-22.04\home\lucas\fn_registry\registry.db" `
--api "http://127.0.0.1:8484" `
"\\wsl.localhost\Ubuntu-22.04\home\lucas\fn_registry\registry.db"