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

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions