Skip to content

refactor: settings に _schemaVersion を導入し migration を versioned array 化 (#208)#230

Merged
ymnao merged 1 commit into
mainfrom
refactor/settings-schema-version
Jun 24, 2026
Merged

refactor: settings に _schemaVersion を導入し migration を versioned array 化 (#208)#230
ymnao merged 1 commit into
mainfrom
refactor/settings-schema-version

Conversation

@ymnao

@ymnao ymnao commented Jun 24, 2026

Copy link
Copy Markdown
Owner

概要

settings.json の schema migration を versioned array で表現するリファクタリング (#208)。
従来 loadSettings() 内に inline if-else で記述されていた legacy themethemePreference
変換を src/lib/store-migration.tsMIGRATIONS 配列に移植し、_schemaVersion
適用済み migration を追跡する形に切り替えた。次の migration 追加は MIGRATIONS に 1 entry
追加で完結し、loadSettings に分岐が増えない。

関連 Issue

Closes #208

移行 Stage

該当なし — Tauri purge 後の継続的なアーキテクチャ refactor (v0.6.0 milestone Tier 1)。

変更内容

  • src/lib/store-migration.ts 新設: MIGRATIONS 配列 + applyMigrations() + LATEST_SCHEMA_VERSION
  • src/lib/store.ts: loadSettings() 冒頭で migration 適用、inline theme 変換コードを削除
  • _schemaVersion は settings.json 上にのみ書かれ、AppSettings interface には surface しない
    (storage 内部の concern を public interface に leak しない — /simplify Altitude F1 採用)
  • src/lib/store-migration.test.ts 新設: 9 ケース (構造 / fresh / migration / skip / 不正値)
  • src/lib/store.test.ts: migration skip テスト追加、stateful mock で migration の disk 効果を verify
  • e2e/electron/settings-migration.electron.spec.ts: _schemaVersion=1 書き込み verify + skip シナリオ
  • docs/specification.md: Settings の追加・移行フロー (型 / DEFAULTS / migration / test の 4 ステップ + 判断ルール) を明記

設計判断: issue 提案からの逸脱

issue の提案は snapshot-based な migrateSettings(raw) pure function だったが、settings IPC が
key-level (settings:get/set/delete/save、snapshot API なし) であるため、現状の I/O 形と整合
しない。代わりに MigrationContext を介した key-level の副作用として記述する形を採用した
(run(ctx) 内で ctx.get/set/delete を使う)。本旨「array 1 entry 追加で新 migration が記述可能」
は満たしている。

/simplify で skip した correctness 領域の指摘 (別途検討対象)

quality 改善の /simplify では scope 外として skip したが、correctness 観点で別途検討すべき点が
2 件:

  1. loadSettings() の top-level try { ... } catch {}applyMigrations の書き込み失敗を
    { ...DEFAULTS } に縮退させる挙動 — migration が theme delete までは成功したが
    _schemaVersion set で IPC エラーになった場合、disk は中途半端な状態で残り、次回起動で
    migration が再実行される。idempotent なら問題ないが、framework の保証としては弱い。
  2. migration の write が 2 段 (run(ctx) の書き込み群 + _schemaVersion set) で非 atomic。
    crash 時の整合は idempotent run に依存。

いずれも現状 (migration 1 件のみ、すべて idempotent) では実害なし。次回 non-idempotent な
migration を追加する前に別 issue で検討する。

動作確認

  • biome check / typecheck / unit test (2212 件 pass) / electron-vite build
  • CI: e2e (electron-e2e job で settings-migration.electron.spec.ts の 3 ケースが pass)
  • 通常起動で既存 settings (themePreference / fontSize 等) が正しく読まれる
  • ~/Library/Application Support/scripta-next/settings.json_schemaVersion: 1 が刻まれる
  • theme キーが残っている disk から起動すると themePreference に変換され theme が削除される

スクリーンショット

UI 変更なし。

#208)

- `src/lib/store-migration.ts` を新設し、`MIGRATIONS` 配列・`LATEST_SCHEMA_VERSION`・
  `applyMigrations()` で settings.json の schema 変換を versioned array で表現する
- 既存の inline if-else 形式 (theme → themePreference 変換) を MIGRATIONS[0] に移植し、
  store.ts の `loadSettings()` 冒頭で `applyMigrations()` を 1 回呼ぶ形にリファクタ
- 今後の migration 追加は MIGRATIONS に 1 entry 追加で完結し、loadSettings に分岐が増えない
- `_schemaVersion` は settings.json 上にのみ書かれ、`AppSettings` interface には surface しない
  (storage 内部の concern を public interface に leak しない)
- unit test (`src/lib/store-migration.test.ts` 9 ケース) と e2e
  (`e2e/electron/settings-migration.electron.spec.ts` に _schemaVersion 書き込み verify と
  skip シナリオを追加) を追加
- `docs/specification.md` に Settings の追加・移行フロー (型 / DEFAULTS / migration / test の
  4 ステップ + 判断ルール) を明記

Closes #208

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@ymnao ymnao merged commit 68881b1 into main Jun 24, 2026
10 checks passed
@ymnao ymnao deleted the refactor/settings-schema-version branch June 24, 2026 16:37
@ymnao ymnao mentioned this pull request Jun 26, 2026
4 tasks
ymnao added a commit that referenced this pull request Jun 26, 2026
- `CHANGELOG.md` に v0.6.0 セクションを追加
  - Internal: #206#229 (AppLayout useShallow), #208#230 (settings
    _schemaVersion + MIGRATIONS), #207#231 (2 モード e2e 振り分け +
    ADR-0009 集約), #225#232 (onNavigate wikilink target),
    #226#233 (useCollapseToggle hook), #228#234 (createScanAction
    factory), #227#235 (producer-side lineContent trim)
- `package.json` の `version` を `0.5.0` → `0.6.0`
- HANDOFF の規約通り、本 commit では `pnpm <script>` を呼ばない
  (lockfile / node_modules には触れない)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

refactor: settings に _schemaVersion を導入し migration を versioned array 化

1 participant