CRM Events
crm_events is the read-only API for the campaign operations page.
Version 1 exposes:
- overview counters
- campaign list and campaign detail
- live notification end-action rows
- local Docker Compose and Helm deployment
- docs and OpenAPI
Aggregation logic composes CRM content_pools and lifecycle_pools, Lumio,
Spark Bonus, trigger-backed reactive flows from Notify Triggers, and real send
ledgers into the response shapes defined in OpenAPI.
Cache model
crm_events uses Mongo as the source of truth and an optional shared Redis
read-through cache for read endpoints. When Redis is enabled, replicas share
cached payloads and per-tenant slice state for:
- overview
- campaigns
- campaign detail
- live events
The API still recomputes meta.sync.is_stale on every response, so Redis does
not freeze freshness metadata inside cached payloads. Redis read or write
failures fall back to Mongo reads. Setting redis.enabled=false means no
caching at all.
Overview and campaign payloads default to a 1 hour TTL. Live-event payloads default to a 60 second TTL. Search-backed campaign list requests bypass Redis payload caching to avoid unbounded key growth.
What the page needs
The read models are:
campaigns_totalplayers_targeted_totalplayers_activated_totalsent_notifications_totalsupport_cases_total
Endpoint docs
Each API now has a dedicated data-lineage note:
- GET /health
- GET /api/v1/overview
- GET /api/v1/campaigns
- GET /api/v1/campaigns/:campaign_id
- GET /api/v1/live-events
Campaign cards and detail need:
- identity and title
- lifecycle status
campaign_originui_statusbenefits— currently hardcoded toConversion,Monetization, andRetention- scope and channels
- campaign window
- benefit scores for conversion, monetization, and retention
players_engagedon campaign detail only
Live event rows need:
tenant_idtimestamptitlecategory—Conversion,Monetization, orRetentionscopechannelsstatus
Response contract
Handlers return typed JSON from OpenAPI. Paginated endpoints include page
totals; overview and campaign list responses embed summary counters plus
status_counts. Campaign summaries and detail include additive
campaign_origin and ui_status fields. Live events represent notification
end-actions only, come from real send ledgers rather than trigger flow runs,
and exclude spark_bonus dispatches. support_cases_total counts Lumio chat
conversations only. Every response includes X-Request-Id for log
correlation. Empty collections and zero counters mean no matching upstream
data for the requested filters.
Read-model sync metrics
/metrics exports per-tenant, per-slice gauges derived directly from the local
sync_state collection:
crm_events_sync_last_success_age_secondscrm_events_sync_fresh_until_age_secondscrm_events_sync_lag_secondscrm_events_sync_failure_count
All four metrics use tenant_id and slice labels. failure_count is the
consecutive number of failed sync attempts since the last successful sync for
that tenant and slice. fresh_until age is negative while the slice is still
inside its freshness window, then turns positive once the slice is stale.