Data model
A map of the main database entities and how they relate. Full DDL lives in
supabase/migrations/; conventions and RLS are in
Database & RLS.
Scoping backbone
tenants ──1:N── brands ──1:N── players ──1:1── player_profiles
│ │ (derived financial + lifecycle snapshot)
│ └── nearly every table carries brand_id (isolation boundary)
└── nearly every table carries tenant_idtenants— operator organizations.brands— skins under a tenant; the primary isolation boundary.players— identity (external_id= the operator/PAM’s id, unique per brand), email/phone, status,metadata(incl.metadata.customfor custom fields).player_profiles— one per player: derived stats (deposits, GGR/NGR, wagered, counts, last-activity),lifecycle_stage(+ changed/checked timestamps), ownership (host_user_id), scores.
Events & derivation
player_events— append-only stream of everything a player does. Optionalevent_idfor idempotency; raw payload retained (_rawwhen a mapping derived fields). The source of truth.player_sessions— play sessions.balance_transactions— append-only ledger of point/currency movements.
Derived state (player_profiles, lifecycle, scores) is computed from these by
the worker and can always be recomputed.
Identity, auth & RBAC
user_profiles— operator users (role, tenant).roles,permissions,role_permissions,user_brand_roles,user_permission_overrides— the RBAC model (RBAC & permissions).api_keys— operator API keys (SHA-256 hash, optionalbrand_idpin,scopes).- Player auth:
players.auth_user_idlinks a portal login to a player.
Segmentation & lifecycle
segments(+rules) andsegment_memberships.player_lifecycle_events— the lifecycle transition log.
Campaigns, messaging & journeys
campaigns(+ variants/sends),notification_templates(channelconfigJSONB),notification_queue(worker drains per channel).journeys(graph) andjourney_runs(per-player execution).- Delivery targets:
player_inbox(in-app, Realtime),push_subscriptions(web-push).
Gamification & bonuses
point_currencies,balances,levels,missions,badges,tournaments,leaderboards.bonusesandplayer_bonuses(wagering, eligibility).
Integration
integration_mappings— one active, versioned per-brand mapping config (Mapping engine).webhooks,webhook_queue,webhook_deliveries— outbound signed callbacks.
Ops & config
crm_tasks(+ comments, reminders),custom_field_definitions,audit_log, alert rules, report subscriptions, suppression, and the analytics aggregate functions (analytics_*,cohort_*,revenue_*, …).
Glossary
Domain terms used throughout the platform and these docs.
| Term | Meaning |
|---|---|
| Tenant | An operator organization. Owns one or more brands. |
| Brand | A skin/site under a tenant; the data-isolation boundary. |
| Player | An end user, scoped to one brand. external_id is the PAM’s id. |
| PAM | Player Account Management — the operator’s wallet/account backend that pushes events. |
| Event | An append-only record of a player action (deposit, bet, login…). |
| Derived stats | Financial/behavioural metrics computed from events by the worker. |
| GGR | Gross Gaming Revenue — bets minus wins. |
| NGR | Net Gaming Revenue — GGR minus bonuses/costs. |
| LTV | Lifetime Value — a player’s cumulative value. |
| Wagered | Total amount staked. |
| RFM | Recency / Frequency / Monetary scoring. |
| Lifecycle stage | Where a player sits: new → active → at-risk → churned, plus VIP tiers. |
| VIP tiering | Promotion to VIP via a deposit-based or engagement-based path (operator-tunable). |
| Segment | A group of players — rule-based (dynamic) or manual (static). |
| Journey | An automated, multi-step, triggered player flow. |
| Canonical event | A platform-normalized event type the worker/analytics consume. |
| Mapping | The per-brand config translating a PAM’s raw events to canonical. |
| RLS | Row-Level Security — Postgres-enforced isolation. |
| Host | The VIP manager who owns a player’s book of business. |
| Append-only | A stream that is never updated or deleted (events, ledger). |