Voller Lern-Flow mit Web-Parität: fällige Karten via /reviews/due laden, flip + rate (4 Buttons + Haptic), Grades via Offline-Queue ans Server-FSRS schicken. - Card/Review/DueReview DTOs mit snake_case + camelCase-deckId- Sonderfall im embedded card-Subobjekt - CardType-Enum (alle 7 Typen), Rating-Enum mit deutschen Labels - Cloze-Helper 1:1-Port aus cards-domain (extractClusterIds, subIndexCount, clusterId, renderPrompt/Answer, hint) - CardsAPI.dueReviews(deckId:) + gradeReview(cardId,subIndex,rating,reviewedAt) - PendingGrade SwiftData-Model + GradeQueue (FIFO-Drain, originaler Timestamp bleibt, bei Netzfehler in Queue, Retry beim nächsten Drain) - StudySession @Observable State-Machine - CardRenderer für basic, basic-reverse, cloze; Placeholder für image-occlusion/audio-front/typing/multiple-choice (β-3/β-4) - RatingBar mit UIImpactFeedbackGenerator (medium/heavy) - StudySessionView per NavigationLink aus DeckListView - 9 neue Tests (Cloze: 8, Review-Decoding: 3), insgesamt 17 grün Server-authoritative FSRS bleibt — kein ts-fsrs-Port. Endurance-Test auf realem Gerät steht aus (siehe PLAN.md). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
4.6 KiB
Plan — cards-native (SwiftUI Universal)
Stand: 2026-05-13 — Phasen β-0 + β-1 + β-2 abgeschlossen. Repo auf Forgejo, Login funktioniert, Deck-Liste mit Cache + Pull-to-Refresh, voller Study-Loop mit Flip/Rating/Haptic + Offline-Queue für Grades (PendingGrade SwiftData). Cloze client- rendered (1:1-Port aus cards-domain). 17 Unit-Tests + 1 UI-Test grün.
Pflicht-Check für β-2: Endurance-Test auf realem Gerät (200+ Karten mit Flugmodus zwischendurch) steht aus — Aufgabe für Till.
SOT:
../mana/docs/playbooks/CARDS_NATIVE_GREENFIELD.md. Dieses File ist die App-lokale Status-Spur, das Greenfield-Doc hat die ganze Architektur-Begründung.
Aktueller Stand
✅ β-0 — Setup (2026-05-12, Tag v0.1.0)
- Repo-Skelett unter
git.mana.how/till/cards-native project.ymlmit Bundle-IDev.mana.cards, ManaSwiftCore viapath: ../mana-swift-coreAppConfigalsManaAppConfig-Provider:- Auth:
https://auth.mana.how - API:
https://cardecky-api.mana.how - Keychain-Service:
ev.mana.cards
- Auth:
CardsTheme.swiftmit forest-Werten (lokal nachgebaut ausmana/packages/themes/src/variants/forest.css)LoginView(Email/PW gegen mana-auth)- 3 Unit-Tests (AppConfig)
✅ β-2 — Study-Loop (2026-05-13, Tag v0.3.0)
Card,Review,DueReviewCodable-DTOs,CardType-Enum (alle 7 Typen)Rating-Enum:again | hard | good | easymit deutschen LabelsCloze-Helpers (extractClusterIds, subIndexCount, clusterId, renderPrompt, renderAnswer, hint) — 1:1-Port auscards/packages/cards-domain/src/cloze.tsCardsAPI.dueReviews(deckId:),CardsAPI.gradeReview(...)mit ISO8601-EncoderPendingGradeSwiftData-Model +GradeQueuefür Offline-Submit (FIFO-Drain, originaler reviewedAt-Timestamp bleibt erhalten)StudySessionals @Observable State-Machine (loading/studying/finished/failed)CardRenderer: basic, basic-reverse (sub-index-abhängig), cloze client-rendered. image-occlusion/audio-front/typing/multiple-choice zeigen Placeholder (β-3/β-4)RatingBarmit Haptic-Feedback (medium für again/hard/good, heavy für easy, soft beim Flip)StudySessionViewvollbild aus DeckListView per NavigationLink- 9 zusätzliche Tests (Cloze 8x, Review/DueReview-Decoding 3x)
✅ β-1 — Decks lesen (2026-05-13, Tag v0.2.0)
Deck-Codable-DTO mit snake_case-CodingKeys, plusDeckCategory,DeckVisibility,FsrsSettings- ISO8601-Date-Decoder mit Fractional-Seconds-Toleranz
CardsAPI.listDecks(),cardCount(deckId:),dueCount(deckId:)CachedDeckals SwiftData-Model mitlastFetchedAt(Offline-Read)DeckListStoreorchestriert API + Cache, paralleles Counts-Fetching via TaskGroupDeckListViewmit Pull-to-Refresh, Card/Due-Counts, deck.color-Streifen, Inbox-Banner für Marketplace-ForksAccountViewmit Sign-out-Button- iOS-Simulator-Build + Tests grün (6 Unit-Tests, 1 UI-Test)
Phasen (Detail in Greenfield-Plan)
| Phase | Status | Inhalt |
|---|---|---|
| β-0 | ✅ 2026-05-12 | Setup, Login, API-Probe |
| β-1 | ✅ 2026-05-13 | Decks lesen, SwiftData-Cache, Pull-to-Refresh |
| β-2 | ✅ 2026-05-13 | Study-Loop, Offline-Grade-Queue (Endurance-Test offen) |
| β-3 | — | Card-/Deck-Editor (basic, cloze, typing, multiple-choice) |
| β-4 | — | Media, image-occlusion (PencilKit), audio-front |
| β-5 | — | Marketplace, Universal-Links |
| β-6 | — | Native-Polish (Widgets, Notifications, Share-Extension) |
| β-7 | — | App-Store-Submission |
Nächste Schritte für β-3 (Editor)
Aus Greenfield-Plan-Sektion "Phase β-3 — Card-/Deck-Editor":
DeckCreateView: Form für Name, Description, Color (Picker), Category-Picker, Visibility, FSRS-Settings (Sheet)CardEditorViewper Type (basic, cloze, typing, multiple-choice): Two-Text-Fields oder Cloze-Syntax-Highlighting- POST/PATCH/DELETE
/api/v1/cardsund/api/v1/decks - Anki-Import als Datei-Picker →
/api/v1/decks/import
Erfolgskriterium: Karte in Native erstellt, in Web sichtbar; Karte in Web erstellt, in Native sichtbar (Pull-to-Refresh).
Pflicht-Tests für β-2 (vor β-3-Start)
- Endurance-Test auf realem Gerät: 200+ Karten lernen, Flugmodus zwischendurch — alle Grades landen am Server nach Reconnect.
- Cross-Check mit Web: Karte gegrade in Native → Web zeigt identischen Review-State nach Reload.
Cross-Refs
../mana/docs/playbooks/CARDS_NATIVE_GREENFIELD.md— Greenfield-Plan SOT../mana/docs/MANA_SWIFT.md— Plattform-SOT../cards/CLAUDE.md— Cards-Repo../cards/STATUS.md— Web-Phasenstand (Referenz)../mana-swift-core/CLAUDE.md— ManaCore-KonventionenCLAUDE.md— Repo-Konventionen