F

Fintexa Webhook

marketplace heartbeat + commands

Last refresh:

🎯 Fluency
Heartbeats
beats
Personas
conexiones (user·host·os)
Commands
queued
Errors
uptime

Sin conexión

Tablero técnico Fintexa Webhook v2.0.1 requiere X-Api-Key (admin o readonly) para mostrar métricas en vivo.

Sin key configurada · NO se muestran datos · prevenimos confusión con números simulados.

Header X-Api-Key · ver API docs

Configuración

📖 Referencias del dashboard

Qué mide cada KPI · cada gráfico · cada columna · ESC ó ? para cerrar

Barra de filtros (sticky arriba)

Range presets
1h / 24h / 7d / 30d / 90d / custom — aplica a todos los KPI Fase D + chart "Métricas en el tiempo" + 4 charts Sprint C. Se persisten en localStorage.
desde / hasta
Datetime custom local. Cambiar conmuta a custom y refresca de inmediato KPIs + chart + Sprint-C (v3.4 · antes esperaba el tick de 60s).
user / persona
Autocompleta con nombre de persona + su compuesto user**host**os. Acota productividad/engagement/capabilities. Refresca de inmediato.
repo
Autocompleta con repos vistos. Match exacto contra el campo Repo del HourlyAggregate.
🔄 Refrescar
Fuerza un refresh completo ahora (spinner mientras corre).
● 60s / ⏸ pausa
Activa/pausa el auto-refresh de 60s (v3.4 · el toggle ahora corta/reinicia el intervalo de verdad). "act. HH:MM:SS" = última actualización.

KPI Hero (header morado)

Heartbeats · N° total de POST /heartbeat recibidos. Cada cliente envía 1 cada 5 min. Sub-line: total_beats (suma de count dentro de cada heartbeat — múltiples beats por request).
Personas / Conexiones · Personas = humanos únicos (dedup por identidad git/jira/normalizado · personsReport.kpis.persons_total). Conexiones = compuestos distintos user**hostname**os vistos (metrics.global.unique_users). Una persona puede tener N conexiones (máquinas/variantes).
Commands · Total de comandos despachados (entregados al cliente en su próximo HB). Sub-line: queued = comandos esperando entrega.
Errors · Errores capturados durante el procesamiento. Sub-line: uptime del proceso.

LIVE — últimos 20 min

Conexiones activas (LIVE) · Conexiones (compuestos user·host·os) con actividad en la ventana rolling 20min + delta vs el primer sample. Sub-línea muestra el total de personas (dedup) para contexto. Sparkline = evolución 20 samples (refresca c/60s).
Beats total · Acumulado del proceso · sparkline = serie last 20min.
Commands dispatched · Total despachados desde el boot del proceso · sparkline.
Latency p95 (ms) · p95 ponderado del log Serilog · el sparkline ahora es serie temporal real (p95 por cada tick de 60s, no un snapshot). Punto = valor actual. verde <100ms · amber <500ms · rojo ≥500ms.

El pill ● en vivo / ⏸ pausado refleja el auto-refresh. Sparklines más grandes con punto en el valor actual.

Rendimiento (Engineering) — API últimos 60 min

Salud de la API desde los logs Serilog reales. Fuente: /metrics/engineering/detail. Traído al tablero central (antes solo en ceo/sanctum, que son experimentales).

p50 / p95 / p99 (ms) — percentiles de latencia globales (promedio ponderado por hits sobre los endpoints). p95<100/<500/≥500.
error rate — % de respuestas 4xx/5xx. rojo >1%.
throughput (rps) — requests por segundo en la ventana.
Apdex — satisfacción de latencia 0-1 (umbral 300ms): satisfechos + tolerados/2 ÷ total. ≥0.94 excelente.
Endpoints más lentos — top 5 por avg ms. Nota honesta (ADR-037): los percentiles por-bucket NO se miden → el histórico real de percentiles está en /metrics/engineering/timeline (SQL); la serie de /detail sólo trae throughput real por bucket.

KPI Fase D (4 cards bordes color, filtrados por barra global)

📊 Productividad · Suma de last_lines_added y last_lines_removed de los HourlyAggregate buckets en el rango. Net = added − removed. h = horas con beats > 0. users = users distintos en buckets.
🔧 Versions · Card dual:
· Mkt = Fintexa Marketplace version (campo legacy version del HB · ej v2026.504.11-beta)
· CLI = Claude Code CLI version (campo Fase A cli_version · ej 2.3.0)
Cada uno: latest detectado / N adopted / total users / N en versión vieja.
⚡ Engagement · active_hours = hours con actividad. sesiones = sessions únicas. beats = total beats. beats/ciclo = beats ÷ heartbeat_requests (cuántos beats vienen por cada POST).
🧠 Capabilities · thinking﹪ = beats con thinking:true ÷ total beats. fast﹪ = beats con fast_mode:true. 1m﹪ = beats que reportaron contexto 1M tokens. top = effort_level más frecuente (high/medium/low/xhigh/minimal).
🚦 Rate limits (v1.9 — snapshot estado actual, NO usa filtros range)
Reporta consumo de cuota de la suscripción Claude Code de cada user. Cuenta cuántos están críticos (≥90﹪), warning (70-89﹪) y ok (<70﹪) sobre el max(rate_5h, rate_7d). Sub-line: avg 5h/7d global.

Rate limits (Claude Code subscriptions)

Trackea consumo de la suscripción Claude Code de cada user. Dos ventanas:

5h ventana (sesión)

% consumido sobre el cap horario de 5h. Crítico si llega ≥90﹪ — al 100﹪ Claude bloquea hasta que reset el contador.

7d ventana (semanal)

% consumido sobre el cap semanal del plan. Indica tendencia más estable. Si está alto y queda mucho de la semana ⇒ probable upgrade necesario.

Tabla de tiers (caps semanales · valores empíricos calibrados)
Tier key Subscription Cap 7d Cap 5h
enterprise.max20xEnterprise (max 20x)~750 MB~120 MB
enterprise.*Enterprise~300 MB~30 MB
team.max20xTeam Opus 1M (max 20x)~750 MB~120 MB
team.max5xTeam Opus / Sonnet 1M~300 MB~30 MB
pro.max5xPro (Sonnet 200k, max 5x)~120 MB~10 MB
proPro Sonnet 200k~120 MB~10 MB
apikeyAPI key (sin cap)

Calibración 2026-04-20 (sl-usage.sh) — empírica team.max5x: 82﹪ web == 120MB jsonl/7d → 100﹪=146MB. Tiers nuevos requieren re-calibración.

⚠ Requiere cooperación del cliente

El backend solo reporta lo que el cliente le envía. El cliente HB debe enviar campos top-level adicionales (forward-compat ya soportado):

{
  "user": "...",
  "rate_5h_pct": 72,
  "rate_7d_pct": 65,
  "subscription": "team",
  "tier": "max5x",
  "tier_key": "team.max5x",
  "week_mb": 95,
  "sess_mb": 18,
  "heartbeats": [...]
}

El statusline ya computa estos valores en sl-usage.sh (vars USAGE_PCT_WEEK, USAGE_SESS_MB, _TKEY). Solo falta inyectarlos al payload del HB. Para POC se pueden mockear via cURL directo al endpoint POST /heartbeat.

Heatmap actividad — Lun→Dom × 24h

Matriz 7 días × 24 horas que muestra concentración de actividad. Cada celda agrega los valores de TODOS los días con esa combinación (ej: todos los lunes a las 14h en el rango).

Modo BEATS

Suma total de beats por celda. Muestra volumen de actividad: en qué horas el equipo trabaja más intensamente. Ideal para detectar peaks de uso, ventanas de baja actividad, patrones diarios.

Modo USERS

Cantidad de usuarios distintos activos en esa banda horaria. Muestra cobertura del equipo: cuántos miembros coinciden trabajando a determinada hora. Útil para coordinación y capacity planning.

Escala de color (8 niveles)
0﹪
100﹪ del max
El color es relativo al máximo del periodo filtrado · cyan = baja-media · amber = alta · rojo = peak. Hover en cada celda muestra día + hora + valor exacto.
Notas
  • Solo se cuentan buckets base (repo='') para evitar doble-counting cuando un user toca varios repos en la misma hora
  • Días empiezan en Lunes (estándar ISO 8601, no domingo)
  • Hora local del servidor (UTC en Docker · UTC-3 si corre nativo en AR)
  • Si una banda no tiene datos → celda gris claro sin número

Sprint C — 4 charts dedicados Fase D

Top 10 users (líneas net) · Bar horizontal — users ordenados por net = lines_added − lines_removed en el rango. Top 10 únicamente.
Top 10 repos (líneas net) · Bar horizontal — repos ordenados por net. Cada bucket repo cuenta independientemente. Útil para ver qué repos tuvieron más actividad de código.
CLI versions adoption · Donut — cuántos users usaron cada versión CLI en el rango. Tooltip: count + porcentaje. Indica fragmentación de adopción.
Effort distribution · Bar vertical color-coded — beats por nivel effort (xhigh / high / medium / normal / low / minimal). Tooltip: beats absolutos + ﹪ del total.

Métricas en el tiempo (chart dual-axis)

Serie temporal con snapshots persistidos cada 1h. Usa el rango global. Tiene 2 ejes Y porque los valores tienen escalas distintas:

Eje IZQUIERDO (cuentas grandes)
  • Heartbeats — POST /heartbeat acumulados
  • Beats — beats totales (suma)
  • Commands — comandos despachados
Áreas con gradient · format ticks: ≥1k → "1.5k"
Eje DERECHO (Users)
  • Users — users únicos vistos
Área dashed morada · escala adaptativa con padding 30﹪ del max para que la curva siempre se vea ancha (ej max=10 → eje 0-13)

💡 Botones-chip de serie (arriba del chart) muestran/ocultan cada línea y persisten en localStorage. Abajo, indicadores total · promedio · pico del rango visible por serie.

Tabla "Conexiones" — columnas

User — identidad name**hostname**os · sortable
Last seen — relativo · verde <10min · cyan <1h · amber <24h · gris >24h
CLI — última versión Claude Code reportada
Effort — nivel effort más frecuente (top mode)
Lines+ — última lectura lines_added reportada (sortable)
Lines− — última lectura lines_removed reportada (sortable)
Beats — total beats en uptime del proceso (sortable)
HB — total POST /heartbeat (sortable)
Cmds — total commands recibidos por este user (sortable)
💡 Tip: click en cualquier fila ⇒ filtra todo el dashboard por ese user automáticamente

Personas — usuarios unificados (dedup por identidad)

Una persona = un humano real. Colapsa todos sus alias (user**host**os de cada máquina/variante) en uno solo, para no contar la misma persona N veces. Fuente: /metrics/users.

Ventana de actividad — sólo cuentan personas con actividad en los últimos N días (default 60). Las dormidas (tests / usuarios de baja) se excluden de TODOS los KPIs pero se muestran como conteo aparte (honesto).
DAU / WAU / MAU — humanos únicos activos en 1d / 7d / 30d (por PERSONA, no por máquina). Stickiness = DAU÷MAU.
Método — cómo se unificó: authenticated (git/jira · account_id/email · transitivo) > normalized_user (mismo slug: case/separador/acentos) > inferred_name (mismo host + afinidad de nombre · menor confianza ⚠) > single.
autenticadas ﹪ — cobertura de identidad real (git/jira). El resto es inferido → mejora a medida que llega el campo identity en el HB.
nuevas 30d — personas cuya primera aparición fue ≤30d (adopción). NEW en la grilla.
cerca-límite — personas con rate 5h ≥80﹪ = riesgo de agotar cuota Claude. El rate es por-PERSONA (peor de sus máquinas, porque la suscripción es del humano).
Uso — alias · máquinas · beats de la persona. Expandir (▶) muestra la grilla sesión/host + superficies.
merge_candidates — pares con afinidad de nombre cross-host que NO se auto-unieron (evita falsos) → confirmar con auth/humano.

Conexiones — por máquina/sesión

Persona · Conexión — nombre nominal resuelto (quién es) + el compuesto user**host**os + chips host/os/entrypoint.
Filtros — por persona · por os · búsqueda por nombre. Toggle inactivos = incluir conexiones fuera de la ventana (default oculta tests/bajas).
Mkt / CLI — versión Fintexa Marketplace / versión Claude Code CLI reportadas.
💡 "Conexiones" = las máquinas; "Personas" ↑ = el humano unificado detrás de ellas.

Artefactos — generados por skills IA

Archivos que producen los skills del marketplace (specs, planes, reviews, etc.). Fuente: /metrics/artifacts/timeline (por día · SQL persistido) + /metrics/marketplace/breakdown (canónicos).

Archivos por día — barras de files por día (últimos 30d). Hover = archivos · KB · users. Persistido, sobrevive restart.
Tipos canónicos — familia del artefacto: SPEC · FEATURE · HANDOFF · FINDINGS · DRIFT · REVIEW · CHANGELOG · MORF · DEBATE · AGDR · …
Top tickets — tickets con más artefactos + tipos generados.
Skills más usadas — invocaciones por skill (derivado de los artefactos que produce).

AI Fluency — AFI 4D (Anthropic)

Índice de fluidez con IA por repo/equipo. Fuente: /metrics/fluency/board. El botón 🎯 Fluency (arriba) abre el tablero completo.

AFI global — AI Fluency Index 0-100 = promedio de las 4 dimensiones. ≥70 alto · ≥50 · ≥35 · <35 bajo.
4 dimensiones (0-100﹪)D1 Delegación (cuánto se delega en IA) · D2 Descripción (calidad del prompt/contexto) · D3 Discernimiento (revisión crítica del output) · D4 Diligencia (verificación/tests).
Repos — escaneados / flota total. Autores — usan marketplace / totales.
💡 Este bloque es el resumen; el detalle por repo/ecosistema/equipo vive en el tablero fluency.

Notas técnicas

  • HourlyAggregate = 1-2 rows / hora / user (1 base con repo='' + 1 per repo distinto tocado). UPSERT por PK (Hour, User, Repo).
  • Retención = 90 días default (max 365d). Configurable via Persistence:RetentionDays.
  • Granularidad = 1 hora. Buckets de hora actual viven in-memory hasta el flush (default 5 min).
  • Auto-refresh = 60s (toggleable en Config). Los charts re-renderizan sin perder estado.
  • Storage = SQL Server por default (Docker). Swapeable a SQLite o JSON via PERSISTENCE_PROVIDER.
  • Forward-compat = campos JSON nuevos del HB se guardan en dict extras (string→string). No hace falta cambiar schema.

⌨ Atajos de teclado

Ctrl+K · enviar comando ? · abrir referencias ESC · cerrar modal
Filtros

LIVE — últimos 20 min

· ventana rolling 20min (/20 samples) · HB cliente c/5min
Conexiones activas
vs 20min · personas
Beats total
+ en 20min
Commands dispatched
+ en 20min
Latency p95 (ms)
avg ms
Productividad
📊
/
Net: líneas · h · users
Versions
🔧
Mkt
/
CLI
/
Engagement
h
sesiones · beats · /ciclo
Capabilities
🧠
thinking
fast: · 1m: · top:
Rate limits
críticos
warn · ok · avg /
Live · 5 min
beats
actividad reciente · ventana rolling
DAU · 1 día
👥
stickiness (DAU÷MAU):
WAU · 7 días
📅
MAU 30d:
Artefactos 24h
📄
/ KB
top: · archivos · users

AI Fluency · AFI 4D (Anthropic) · ventana 30d

Abrir tablero completo →
Sin scans de fluency aún · corré /ffluency o abrí el tablero para detalle.
AFI global
/ 100
Repos
/
escaneados / flota
Autores
/
usan / total

Artefactos · inventario .claude del último scan

archivos (inventario) · con mtime <24h
ℹ El desglose por tipo · ticket · skill · user requiere que el scanner reporte el inventario completo (total.by_type + total.samples[]) — hoy solo reporta actividad de las últimas 24h. Ver Opción A (pendiente).
Actividad de archivos (mtime <24h por scan · ventana móvil, no acumulativo)
archivos/día tickets/día (distintos)
Sin actividad de archivos en el rango.
pico arch · tickets
Tipos canónicos (SPEC/FEATURE/HANDOFF/DRIFT/…)
Sin desglose por tipo · el scanner no reporta by_type en el heartbeat.
Top tickets (por artefactos)
Sin datos · requiere artifacts.samples[] (filename·type·ticket) en el HB del scanner.
Skills más usadas
Sin datos · requiere artifacts.samples[] en el HB del scanner.

Rate limits

· reportan · cri / w / ok
mostrando /
📡 Ningún cliente reporta rate limits.
# User Host OS Plan 5h 7d MB St

Top 10 users (líneas net)

Sin datos en el rango

Top 10 repos (líneas net)

Sin datos en el rango

· adoption

Sin datos CLI Claude Code en el rango
Sin datos Fintexa Market

Effort distribution

Sin datos en el rango

· · máx · user únicos pico · (sin datos en período)
0

Costos estimados · ROI marketplace

· appsettings.Costing
ARPU mensual
Promedio/user/mes
Costo/user
Infra + API estimado
Margen unit.
ARPU − Costo
MRR total
Datos: /metrics/business/arpu + /metrics/business/cost-per-user · TokenCost configurable en appsettings.json:Costing.TokenCost

Métricas en el tiempo

Dual-axis: izq = Heartbeats·Beats·Commands · der = Conexiones (compuestos user·host·os · no dedup a persona — la serie histórica por-persona llega con G1 time-series) · usa filtros globales arriba

samples
clic para mostrar/ocultar

Actions

Versions adoption
Models usage
Top branches
Top repos

Personas unificado por identidad · activas últimos d

ventana
activas · dormidas
ADOPCIÓN humanos únicos activos (dedup)
personas
DAU
WAU
MAU
stickiness
nuevas 30d
CALIDAD · RIESGO identidad · cuota · máquinas
autenticadas
cerca-límite
multi-máq
avg máq/pers
superficies
dormidas
Persona Uso Versión Mkt/CLI Rate D·W·M
Sin personas activas en la ventana (d) · requiere heartbeats con el campo identity (v3.3)
⚠ merge_candidates · cross-host sin señal fuerte · NO auto-unido · confirmar con auth/humano
Confianza: authenticated (git/jira · transitivo) › normalized_user (case/sep/acentos) › inferred_name (mismo host) › merge_candidate (sugerido). Rate limit = cuota Claude por-persona (peor máquina). Fuente: /metrics/users.

Conexiones · por máquina/sesión · activas d · ver Personas ↑ para el unificado

users · pág /
Persona · Conexión Last seen Mkt CLI Effort Lines+ Lines- Beats HB Cmds
...

Actions dispatched

Sin commands despachados aún
Top endpoints · count + latencia (ms)
Endpoint Hits avg p50 p95 p99 max
No hay datos de log aún — hacé requests
Status codes
Top IPs (remote)
Requests per minute (últimos 120 buckets)

🚀 Enviar comando

Se entrega al user en su próximo heartbeat · ESC para cerrar
👤

Path-targeted: POST /admin/broadcast/{user}

Whitelist: HEARTBEAT_* · DEBUG_* · FINTEXA_*

Positivo=min · -1=persistente · 0=ya expirado

POST

        
Ts Tpl From To Title Summary Status
Sin cards logueadas aún · Usar fteams-post.sh ... --api-log http://localhost:5080/teams/log

Card # ·

Ts:
Status:
From:
To:
Channel:
CorrelationId:
Title
Summary
Adaptive Card JSON

        
🔧 Diagnóstico técnico · Rendimiento API · snapshots de persistencia · endpoints registrados — avanzado ▸ expandir

Rendimiento · API últimos 60 min (logs reales)

p50
ms
p95
ms
p99
ms
error rate
%
throughput
rps
Apdex
Endpoints más lentos (avg)
Sin requests en la ventana (o logs no disponibles).

Persistence snapshots

Provider:

Endpoints registrados