From 3de6b05357231280795fa44bdff452f0ef7b4228 Mon Sep 17 00:00:00 2001 From: Egutierrez Date: Mon, 13 Apr 2026 01:37:09 +0200 Subject: [PATCH] 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) --- app.md | 55 +++++++++++++++++++---------- main.cpp | 79 +++++++++++++++++++++++++++++++++--------- registry_dashboard.ps1 | 5 +-- 3 files changed, 101 insertions(+), 38 deletions(-) diff --git a/app.md b/app.md index 76cd35b..a09804e 100644 --- a/app.md +++ b/app.md @@ -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. diff --git a/main.cpp b/main.cpp index 13368a6..268e341 100644 --- a/main.cpp +++ b/main.cpp @@ -2,22 +2,41 @@ #include "imgui.h" #include "core/fullscreen_window.h" #include "data.h" +#include "data_http.h" #include "views.h" #include #include +#include #include #include 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{}; - 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()); + + // 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()); + } } } @@ -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 [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 [fallback_path ...]\n"); - fprintf(stderr, " Tries each path in order until one opens successfully.\n"); - return 1; + // Parse --api flag + std::vector 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(); diff --git a/registry_dashboard.ps1 b/registry_dashboard.ps1 index ea2022e..1827caa 100644 --- a/registry_dashboard.ps1 +++ b/registry_dashboard.ps1 @@ -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"