Developer DocsData model

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_id
  • tenants — 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.custom for 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_eventsappend-only stream of everything a player does. Optional event_id for idempotency; raw payload retained (_raw when a mapping derived fields). The source of truth.
  • player_sessions — play sessions.
  • balance_transactionsappend-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, optional brand_id pin, scopes).
  • Player auth: players.auth_user_id links a portal login to a player.

Segmentation & lifecycle

  • segments (+ rules) and segment_memberships.
  • player_lifecycle_events — the lifecycle transition log.

Campaigns, messaging & journeys

  • campaigns (+ variants/sends), notification_templates (channel config JSONB), notification_queue (worker drains per channel).
  • journeys (graph) and journey_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.
  • bonuses and player_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.

TermMeaning
TenantAn operator organization. Owns one or more brands.
BrandA skin/site under a tenant; the data-isolation boundary.
PlayerAn end user, scoped to one brand. external_id is the PAM’s id.
PAMPlayer Account Management — the operator’s wallet/account backend that pushes events.
EventAn append-only record of a player action (deposit, bet, login…).
Derived statsFinancial/behavioural metrics computed from events by the worker.
GGRGross Gaming Revenue — bets minus wins.
NGRNet Gaming Revenue — GGR minus bonuses/costs.
LTVLifetime Value — a player’s cumulative value.
WageredTotal amount staked.
RFMRecency / Frequency / Monetary scoring.
Lifecycle stageWhere a player sits: new → active → at-risk → churned, plus VIP tiers.
VIP tieringPromotion to VIP via a deposit-based or engagement-based path (operator-tunable).
SegmentA group of players — rule-based (dynamic) or manual (static).
JourneyAn automated, multi-step, triggered player flow.
Canonical eventA platform-normalized event type the worker/analytics consume.
MappingThe per-brand config translating a PAM’s raw events to canonical.
RLSRow-Level Security — Postgres-enforced isolation.
HostThe VIP manager who owns a player’s book of business.
Append-onlyA stream that is never updated or deleted (events, ledger).