From 293614d667cf8a097e9ebcd4bd10f2551f3d7bcb Mon Sep 17 00:00:00 2001 From: "alexei.dolgolyov" Date: Tue, 21 Apr 2026 20:35:21 +0300 Subject: [PATCH] fix(db): declare locale on CommandConfig model + defensive migration Startup was crashing on fresh databases because: - init_db() calls SQLModel.metadata.create_all(), which builds tables from the model classes. CommandConfig didn't declare `locale`, so the created command_config table lacked the column. - The seeder then issued INSERTs that included locale='en', causing `OperationalError: table command_config has no column named locale`. The legacy migration #6 in migrate_schema creates command_config WITH locale via raw SQL, so upgraded databases worked. Only fresh installs broke. Fix: - Add `locale: str = Field(default='en')` to CommandConfig model so create_all() produces a consistent schema. - Add a defensive ALTER TABLE ... ADD COLUMN locale in migrate_schema's else-branch, so any existing command_config table missing the column (from a broken v0.1.0 install) is backfilled on next startup. --- .../server/src/notify_bridge_server/database/migrations.py | 7 +++++++ .../server/src/notify_bridge_server/database/models.py | 1 + 2 files changed, 8 insertions(+) diff --git a/packages/server/src/notify_bridge_server/database/migrations.py b/packages/server/src/notify_bridge_server/database/migrations.py index 9cf27c4..d5815ba 100644 --- a/packages/server/src/notify_bridge_server/database/migrations.py +++ b/packages/server/src/notify_bridge_server/database/migrations.py @@ -614,6 +614,13 @@ async def migrate_entity_refactor(engine: AsyncEngine) -> None: ")" )) logger.info("Created command_config table") + else: + # Backfill locale column for tables created before locale was on the model + if not await _has_column(conn, "command_config", "locale"): + await conn.execute( + text("ALTER TABLE command_config ADD COLUMN locale TEXT DEFAULT 'en'") + ) + logger.info("Added locale column to command_config table") # ------------------------------------------------------------------ # 7. Create command_tracker table diff --git a/packages/server/src/notify_bridge_server/database/models.py b/packages/server/src/notify_bridge_server/database/models.py index 887dca6..8f3f41a 100644 --- a/packages/server/src/notify_bridge_server/database/models.py +++ b/packages/server/src/notify_bridge_server/database/models.py @@ -383,6 +383,7 @@ class CommandConfig(SQLModel, table=True): name: str icon: str = Field(default="") enabled_commands: list[str] = Field(default_factory=list, sa_column=Column(JSON)) + locale: str = Field(default="en") response_mode: str = Field(default="media") # "media" or "text" default_count: int = Field(default=5) rate_limits: dict[str, Any] = Field(default_factory=dict, sa_column=Column(JSON))