Files
registry_dashboard/data.h
T
egutierrez 87b7ef45ff feat(monitor): Monitor tab as primary landing + errors KPI + recent executions + date filter
Rebrand "Claude Usage" tab to "Monitor" and promote it to first/default tab in
the main TabBar. Monitor is the landing for the reactive loop (construir →
ejecutar → recopilar → analizar → mejorar).

UI additions:
- Local toolbar inside Monitor with date preset combo (1h / 24h / 7d / 30d /
  All), manual Refresh button, and live LED + last-event-ts indicator.
- 5 KPI cards (was 4): added "Errors" derived from COUNT(*) FROM calls WHERE
  success = 0 filtered by the active window.
- New sub-tab "Recent Executions" (first sub-tab) with columns: When,
  Function, Tool, ms, OK (check/X colored), Error class. Backed by calls
  table, sorted by ts DESC, limit 100, filtered by window.
- Violations sub-tab gains "When" column with formatted ts.

Data layer:
- data.h: RecentExecutionRow + window_secs + ws_connected/last_event_ts /
  last_seen_call_id watermark on ClaudeUsageData.
- data_http.{h,cpp}: load_claude_usage_http now takes window_secs and embeds
  ts_filter() in calls/errors/violations queries. total_errors populated.
  recent_executions populated up to 100 rows. New standalone
  load_recent_executions_http() for future WS-driven partial refetch.
- main.cpp: reload_data preserves window_secs across reloads; new
  reload_monitor() does a Monitor-only refetch when the user changes the
  window or clicks Refresh, without re-querying the full registry.

Wiring:
- views.h: draw_monitor + monitor_consume_reload_request() +
  monitor_set_ws_state() exported. draw_claude_usage removed.
- views.cpp: render() consumes monitor_consume_reload_request each frame
  and dispatches reload_monitor().

This is the UI half of issue 0086. The server-side WebSocket endpoint in
sqlite_api and the C++ WS client are next; the LED is wired to
monitor_set_ws_state but stays gray until those land.

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

234 lines
5.9 KiB
C++

#pragma once
#include <string>
#include <vector>
#include <cstdint>
struct RegistryStats {
int total_functions = 0;
int total_types = 0;
int total_apps = 0;
int total_analysis = 0;
int total_unit_tests = 0;
int total_proposals = 0;
int tested_functions = 0;
int pure_functions = 0;
int impure_functions = 0;
};
struct LangCount {
std::string lang;
int count = 0;
};
struct DomainCount {
std::string domain;
int count = 0;
};
struct KindCount {
std::string kind;
int count = 0;
};
struct DateCount {
std::string date; // YYYY-MM-DD
int count = 0;
};
struct FunctionRow {
std::string id;
std::string name;
std::string lang;
std::string domain;
std::string kind;
std::string purity;
std::string description;
std::string created_at;
bool tested = false;
};
struct AppRow {
std::string id;
std::string name;
std::string lang;
std::string domain;
std::string description;
std::string framework;
std::string repo_url;
std::string dir_path;
};
struct AnalysisRow {
std::string id;
std::string name;
std::string lang;
std::string domain;
std::string description;
};
struct TypeRow {
std::string id;
std::string name;
std::string lang;
std::string domain;
std::string algebraic;
std::string description;
};
struct VaultRow {
std::string id;
std::string name;
std::string path;
std::string description;
bool symlink = false;
};
struct ProjectRow {
std::string id;
std::string name;
std::string description;
int apps_count = 0;
int analyses_count = 0;
int vaults_count = 0;
};
// Test unitario asociado a una funcion (1:N — una funcion puede tener varios).
struct UnitTestRow {
std::string id;
std::string function_id;
std::string name;
std::string lang;
std::string file_path;
std::string code;
std::string created_at;
};
// Detalle completo de una funcion (codigo + documentacion).
// Cargado on-demand cuando el usuario selecciona una funcion en Explorer.
struct FunctionDetail {
std::string id;
std::string name;
std::string lang;
std::string domain;
std::string kind;
std::string purity;
std::string version;
std::string signature;
std::string description;
std::string code;
std::string documentation;
std::string notes;
std::string example;
std::string params_schema;
std::string uses_functions;
std::string uses_types;
std::string returns;
std::string error_type;
std::string file_path;
std::string created_at;
bool tested = false;
};
struct ProjectDetail {
std::string id; // "" si no hay seleccion; "orphans" para huerfanas
std::string name;
std::string description;
std::vector<AppRow> apps;
std::vector<AnalysisRow> analyses;
std::vector<VaultRow> vaults;
};
// All data loaded from registry.db in one shot
// Issue 0085: Claude usage telemetry rows from call_monitor.operations.db.
struct ClaudeUsageRow {
std::string function_id;
int calls_total = 0;
int calls_7d = 0;
int errors_total = 0;
double error_rate = 0.0;
double mean_duration_ms = 0.0;
};
struct ClaudeViolationRow {
std::string rule_id;
std::string function_id;
std::string command_snippet;
std::string severity;
long long ts = 0;
};
struct ClaudeCopiedRow {
std::string app_file;
std::string app_function;
std::string registry_id;
std::string kind;
double similarity = 1.0;
};
// Una invocacion concreta del registro de telemetria. Lo que el agente lanzo,
// cuanto tardo, si fallo. Usado por la tabla "Recent Executions" del Monitor.
struct RecentExecutionRow {
long long id = 0; // calls.id (watermark para WS deltas)
long long ts = 0; // epoch seconds
std::string function_id;
std::string tool_used; // mcp / fn_cli_run / bash / heredoc / ...
int duration_ms = 0;
bool success = true;
std::string error_class;
std::string session_id;
};
struct ClaudeUsageData {
bool available = false; // true if call_monitor.operations.db is reachable
int total_calls = 0;
int total_errors = 0;
int total_violations = 0;
int total_copies = 0;
int total_versions = 0;
std::vector<ClaudeUsageRow> top_functions; // top 20 by calls_total
std::vector<ClaudeViolationRow> recent_violations; // last 20
std::vector<ClaudeCopiedRow> copies;
std::vector<RecentExecutionRow> recent_executions; // last N within window
// Filtro de fecha. 0 = All. Otros valores en segundos.
int window_secs = 86400; // default 24h
// WS live state. true cuando hay conexion WS activa al hub de eventos.
bool ws_connected = false;
long long last_event_ts = 0; // ultimo ts recibido por WS
long long last_seen_call_id = 0; // watermark (max id procesado)
};
struct RegistryData {
RegistryStats stats;
std::vector<LangCount> by_lang;
std::vector<DomainCount> by_domain;
std::vector<KindCount> by_kind;
std::vector<DateCount> by_date; // last 30 days
std::vector<FunctionRow> recent_funcs; // last 20
std::vector<AppRow> apps;
std::vector<AnalysisRow> analyses;
std::vector<TypeRow> types;
std::vector<ProjectRow> projects;
ClaudeUsageData claude;
int orphan_apps = 0;
int orphan_analyses = 0;
int orphan_vaults = 0;
// For chart data (populated by prepare_chart_data)
std::vector<std::string> lang_labels;
std::vector<float> lang_values;
std::vector<std::string> domain_labels;
std::vector<float> domain_values;
std::vector<std::string> kind_labels;
std::vector<float> kind_values;
std::vector<std::string> date_labels;
std::vector<float> date_values;
void prepare_chart_data();
};
// Load all data from registry.db. Returns true on success.
bool load_registry_data(const char* db_path, RegistryData& out);