Add a new Complete the Sentence quiz type that renders a Spanish example sentence from the card with the target word blanked out and asks the student to pick the missing word from 4 choices (other cards' fronts from the same week's pool). Core logic lives in SharedModels/SentenceQuizEngine as pure functions over VocabCard, covered by 18 Swift Testing tests. CourseQuizView calls the engine, pre-filters the card pool to cards that can produce a resolvable blank, and reuses the existing MC rendering via a new correctAnswer(for:) helper. VocabCard gains examplesBlanks (parallel array to examplesES) so content can explicitly tag the blanked substring; DataLoader reads an optional "blank" key on each example. Additive schema change, CloudKit-safe default. Also adds ContentCoverageTests that parse the repo's course_data.json and assert every card has >=3 examples and yields a resolvable question. These tests currently fail: 1,117 cards still need sentences. They are the oracle for the gap-fill pass that follows. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
33 lines
1.1 KiB
Swift
33 lines
1.1 KiB
Swift
import SwiftData
|
|
import Foundation
|
|
|
|
@Model
|
|
public final class VocabCard {
|
|
public var front: String = ""
|
|
public var back: String = ""
|
|
public var deckId: String = ""
|
|
public var examplesES: [String] = []
|
|
public var examplesEN: [String] = []
|
|
/// Per-example blank word for Complete the Sentence quiz. Index-aligned with `examplesES`.
|
|
/// Empty string at a given index means "fall back to substring-matching card.front".
|
|
public var examplesBlanks: [String] = []
|
|
|
|
public var deck: CourseDeck?
|
|
|
|
// Legacy SRS fields retained only so old local progress can be migrated to CourseReviewCard.
|
|
public var easeFactor: Double = 2.5
|
|
public var interval: Int = 0
|
|
public var repetitions: Int = 0
|
|
public var dueDate: Date = Date()
|
|
public var lastReviewDate: Date?
|
|
|
|
public init(front: String, back: String, deckId: String, examplesES: [String] = [], examplesEN: [String] = [], examplesBlanks: [String] = []) {
|
|
self.front = front
|
|
self.back = back
|
|
self.deckId = deckId
|
|
self.examplesES = examplesES
|
|
self.examplesEN = examplesEN
|
|
self.examplesBlanks = examplesBlanks
|
|
}
|
|
}
|