Informe técnico de ingeniería: ecosistema gghstats v1.5.1

gghstats v1.5.1 — Honest Reporting

1. Contexto y filosofía de diseño

Los datos de tráfico de GitHub (vistas y clones) solo se retienen en una ventana rodante de 14 días. Sin captura propia, esa telemetría se pierde. gghstats persiste histórico de tráfico en SQLite, con dashboard, API, CLI y métricas Prometheus, de modo que la organización conserva series más allá del límite de la API.

GitHub API 14 días vs gghstats SQLite

El diseño prioriza soberanía de datos y minimalismo operativo: un binario Go + SQLite, sin base de datos externa obligatoria, orientado al autoalojamiento frente a SaaS que exige delegar un PAT a terceros.

Separación de responsabilidades

Repositorio Rol
gghstats (core) Aplicación: sync GitHub → SQLite, serve, API/UI, CLI, Prometheus, alertas opt-in, imagen GHCR / binarios. Variables de app como GGHSTATS_DB, GGHSTATS_TRUSTED_PROXIES, GGHSTATS_GITHUB_TOKEN, etc.
gghstats-selfhosted (despliegue) IaC operativo: Compose (minimal / Traefik TLS / observability), Helm, layout GGHSTATS_HOST_DATA, pin de imagen, docs de VPS. No es el código del motor.

Diagrama ecosistema gghstats v1.5.1

Traefik, Helm, stacks Grafana/Prometheus/Loki y la convención GGHSTATS_HOST_DATA pertenecen a selfhosted. El core solo expone el binario/imagen y la semántica de variables de aplicación (p. ej. confiar cabeceras X-Forwarded-* vía GGHSTATS_TRUSTED_PROXIES).


2. Instalación y despliegue

Evaluación rápida (core)

Método Comando / herramienta Uso
Script curl -fsSL https://get.gghstats.com/install.sh | sh Instalación rápida Linux/macOS (pin: VERSION=v1.5.1 …)
Homebrew brew install hrodrig/gghstats/gghstats Workstations
Go go install github.com/hrodrig/gghstats/cmd/gghstats@latest Fuente / bleeding-edge

Modo demo: gghstats serve --demo (o GGHSTATS_DEMO=true) — UI con datos sintéticos, sin PAT ni sync real.

Producción: qué vive dónde

Core (aplicación):

Selfhosted (manifiestos): versión de repo ~0.1.58, pin de app GGHSTATS_VERSION=v1.5.1.

Alertas (Slack / webhook / Loki / SMTP) son del core (GGHSTATS_ALERTS_*); selfhosted solo cablea esas vars en Compose/Helm y documenta gghstats alert test.


3. Trayectoria: v1.1.0 → v1.5.1

v1.3.0 — Índice estadístico + JSONL

v1.5.0 — Cinco slices de reportería

Slice Contenido
F-fresh Estado de frescura / cobertura por métrica (views / clones). Statuses: fresh | delayed | missing | failed | never. Charts con huecos null (cero explícito ≠ día omitido). Fetch views/clones independiente. Migración v7 (traffic_metric_state, traffic_metric_coverage).
V-vis github_visibility + report_policy (exclude > include > inherit); GGHSTATS_REPORT_PRIVATE; CLI repo report ls/set. Superficies de reporte fail-closed (404 indistinguible). Colección (filter/pins/INCLUDE_PRIVATE) separada del reporting. Migración v8.
V-json gghstats repo report ls --json (+ filtros --visibility / --policy) para scripts post-upgrade.
U-legend Leyenda i18n en charts de detalle: gap/null = no reportado por GitHub; 0 = cero confirmado.
X-chart Descarga JSON alineado al chart (/{owner}/{repo}/traffic.json); dogfood …/traffic?dense=1 (sparse por defecto sin cambios).

Operadores: tras 1.5.0, filas existentes → unknown + inherit hasta el siguiente sync (o repo report set … include). El histórico SQLite no se borra; dashboard/APIs/exports/badges pueden quedar vacíos hasta entonces.

En 1.5.0, Featured se trató erróneamente como superficie de reporte: /featured, API, nav y sitemap exigían una fila repos recolectada y reportVisible. Eso rompe la vitrina editorial (entrada Featured ≠ repo con tráfico).

1.5.1 restaura el catálogo: FilterFeatured / FeaturedCount de nuevo. La visibilidad de reporte sigue aplicando solo a rutas de tráfico/dashboard. No hace falta sync para la vitrina. No es un relajamiento del fail-closed del dashboard; el fallo era el scope incorrecto de Featured.


4. Datos, seguridad y cadena de suministro

Migraciones SQLite relevantes

Versión Contenido
v6 pins, featured
v7 Frescura/cobertura de tráfico
v8 repos.github_visibility, repos.report_policy

Apertura con WAL para lecturas concurrentes (UI/API) mientras el sync escribe.

Defensa en profundidad (core)

Alertas

Opt-in (GGHSTATS_ALERTS_ENABLED): sinks Slack / webhook / Loki / SMTP; reglas tras sync; validación con gghstats alert test. Los stacks Grafana/Loki de observability Compose son despliegue selfhosted, distintos del sink Loki de la app.


5. Cierre

v1.5.1 consolida la línea 1.5: frescura honesta (cinco estados + gaps null), visibilidad de reporte fail-closed con migraciones v7/v8, y la corrección de que Featured es catálogo editorial, no report scope. El motor permanece en gghstats; Traefik, Helm, GGHSTATS_HOST_DATA y stacks de observabilidad viven en gghstats-selfhosted, con imagen pin v1.5.1.

Referencias: CHANGELOG · SPEC · README core · gghstats-selfhosted · install https://get.gghstats.com/install.sh