본문으로 건너뛰기

ADR-005: Wallet Topology Bucket Ledger Model

Status

Accepted

Date

2026-04-23

Owners

  • Platform Backend
  • Wallet Domain

Affected Services

  • wallet_service
  • rolling_service
  • promotion_service
  • game_service
  • gateway
  • admin_service
  • docs/specs/wallet/2026-04-23-ruby-wallet-split-structure.md
  • docs/plans/wallet/2026-04-23-ruby-wallet-split-implementation.md
  • docs/runbooks/wallet/ruby-wallet-topology-rollout.md
  • docs/services/wallet-service.md
  • docs/architecture/data-ownership.md

Context

The wallet domain must support Ruby Wallet split rules before launch:

  • configurable wallet structure
  • configurable sports, live, and slots betting policies
  • separate normal and bonus buckets by wallet group
  • shared withdrawable and points buckets
  • scoped coupon grants
  • deterministic settlement, rollback, transfer, and rolling attribution

The current flat wallet-column model is too rigid for this. Adding more player columns for every new wallet shape would make future wallet policy changes expensive and error-prone, and it would keep money state coupled to player profile storage.

The system needs a durable model where wallet shape is configurable data, wallet balances are wallet-owned, and every money movement is auditable.

Decision

wallet_service will own a topology-driven wallet model:

  • wallet_topology defines versioned wallet shape.
  • wallet_bucket_type defines bucket types for a topology.
  • wallet_bucket stores current player balances by bucket type.
  • wallet_coupon_grant stores coupon money and coupon-specific constraints.
  • wallet_policy stores versioned declarative policy documents.
  • wallet_bet_authorization stores the immutable funding decision for each accepted bet.
  • wallet_ledger stores append-only money movement records.

Wallet bucket type codes are topology data, not hard-coded money-column names. Contracts may contain stable role and provider enums, but the active wallet shape must come from topology and policy documents.

Every wallet command must resolve authoritative topology and policy server-side. Callers may pass facts such as player, bet, amount, provider type, provider ID, and selected wallet source when required, but callers must not decide funding mode, deduction order, settlement destination, or rolling attribution.

Every accepted money movement must store:

  • topology code and version
  • policy version
  • policy snapshot where deterministic replay is required
  • ledger rows for the actual balance movement

Consequences

Positive:

  • wallet shape can evolve without adding player balance columns
  • sports/casino split can launch as RUBY_SPLIT_V1
  • future live/slots/provider-specific wallet splits are possible through topology and policy changes
  • settlement and rollback are deterministic from stored authorization data
  • auditability improves through append-only ledger records
  • wallet_service remains the only money writer

Negative:

  • implementation is larger than extending the current flat fields
  • policy validation becomes a required production capability
  • topology activation requires strict safety checks
  • tests must cover topology, policy, and ledger behavior before rollout

Constraints

  • No new canonical wallet implementation may write flat player wallet columns.
  • Ledger rows are immutable after commit.
  • Policy documents must be declarative data and must pass versioned schema validation before activation.
  • Topology activation must fail when unresolved balances, coupon grants, rollings, unsettled bets, or transfers would become unreachable.
  • Settlement and rollback must use stored authorization breakdowns, not current balances or current policy.
  • Coupon money must remain grant-scoped, not collapsed into one generic coupon bucket.
  • Points cannot be bet or withdrawn directly unless a future accepted spec explicitly changes that rule.

Follow-Up

  • Implement the wallet split structure according to the related spec and plan.
  • Add topology validation tests before money command implementation.
  • Update stable service and architecture docs after the implementation is merged.
  • Promote the wallet rollout runbook to Ready before enabling the new wallet model in any shared environment.