Fix widget wiping the Books tables on every refresh

The widget extension opened the shared local SwiftData store with a
7-entity schema while the app's store has 10. SwiftData treats the
smaller schema as a migration and destructively drops the unlisted
tables — so every widget refresh deleted the bundled Book/BookChapter
rows (and DownloadedVideo), which is why books vanished after reinstalls.

Introduce SharedStore.localSchemaModels as the single source of truth
for the local schema and build the app and both widget containers from
it, so app and widget can no longer drift apart. The same class of bug
hit TextbookChapter previously; a shared list prevents a third recurrence.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Trey T
2026-05-17 22:12:51 -05:00
parent dd08a09860
commit 26ce662c60
4 changed files with 37 additions and 39 deletions
@@ -23,4 +23,22 @@ public enum SharedStore {
/// and hit the exact container used for seeding.
@MainActor
public static var localContainer: ModelContainer?
/// The canonical model list for the local reference-data store.
///
/// The main app AND the widget extension MUST build their `ModelContainer`
/// from this exact set. Opening the store with a *subset* schema makes
/// SwiftData destructively migrate it silently dropping every table that
/// isn't listed. That is how widget refreshes repeatedly wiped the bundled
/// `Book`/`BookChapter` rows (and `TextbookChapter` before them). Keeping
/// one shared list means a newly-added model can't be forgotten in the
/// widget and quietly nuke its own data.
public static var localSchemaModels: [any PersistentModel.Type] {
[
Verb.self, VerbForm.self, IrregularSpan.self,
TenseGuide.self, CourseDeck.self, VocabCard.self,
TextbookChapter.self, DownloadedVideo.self,
Book.self, BookChapter.self,
]
}
}