fix(economy): handle db_error in commands, dedupe cooldowns, single leaderboard scan
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
This commit is contained in:
@@ -3,15 +3,16 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import random
|
||||
from datetime import date, timedelta
|
||||
from datetime import date
|
||||
|
||||
import strings
|
||||
|
||||
from ..pb_client import DatabaseError
|
||||
from . import house
|
||||
from .store import (
|
||||
COOLDOWNS, JAIL_DURATION, PRESTIGE_SHOP, _commit, _cooldown_remaining,
|
||||
_is_jailed, _locked_by, _log, _now, _prestige_mult, _txn, get_user,
|
||||
JAIL_DURATION, PRESTIGE_SHOP, _commit, _cooldown_remaining,
|
||||
_is_jailed, _locked_by, _log, _now, _prestige_mult, _txn, effective_cooldown,
|
||||
get_user,
|
||||
)
|
||||
from .house import _credit_house
|
||||
from .consumables import earn_mult
|
||||
@@ -29,7 +30,7 @@ async def do_daily(user_id: int) -> dict:
|
||||
if user.get("eco_banned"):
|
||||
return {"ok": False, "reason": "banned"}
|
||||
|
||||
daily_cd = timedelta(hours=18) if "korvaklapid" in user["items"] else COOLDOWNS["daily"]
|
||||
daily_cd = effective_cooldown("daily", user["items"])
|
||||
if cd := _cooldown_remaining(user, "daily", override_cd=daily_cd):
|
||||
return {"ok": False, "reason": "cooldown", "remaining": cd}
|
||||
|
||||
@@ -109,7 +110,7 @@ async def do_work(user_id: int) -> dict:
|
||||
if user.get("eco_banned"):
|
||||
return {"ok": False, "reason": "banned"}
|
||||
|
||||
work_cd = timedelta(minutes=40) if "monitor" in user["items"] else COOLDOWNS["work"]
|
||||
work_cd = effective_cooldown("work", user["items"])
|
||||
if cd := _cooldown_remaining(user, "work", override_cd=work_cd):
|
||||
return {"ok": False, "reason": "cooldown", "remaining": cd}
|
||||
if jail := _is_jailed(user):
|
||||
@@ -163,7 +164,7 @@ async def do_beg(user_id: int) -> dict:
|
||||
if user.get("eco_banned"):
|
||||
return {"ok": False, "reason": "banned"}
|
||||
|
||||
beg_cd = timedelta(minutes=3) if "hiirematt" in user["items"] else COOLDOWNS["beg"]
|
||||
beg_cd = effective_cooldown("beg", user["items"])
|
||||
if cd := _cooldown_remaining(user, "beg", override_cd=beg_cd):
|
||||
return {"ok": False, "reason": "cooldown", "remaining": cd}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user