Add startup scheme
This commit is contained in:
15
bot.py
15
bot.py
@@ -383,6 +383,21 @@ async def on_ready():
|
||||
log.info("Logged in as %s (ID: %s)", bot.user, bot.user.id)
|
||||
economy.set_house(bot.user.id)
|
||||
|
||||
# PocketBase silently drops writes to fields missing from the collection
|
||||
# schema, so surface any drift loudly instead of letting features no-op.
|
||||
try:
|
||||
missing = await economy.missing_schema_fields()
|
||||
if missing:
|
||||
log.error(
|
||||
"PocketBase collection '%s' is missing %d schema field(s): %s "
|
||||
"- writes to them are silently dropped! Run scripts/sync_pb_schema.py.",
|
||||
config.PB_ECONOMY_COLLECTION, len(missing), ", ".join(missing),
|
||||
)
|
||||
else:
|
||||
log.info("PocketBase schema check passed (%s)", config.PB_ECONOMY_COLLECTION)
|
||||
except Exception as e:
|
||||
log.warning("Could not verify PocketBase schema: %s", e)
|
||||
|
||||
_apply_profile_command_filters()
|
||||
|
||||
# Pull sheet data into cache
|
||||
|
||||
@@ -573,6 +573,15 @@ async def do_spam_jail(user_id: int) -> None:
|
||||
# ---------------------------------------------------------------------------
|
||||
# Public helpers
|
||||
# ---------------------------------------------------------------------------
|
||||
async def missing_schema_fields() -> list[str]:
|
||||
"""Compare the live PocketBase collection schema against every field the
|
||||
bot persists. PocketBase silently drops writes to undeclared fields, so
|
||||
any name returned here means broken features without error messages."""
|
||||
live = await pb_client.get_collection_fields()
|
||||
expected = set(_default_user()) | {"user_id"}
|
||||
return sorted(expected - live)
|
||||
|
||||
|
||||
async def get_all_users_raw() -> dict[str, "UserData"]:
|
||||
"""Return a snapshot of all user records."""
|
||||
records = await pb_client.list_all_records()
|
||||
|
||||
@@ -147,6 +147,12 @@ async def update_record(record_id: str, data: dict[str, Any]) -> dict[str, Any]:
|
||||
)
|
||||
|
||||
|
||||
async def get_collection_fields() -> set[str]:
|
||||
"""Return the field names defined on the economy collection's schema."""
|
||||
data = await _request("GET", f"{PB_URL}/api/collections/{ECONOMY_COLLECTION}")
|
||||
return {f["name"] for f in data.get("fields", [])}
|
||||
|
||||
|
||||
async def count_records() -> int:
|
||||
"""Return the total number of records in the collection (single cheap request)."""
|
||||
data = await _request(
|
||||
|
||||
@@ -73,6 +73,11 @@ class FakePocketBase:
|
||||
async def count_records(self) -> int:
|
||||
return len(self.records)
|
||||
|
||||
async def get_collection_fields(self) -> set[str]:
|
||||
if self.schema_fields is None:
|
||||
return set(economy._default_user()) | {"user_id"}
|
||||
return set(self.schema_fields)
|
||||
|
||||
# -- test helpers -------------------------------------------------------
|
||||
def record_for(self, user_id: int) -> dict:
|
||||
for record in self.records.values():
|
||||
@@ -83,7 +88,7 @@ class FakePocketBase:
|
||||
|
||||
def _install(monkeypatch, fake: FakePocketBase) -> FakePocketBase:
|
||||
for name in ("get_record", "create_record", "update_record",
|
||||
"list_all_records", "count_records"):
|
||||
"list_all_records", "count_records", "get_collection_fields"):
|
||||
monkeypatch.setattr(pb_client, name, getattr(fake, name))
|
||||
monkeypatch.setattr(economy, "HOUSE_ID", None)
|
||||
monkeypatch.setattr(economy, "_house_pb_id", None)
|
||||
|
||||
@@ -100,6 +100,12 @@ class TestClaim:
|
||||
|
||||
|
||||
class TestSchemaDetection:
|
||||
def test_missing_fields_reported(self, fake_pb_without_quest_fields):
|
||||
assert run(economy.missing_schema_fields()) == ["quest_daily", "quest_weekly"]
|
||||
|
||||
def test_healthy_schema_reports_nothing(self, fake_pb):
|
||||
assert run(economy.missing_schema_fields()) == []
|
||||
|
||||
def test_missing_quest_fields_warn_and_zero_progress(
|
||||
self, fake_pb_without_quest_fields, caplog
|
||||
):
|
||||
|
||||
Reference in New Issue
Block a user