Traducción. Autoritativo: fs-core-0010-usage-snapshots.md.
Contexto
DEC-G3 comprometió un pricing estilo Vercel: precios unitarios publicados, cuotas incluidas, consumo medido, panel de gasto proyectado y spend caps configurables por el tenant. Todo eso descansa en una medición lo bastante frecuente para ser accionable y lo bastante barata para correr por siempre para cada tenant. DEC-G1 lo fijó en cada 30 minutos con deltas. Calcular el consumo bajo demanda pondría una consulta agregada en el camino de un dashboard; snapshots diarios dejarían a un tenant pasarse de una cuota durante 23 horas antes de que alguien lo notara. La medición tiene peso contractual: los ToS nombran estos snapshots como la base probatoria de la facturación. Por eso son append-only y por eso una corrección es una fila nueva, nunca una edición.Alcance (normativo)
core.usage_snapshots, append-only, particionada mensualmente, cada 30 minutos por tenant.core.billable_metrics: paramétrica — contactos accionables, eventos registrados, mensajes por canal, almacenamiento.- Cálculo de delta entre t1 y t2, para que el consumo nunca requiera un scan.
- El conteo de contactos accionables, usando el predicado definido en FS-CORE-0004.
- Alertas de umbral a 80 / 90 / 100% por el propio sistema de notificaciones de la plataforma.
- Ganchos de enforcement: gracia, corte duro u overage por métrica, configurable por tenant desde Ops.
Fuera de alcance (normativo)
- El rating engine — consume estos snapshots; es su propio epic (ADR-016).
- Facturación y cobro — Fintoc, Paddle, LibreDTE.
- La UI del panel de consumo —
frontend/console.
Comportamiento (normativo)
- Los snapshots corren cada 30 minutos para cada tenant, por fan-out de cron. Sin tiers — el costo es bajo y un tenant que descubre un exceso un día tarde es un problema de soporte nuestro.
- Cada fila guarda el valor absoluto y el delta desde el snapshot anterior. Los deltas hacen que facturar sea una suma en vez de un scan.
- La tabla es append-only. Una corrección es una fila nueva con referencia
correction_of; editar un snapshot destruiría el valor probatorio del que dependen los ToS. - Los contactos accionables usan el predicado de FS-CORE-0004 — una sola definición, compartida, para que medición y mensajería nunca discrepen sobre quién es facturable.
- Las alertas a 80, 90 y 100% se envían por la cascada de notificaciones de la plataforma. Construir un segundo camino de entrega para nuestras propias alertas las pondría fuera de las reglas que todo lo demás obedece.
- El enforcement por métrica es configurable por tenant desde Softcrum Ops (DEC-G2). Defaults: contactos gracia + aviso, mensajes duro al 110%, eventos soft con overage.
- Un spend cap es la cara self-service del enforcement: alcanzarlo aplica el mismo corte que aplicaría el operador.
- Una ventana de snapshot perdida se registra como faltante, nunca se interpola. Un número interpolado dentro de una base de facturación es un número que no podemos defender.
- Particionada mensualmente; la retención sigue el plan, con el mínimo legal aplicando aparte.
Datos (normativo)
API (normativo)
Eventos (normativo)
core.usage.threshold_crossed en el outbox al 80, 90 y 100%, que es lo que dispara la campaña de
alerta por messaging.
Criterios de aceptación (normativo)
- Los snapshots caen cada 30 minutos para cada tenant, verificado sobre una corrida sintética de 24 horas.
- La suma de deltas de un ciclo equivale a la diferencia de absolutos en sus extremos.
- El conteo de contactos accionables coincide con la vista propia del módulo de mensajería para el mismo tenant e instante.
- Cruzar el 80% emite una vez y no vuelve a emitir mientras siga por encima.
- Una ventana perdida se registra como faltante y es visiblemente ausente, no interpolada.
- Un spend cap aplica el enforcement configurado dentro de una ventana de snapshot.
- Las correcciones se agregan con
correction_ofy dejan legible la original. - Negativo: ningún camino de código actualiza o borra una fila de snapshot.
Ejecución
Pipeline asíncrono. Fan-out de cron enbackend/scheduler, cálculo en backend/workers, endpoints
de lectura en backend/api.