Background jobs
Event-driven and scheduled work runs in a dedicated worker container
(apps/worker) on BullMQ over self-hosted Redis — no external queue
service (chosen for $0 cost + data residency).
What the worker does
| Area | Processor(s) | Responsibilities |
|---|---|---|
| Derivation | derive, session-derive, scoring | Turn player_events into player-profile stats (deposits, GGR/NGR, wagered, counts, last-activity) and player scores (churn/value/engagement). |
| Lifecycle | lifecycle | Recompute each player’s stage (+ VIP tiering) and log transitions. |
| Segments | segments, segments-realtime | Recompute dynamic-segment membership; a fast real-time reconciler for opted-in segments. |
| Notifications | email, telegram, push, inapp, channel-fallback | Drain the notification queue per channel and deliver (email/SMTP, Telegram/Bot API, web-push/VAPID, in-app inbox over Realtime), with channel fallback. |
| Campaigns | campaigns, ab-winner | Dispatch scheduled/recurring campaigns; auto-select the winning A/B variant. |
| Journeys | journeys, journey-enroll, journey-enroll-scheduled | Enrol players and advance journey runs through the graph. |
| Webhooks | webhooks | Drain the webhook queue: sign, POST, log the attempt, retry with backoff. |
| Reports/exports | reports, segment-exports | Scheduled KPI digests (with PDF charts) and scheduled segment CSV exports. |
| Alerts | alerts, alert-rules | Evaluate operator alert rules and custom metric rules, and notify. |
| Intelligence | fraud, train-models | Fraud scoring and ML model training (feeding forecasts / next-best-action / scores). |
| Tasks | task-reminders | Send reminders for due CRM tasks. |
Delivery semantics
- Idempotent / claim-based. Jobs claim rows atomically (e.g. a queued → sending CAS) so two workers don’t double-process.
- Backoff on failure. Outbound webhooks retry ~1m → 5m → 15m → 1h up to 5 attempts; other queues use BullMQ’s retry/backoff.
- Service role. The worker uses the Supabase service-role client and is not constrained by RLS — it operates platform-wide by design.
Append-only inputs
The worker reads append-only streams (player_events,
balance_transactions) and writes derived state elsewhere. It never mutates the
streams, so derivation can always be recomputed from scratch.
Configuration
Queues connect to Redis via REDIS_URL. Channel delivery needs its provider
credentials (SMTP, TELEGRAM_BOT_TOKEN, VAPID keys). Webhook tuning is via
WEBHOOK_BATCH, WEBHOOK_MAX_ATTEMPTS, WEBHOOK_TIMEOUT_MS.