# SQLite Migration ## Phase 1: Infrastructure - [x] Create `storage/database.py` — SQLite connection wrapper (WAL mode, thread-safe) - [x] Create `storage/base_sqlite_store.py` — same public API as BaseJsonStore, backed by SQLite - [x] Create `storage/migration.py` — auto-migrate JSON files to SQLite on first run - [x] Add `database_file` to `StorageConfig` in config.py - [x] Update demo mode path rewriting for database_file ## Phase 2: Convert stores (one-by-one) - [x] SyncClockStore - [x] GradientStore - [x] WeatherSourceStore - [x] AutomationStore - [x] ScenePresetStore - [x] TemplateStore - [x] PostprocessingTemplateStore - [x] PatternTemplateStore - [x] AudioTemplateStore - [x] ColorStripProcessingTemplateStore - [x] PictureSourceStore - [x] AudioSourceStore - [x] ValueSourceStore - [x] DeviceStore - [x] OutputTargetStore - [x] ColorStripStore ## Phase 3: Update backup/restore - [x] Refactor backup.py to read from SQLite (export/import/backup/restore) - [x] Keep JSON backup format identical for compatibility - [x] Update AutoBackupEngine to read from SQLite - [x] Add Database to dependency injection ## Phase 4: Cleanup - [ ] Remove individual `*_file` fields from StorageConfig (keep `database_file` only) - [ ] Remove `atomic_write_json` usage from stores (still used by auto_backup settings) - [ ] Remove `freeze_saves` from base_store (only `freeze_writes` needed) - [ ] Remove BaseJsonStore (keep EntityNotFoundError — move to shared location) - [ ] Update _save_all_stores to use _save_all() instead of _save(force=True) - [ ] Update CLAUDE.md and server/CLAUDE.md documentation - [ ] Remove `_json_key`/`_legacy_json_keys` references from old code - [ ] Clean up test files to use Database fixture instead of file paths