Phase 2: 永続化層(SwiftData) - #2
Merged
Merged
Conversation
CachedRepository/CachedRelease/InstalledApp model the GitHub cache and installed-app records from the Phase 2 plan. CairnEnvironment wraps ModelContainer creation (on-disk by default, in-memory for tests) so the schema has a single source of truth. CachedRelease gains an explicit inverse (repository) not present in the original plan sketch, required for CachedRepository's cascade delete rule to actually take effect. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Covers insert/fetch round-trips, CachedRepository -> CachedRelease cascade delete, the inverse relationship reflecting on the repository side, and unique-constraint duplicate inserts (githubId/bundleIdentifier). SwiftData's .unique constraint does not throw on duplicate insert; it upserts the existing record instead. Confirmed by running the tests rather than assuming, since this diverges from a naive expectation. Suites are @suite(.serialized) because parallel test execution against separately-constructed in-memory ModelContainers crashed the test process (signal 5) during verification. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
The app now boots with SwiftData persistence active via .modelContainer(_:) on the WindowGroup scene. Verified with 'just run': the process launches without fatalError-ing, and a persistent store file is created on disk. ContentView stays as the Phase 0 placeholder; Discovery UI comes in Phase 5. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
CachedRepository/CachedRelease/InstalledAppの SwiftData@Modelを追加(Sources/Cairn/Cache/)ModelContainerを保持する軽量な環境容器CairnEnvironmentを追加(on-disk / in-memory 切り替え、初期化失敗時はfatalError)CairnApp.swiftに.modelContainer(_:)を配線し、実機起動時に永続化ストアが生成されることを確認AppEnvironmentへの統合は今回のスコープ外(引き続き次のUI機能フェーズへ)実装時に判明した挙動
.unique制約は違反時に例外を投げず、既存レコードを上書き(upsert)する。テストの期待値はこの実挙動に合わせているModelContainerはヘルパー関数がModelContextだけを返すとCairnEnvironmentインスタンスがスコープ外で解放されテストプロセスがクラッシュするため、CairnEnvironment自体をローカル変数として保持する必要があるTest plan
just build— ビルド成功just test— 全51テストパス(Cache配下の新規10テスト含む)just run— 実機起動、fatalErrorなし、~/Library/Application Support/default.storeの生成を確認just lint— 新規追加ファイルにlint違反なし🤖 Generated with Claude Code
https://claude.ai/code/session_014bzWqvKZywe5exBTy9Y6eQ