Skip to content

fix: reconcile config naming inconsistencies from Pydantic v2 migration #190

Description

@dimoschi

Problem

The Pydantic v1 → v2 migration in v1.13.0 changed the app's env var convention
from single-underscore prefixes (BOT_, MYSQL_, CHANNEL_, ROLE_) to
double-underscore nested delimiters (BOT__, DATABASE__, CHANNEL__,
ROLE__). A few spots were missed or are now confusingly inconsistent with
that change.

Issues

1. scripts/seed_dynamic_roles.py still uses the old single-underscore convention
It reads env vars via dotenv_values() directly and hardcodes
env_var = f"ROLE_{suffix}", independent of RolesSettings (ROLE__*) and
RoleManager._ENV_FALLBACK_MAP. Proposed fix: update the seed script to read
ROLE__{suffix}, or document why it's intentionally separate.

2. BOT_ENVIRONMENT vs bot.ENVIRONMENT/BOT__ENVIRONMENT — near-identical names, different purposes
src/core/config.py reads os.environ.get("BOT_ENVIRONMENT") directly to pick
the env file, while BotSettings.ENVIRONMENT (Sentry tagging,
src/__init__.py:71) comes from BOT__ENVIRONMENT. Both must be set for prod
to behave correctly, and the one-character difference is an easy foot-gun.
Proposed fix: rename the raw check to something distinct, e.g. APP_ENV_FILE.

3. SEASON_ID was silently broken before this release and may still be unset in prod
.test.env used CURRENT_SEASON_ID pre-v1.13.0, which never matched the
always-unprefixed Global.SEASON_ID field — silently ignored. Fixed in
.test.env in v1.13.0, but production Vault may still only define
CURRENT_SEASON_ID. Proposed fix: audit production Vault, add SEASON_ID
with the real value.

4. DatabaseSettings.ASYNC is declared but not wired, and DB connection info is duplicated across two conventions
assemble_db_connection() always hardcodes mariadb+asyncmy:// regardless of
ASYNC. Meanwhile alembic/env.py::get_url() bypasses DatabaseSettings
entirely, reading raw MYSQL_HOST/MYSQL_PORT/MYSQL_USER/MYSQL_PASSWORD/MYSQL_DATABASE
(pre-migration convention) and hardcoding mariadb+pymysql:// since Alembic
needs a sync driver.

Proposed fix: make assemble_db_connection() pick the driver based on ASYNC
(asyncmy when true/default, pymysql when false), and have
alembic/env.py::get_url() call settings.database.assemble_db_connection(async_=False)
instead of re-implementing credential reading against a stale env convention.
startup.sh's mysqladmin ping readiness check also reads raw MYSQL_*
that's shell-level and can stay as-is, but note it as related context.

Out of scope

RoleManager._ENV_FALLBACK_MAP is explicitly documented as transition-only
("will be removed in follow-up PR") — tracked separately.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions