A strategic counterpart to /rob: coins moved to the bank are safe from /rob and
/heist (which only touch liquid balance) but earn no Bot Farm interest and can't
be spent, gambled or given until withdrawn - the deliberate trade-off against
keeping coins liquid.
- New bank.py (do_deposit/do_withdraw), bank_balance schema field.
- /bank (view), /deposit, /withdraw commands ('all' supported), with db_error
handling; /balance shows the vault when non-zero.
- Coins leaderboard and /status money-supply now count net worth
(balance + bank_balance), so banking never hides you from the board or the
supply metric.
- Season reset wipes bank_balance too (no cross-season wealth hiding).
10 tests: deposit/withdraw math, guards, coin conservation, rob cannot touch the
vault, and net-worth accounting on the leaderboard + stats.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013VbAVsrZuYesea99mPMmPT
Adds economy.get_economy_stats() (single-scan total coins, house balance,
player-held coins, player count) and a "Rahavaru" field to /status, so admins
can see whether the sinks are keeping pace with minted income. Also removed a
duplicate bot_admin_check import.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013VbAVsrZuYesea99mPMmPT
Three robustness/perf fixes from the review:
1. db_error UX: economy core returns {"ok": False, "reason": "db_error"} on a
PocketBase outage, but no handler expected it - deferred commands hung on
"thinking..." and others showed a misleading "you're broke". Added a shared
reply_db_error helper (commands/_replies.py) + S.ERR["db_error"], and wired a
db_error branch into every handler that can receive it (daily/work/beg/crime/
rob/give/buy/roulette/slots/blackjack/heist/fish/prestige/vanity/consumables/
request-funding). Also fixed a latent KeyError in vs-bot RPS that read
res["balance"] without checking res["ok"].
2. Deduped the item->cooldown mapping that was copied in do_daily/do_work/do_beg,
do_fish_start, _maybe_remind and _restore_reminders. Single source of truth:
store.ITEM_COOLDOWNS + effective_cooldown(cmd, items).
3. /leaderboard did six full-collection scans (one per tab). Added
get_all_leaderboards() which scans once and builds all six views in memory.
Tests: effective_cooldown cases, and get_all_leaderboards matches the individual
queries + scans the collection exactly once.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013VbAVsrZuYesea99mPMmPT