Master: SoW: Desk management. Not scheduled. No step of the master SoW needs this work.
Objective. AX records that a trading account is a subaccount of one master account. The record groups a customer's accounts for display, for account creation, and for transfer mandates. It grants no permission and shares no margin.
Uses: customers and
trading_accounts.customer_id from Customer account access. Account
creation and transfers from Accounts and
transfers.
trading_accounts has no parent pointer and no grouping
table (db/postgres/1.sql).trading_accounts.customer_id names the customer that
owns the account. Order-gateway checks is_onboarded and
is_frozen on that customer, not on the acting user
(rs/order-gateway/src/state.rs). Accounts with the same
customer_id have the same approval and freeze state.customer_id alone does not say which
accounts form one group.trading_accounts row with
master_account_id set. It has its own venue identity,
balances, margin, limits, and permissions.customer_id equals the master's.account_permissions and the customer manager right. Account
creation uses the W6 creation mandate. Transfers use the W10 and W11
pair mandates. No permission bit is added.ALTER TABLE trading_accounts
ADD COLUMN is_master BOOLEAN NOT NULL DEFAULT FALSE,
ADD COLUMN master_account_id CHAR(16) REFERENCES trading_accounts(id),
ADD CONSTRAINT master_has_no_parent
CHECK (NOT (is_master AND master_account_id IS NOT NULL));
CREATE INDEX trading_accounts_master_account_id_idx
ON trading_accounts (master_account_id);Invariants that a CHECK cannot reach. The write paths enforce them and a recon check reports violations:
master_account_id references a row with
is_master = TRUE.customer_id.is_master changes to FALSE only when the
account has no subaccounts.trading_accounts is on every logical replication
publication. The new columns reach the api-gateway, order-gateway, and
trade-engine replicas with no publication change.
| Step | Use of the family |
|---|---|
| 11, customer requests an account | A creation mandate can name a master account as its scope. The new
account gets master_account_id, the master's
customer_id, and the master's maker and taker fees. |
| 12, internal transfers | AX can approve the pairs master to subaccount and subaccount to master for a named user in one action. A pair of two subaccounts needs its own mandate. |
| 8, self-trade prevention | AX can put a family in one group. The parent pointer does not do so by itself. |
PUT /admin/accounts/{id}/master { is_master }
PUT /admin/accounts/{id}/parent { master_account_id | null }
GET /accounts/{master_id}/subaccounts -> [TradingAccountResponse]
GET /accounts/{master_id}/subaccounts returns the
subaccounts on which the caller holds List. The admin CLI
accounts command gains set-master and
set-parent.
The Bitnomial edition cannot create venue identity on request. An
admin pairs each account with its btnl_* identity. The
family columns and the admin routes work there. Customer account
creation does not.
blockchain_deposit_addresses row.| Stage | Scope | Reviewers |
|---|---|---|
| A | Schema, replica types, and recon checks. No route reads the columns. | high-risk |
| B | Admin routes, admin CLI commands, and the subaccount list route. | backend |
| C | Creation-mandate scope and pair-mandate approval by family. Needs steps 11 and 12 of the master SoW. | backend |
| D | Customer selector grouping and the admin family tree. | frontend |
accounts_monitor consumers read rows
that carry the family columns?