"""Apply slot-core SQL migrations in sorted order (REQ-006). Idempotent: every migration uses CREATE TABLE IF NOT EXISTS / CREATE INDEX IF NOT EXISTS, so re-running against an existing database is a no-op. """ from __future__ import annotations from pathlib import Path from typing import Any _SQL_DIR = Path(__file__).resolve().parent / "sql" def migration_files() -> list[Path]: return sorted(_SQL_DIR.glob("*.sql")) def apply_migrations(dsn: str, *, psycopg_module: Any = None) -> list[str]: """Apply all migrations to `dsn`. Returns the list of applied filenames.""" if psycopg_module is None: import psycopg # type: ignore[import-not-found] psycopg_module = psycopg applied: list[str] = [] with psycopg_module.connect(dsn, autocommit=False) as conn: for path in migration_files(): with conn.cursor() as cur: cur.execute(path.read_text()) applied.append(path.name) conn.commit() return applied