Appearance
Admin/Bank Split
Status: accepted 2026-07-03 · executed 2026-07-04 (code-complete; deploy-time cutover pending)
What was decided
Dissolve admin-server as a backend. There is no "admin" domain in this codebase — a route-by-route trace found every non-fund route belongs to a service that already owns its state. The end-state is four-way:
- Banks — chain-specific, fund-moving, sign + submit on-chain. One per chain:
evm-bank(wasadmin-server),solana-bank(wassolana-admin-server). Their entire surface is money movement (plus chain-specific reference data: deployments/deploy/reconcile). - game-server — real-time play + everything producing a verifiable record, and now the native operator endpoints: config CRUD + reload (
/admin/config),/admin/rules, observatory reads, tournament views (list/detail, reading the sametable_players.elimination_orderthe payout path uses), nativeforce-end-tournament(callsorchestrator.forceEnd()directly), and copilot-costs. - auth-server — identity + roles, now including
/adminslist +POST /admins/rolegrant/revoke (DB-re-checked per call, audited). apps/admin— a thin frontend. Operator panels ride/api/game-server/[...path]+ direct auth-server calls; money panels ride/api/bank/[...path](CHAIN-selectedBANK_URL). No admin backend, no BFF aggregator service.
Topology
Solana operator parity falls out for free: the operator panels no longer have a chain axis, so one dashboard works on either deploy.
The env model
ADMIN_SERVER_URL is retired entirely. Money → BANK_URL (CHAIN-selected EVM_BANK_URL/SOLANA_BANK_URL, boot-asserted); operator → GAME_SERVER_URL/AUTH_BASE_URL. A legacy-name grep gate in scripts/check-env-contract.sh keeps the retired family out of code, env templates, compose, CI, and test spawn envs — added after new code (a market-create dispatch) landed reading the retired name.
Key tradeoffs accepted
- Transitional duplication during the migration (routes lived in both places until callers moved), in exchange for every step being additive + rollback-by-redeploy.
- Two live fund-critical service renames — gated by the EVM fund-path suite and the Solana cage e2e before AND after each bank-touching phase.
- The moved game-server operator endpoints ride the pre-existing
x-admin-keyoperator auth (secret held server-side in the dashboard BFF), not JWT-role gating; auth-server's role endpoints DO re-check the DB role per call. - Deployment/chain-config parity for Solana (
/deployments,/api/deployment) stays bank-owned per chain — deliberate follow-up scope.