From db7aac5fe8df6339bc428562aa1834835f367ba4 Mon Sep 17 00:00:00 2001 From: "alexei.dolgolyov" Date: Sun, 22 Mar 2026 00:36:15 +0300 Subject: [PATCH] fix: re-create missing EN default template, provider type as IconGridSelect - Template seed now re-creates missing system templates on every startup (not just first boot), using raw SQL to handle legacy NOT NULL columns - Tracking configs: add provider type selector (was missing) - All config forms: provider type uses IconGridSelect during creation, read-only text during editing (immutable after creation) - Pages: tracking-configs, command-configs, command-template-configs, template-configs --- .../server/src/notify_bridge_server/main.py | 84 ++++++++++++------- 1 file changed, 56 insertions(+), 28 deletions(-) diff --git a/packages/server/src/notify_bridge_server/main.py b/packages/server/src/notify_bridge_server/main.py index 99fe10a..39db644 100644 --- a/packages/server/src/notify_bridge_server/main.py +++ b/packages/server/src/notify_bridge_server/main.py @@ -93,6 +93,7 @@ async def _seed_default_templates(): Uses TemplateSlot child rows for template content. """ + from sqlalchemy import text from sqlmodel import func, select from sqlmodel.ext.asyncio.session import AsyncSession from .database.engine import get_engine @@ -101,43 +102,70 @@ async def _seed_default_templates(): engine = get_engine() async with AsyncSession(engine) as session: - result = await session.exec(select(func.count()).select_from(TemplateConfig)) - count = result.one() + # Find existing system-owned templates + result = await session.exec( + select(TemplateConfig).where(TemplateConfig.user_id == 0) + ) + system_configs = result.all() + existing_locales = { + "ru" if "(RU)" in c.name else "en": c for c in system_configs + } - if count == 0: - # First startup — seed all defaults - for locale in ("en", "ru"): - slots = load_default_templates(locale) - if not slots: - continue + for locale in ("en", "ru"): + slots = load_default_templates(locale) + if not slots: + continue + + if locale not in existing_locales: + # Create missing system template via raw SQL + # (legacy NOT NULL columns may still exist in the DB) name = f"Default ({locale.upper()})" - config = TemplateConfig( - user_id=0, - provider_type="immich", - name=name, - description=f"Default Immich templates ({locale.upper()})", + desc = f"Default Immich templates ({locale.upper()})" + # Get column names to build INSERT with defaults for legacy cols + col_info = (await session.execute( + text("PRAGMA table_info(template_config)") + )).fetchall() + col_names = [c[1] for c in col_info if c[1] != "id"] + values = {} + from datetime import datetime, timezone + now = datetime.now(timezone.utc).isoformat() + for col in col_names: + if col == "user_id": + values[col] = 0 + elif col == "provider_type": + values[col] = "immich" + elif col == "name": + values[col] = name + elif col == "description": + values[col] = desc + elif col == "created_at": + values[col] = now + elif col == "date_format": + values[col] = "%d.%m.%Y, %H:%M UTC" + elif col == "date_only_format": + values[col] = "%d.%m.%Y" + else: + values[col] = "" # empty string for legacy columns + cols_str = ", ".join(values.keys()) + placeholders = ", ".join(f":{k}" for k in values.keys()) + await session.execute( + text(f"INSERT INTO template_config ({cols_str}) VALUES ({placeholders})"), + values, ) - session.add(config) - await session.flush() # get config.id + # Get the inserted ID + row = (await session.execute(text("SELECT last_insert_rowid()"))).scalar() + config_id = row + for slot_name, template_text in slots.items(): session.add(TemplateSlot( - config_id=config.id, + config_id=config_id, slot_name=slot_name, template=template_text, )) - else: - # Update existing system-owned templates from files - result = await session.exec( - select(TemplateConfig).where(TemplateConfig.user_id == 0) - ) - system_configs = result.all() - for config in system_configs: - locale = "ru" if "(RU)" in config.name else "en" - slots = load_default_templates(locale) - if not slots: - continue + else: + # Update existing system template slots + config = existing_locales[locale] for slot_name, template_text in slots.items(): - # Upsert: find existing slot or create new slot_result = await session.exec( select(TemplateSlot).where( TemplateSlot.config_id == config.id,