v0.8.0 — Phase β-7 App-Store-Vorbereitung
Feature-komplett für TestFlight. App-Icon-Platzhalter, Siri-Shortcut, Share-Extension, Release-Checklist mit allen externen Apple-Schritten. - scripts/make-appicon.swift: CoreGraphics-basierter Generator für 1024×1024 forest-green PNG mit "C"-Letter und Karten-Stack-Schatten - Asset-Catalog auf Single-Size-AppIcon-Pattern umgestellt - StudyCardsIntent + CardsAppShortcuts (App Intents): Siri- Shortcut "Karten lernen mit Cards" / "Mit Cards lernen" - CardsShareExtension Target: ShareViewController (UIKit-Bootstrap + SwiftUI-Hosting), ShareEditorView mit Text-Edit - PendingShare + PendingShareStore shared in App-Group group.ev.mana.cards - DeckListView zeigt PendingShare-Banner; Tap navigiert zu PendingShareConsumeView mit Deck-Picker + Front/Back-Felder, Submit → POST /cards, danach store.remove - Info.plist: NSPhotoLibraryUsageDescription für Image-Occlusion- Picker, NSUserActivityTypes für Universal-Links - docs/RELEASE_CHECKLIST.md mit externen Schritten: Apple-Developer- Portal, App-IDs, App-Group, AASA, Xcode-Archive, TestFlight-Plan, App-Store-Connect-Felder, Compliance-Verifikation - UI-Test robuster (akzeptiert Login oder Decks/Entdecken als Launch-Erfolg, unabhängig vom Simulator-Keychain-State) - 35 Tests + 1 UI-Test grün, alle drei Targets bauen App-Store-Submission selbst ist externe Aktion und passiert nicht durch dieses Repo — Schritte in docs/RELEASE_CHECKLIST.md. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
55359c5333
commit
0b2ae167b7
16 changed files with 783 additions and 59 deletions
153
docs/RELEASE_CHECKLIST.md
Normal file
153
docs/RELEASE_CHECKLIST.md
Normal file
|
|
@ -0,0 +1,153 @@
|
|||
# RELEASE_CHECKLIST — cards-native
|
||||
|
||||
Externe Schritte vor App-Store-Submission. Alles unter dieser
|
||||
Sektion läuft NICHT durch das Repo — sondern durch das Apple-
|
||||
Developer-Portal, App-Store-Connect, das Cards-Web-Repo (für
|
||||
AASA) und über Xcode (für Build + Sign).
|
||||
|
||||
## Vor TestFlight (intern, kein Apple-Review)
|
||||
|
||||
### Apple-Developer-Konfiguration
|
||||
|
||||
- [ ] **Team-ID prüfen** für den mana-e.V.-Apple-Developer-Account.
|
||||
Eintragen in `project.yml > settings > base > DEVELOPMENT_TEAM`
|
||||
(oder per-Scheme in Xcode unter "Signing & Capabilities").
|
||||
- [ ] **App-ID `ev.mana.cards`** im Developer-Portal anlegen, falls
|
||||
noch nicht da. Mit Capabilities: App Groups, Keychain Sharing,
|
||||
Associated Domains.
|
||||
- [ ] **App-ID `ev.mana.cards.share`** + **`ev.mana.cards.widget`** für
|
||||
die Extensions analog anlegen, ebenfalls mit App Groups.
|
||||
- [ ] **App-Group `group.ev.mana.cards`** im Portal anlegen und allen
|
||||
drei App-IDs zuweisen.
|
||||
- [ ] **Keychain-Access-Group**: heute `ev.mana.cards`. Wenn
|
||||
Shared-Keychain mit `memoro-native` gewünscht (siehe
|
||||
`mana/docs/MANA_SWIFT.md` Phase γ), auf
|
||||
`$(AppIdentifierPrefix)ev.mana.shared` umstellen und
|
||||
`AppConfig.manaAppConfig.keychainAccessGroup` setzen.
|
||||
- [ ] **Provisioning Profiles** für alle drei Targets generieren
|
||||
(Development + Distribution). Bei "Automatic Signing" macht
|
||||
Xcode das beim ersten Build selbst, wenn das Team-ID stimmt.
|
||||
|
||||
### Asset-Polish
|
||||
|
||||
- [ ] **AppIcon ersetzen.** Heute Platzhalter aus
|
||||
`scripts/make-appicon.swift` (forest-green "C"). Vor Submission
|
||||
durch ein vom Designer erstelltes Icon austauschen
|
||||
(`Sources/Resources/Assets.xcassets/AppIcon.appiconset/AppIcon-1024.png`).
|
||||
- [ ] **Marketing-Versionsnummer** in `project.yml` setzen
|
||||
(`MARKETING_VERSION` → "1.0.0").
|
||||
- [ ] **Build-Nummer** monoton inkrementieren bei jedem TestFlight-
|
||||
Upload (`CURRENT_PROJECT_VERSION`).
|
||||
|
||||
### Server-seitige Vorbedingungen
|
||||
|
||||
- [ ] **AASA-Endpoint** auf `cardecky.mana.how/.well-known/apple-app-site-association`
|
||||
ausliefern (heute 404). Format:
|
||||
```json
|
||||
{
|
||||
"applinks": {
|
||||
"apps": [],
|
||||
"details": [{
|
||||
"appID": "<TEAMID>.ev.mana.cards",
|
||||
"paths": ["/d/*"]
|
||||
}]
|
||||
}
|
||||
}
|
||||
```
|
||||
Content-Type muss `application/json` sein (nicht `text/html`).
|
||||
Aufgabe ans Cards-Web-Repo.
|
||||
- [ ] **cardecky-api.mana.how** muss erreichbar bleiben — die App
|
||||
ist 100% Online-write. Health-Probe verifizieren.
|
||||
|
||||
### Build + Archive
|
||||
|
||||
- [ ] `xcodegen generate`
|
||||
- [ ] In Xcode: Product → Archive (Destination "Any iOS Device")
|
||||
- [ ] Im Organizer: Validate App
|
||||
- [ ] Distribute App → TestFlight & App Store
|
||||
|
||||
### TestFlight-Test-Plan
|
||||
|
||||
- [ ] **Endurance:** 200+ Karten lernen, Flugmodus zwischendurch.
|
||||
- [ ] **Cross-Device:** Web↔Native parallel. Karte gegrade in App →
|
||||
Web zeigt nach Reload identischen Review-State.
|
||||
- [ ] **Widget:** ans Home-Screen pinnen, Due-Count nach App-Refresh.
|
||||
- [ ] **Universal-Link:** `https://cardecky.mana.how/d/<slug>` in
|
||||
Safari öffnen → App startet auf Explore-Tab + Public-Deck-Detail.
|
||||
- [ ] **Share-Extension:** Text in Safari markieren → Teilen → "Als
|
||||
Karte speichern" → Karte landet in der App.
|
||||
- [ ] **Siri-Shortcut:** "Hey Siri, Karten lernen" → App öffnet.
|
||||
- [ ] **Daily-Reminder:** Tagesgrenze überqueren, Notification kommt
|
||||
zur konfigurierten Uhrzeit.
|
||||
- [ ] **Login/Logout:** kompletter Auth-Roundtrip.
|
||||
- [ ] **Offline-Grades:** Reviews offline machen, online gehen,
|
||||
`PendingGrade`-Queue läuft leer.
|
||||
|
||||
## Vor App-Store-Submission (öffentliches Review)
|
||||
|
||||
### App-Store-Connect
|
||||
|
||||
- [ ] **App-Eintrag erstellen** unter https://appstoreconnect.apple.com
|
||||
mit Bundle-ID `ev.mana.cards`.
|
||||
- [ ] **App-Name** + **Subtitle** (max 30 Zeichen):
|
||||
- Name: "Cards"
|
||||
- Subtitle: "Karteikarten — Verein mana"
|
||||
- [ ] **Description** (de + en, max 4000 Zeichen). Vorschlag siehe
|
||||
`docs/MARKETING_COPY.md` (existiert noch nicht — TODO).
|
||||
- [ ] **Keywords** (max 100 Zeichen, comma-separated):
|
||||
"Karteikarten,Spaced Repetition,Lernen,Vokabeln,Anki,Flashcards,FSRS,mana,Verein,Open Source"
|
||||
- [ ] **Screenshots** für iPhone 16 Pro Max + iPhone SE-3 + iPad Pro.
|
||||
6.7", 6.5", 5.5", iPad 12.9" — siehe Apple's Specs.
|
||||
- [ ] **Privacy-Policy-URL** — vermutlich `cardecky.mana.how/privacy`
|
||||
oder `mana-ev.ch/privacy`. **Verifizieren.**
|
||||
- [ ] **Support-URL** — `cardecky.mana.how/help` oder Verein-Kontakt.
|
||||
- [ ] **Marketing-URL** (optional) — `cardecky.mana.how`.
|
||||
- [ ] **Age-Rating**: vermutlich 4+ (no objectionable content).
|
||||
- [ ] **Pricing**: Free.
|
||||
- [ ] **App-Privacy** (Data Type Declaration):
|
||||
- Email-Adresse (für Login)
|
||||
- User-Inhalt (Karten, Decks)
|
||||
- Nutzungsdaten (FSRS-Reviews)
|
||||
- **Nicht** für Tracking verwendet.
|
||||
|
||||
### Compliance / Verein-Werte
|
||||
|
||||
- [ ] **Lese `mana/docs/COMPLIANCE.md`** und prüfe, dass keine
|
||||
Telemetrie, kein Crash-Reporter, kein SaaS-Tracker in Submission-
|
||||
Build (Stripe + APNs sind die akzeptierten Ausnahmen — Cards
|
||||
nutzt keines davon heute).
|
||||
- [ ] **Subscriptions / In-App-Purchases**: Marketplace-Paid-Decks
|
||||
sind über `mana-credits` abgewickelt, nicht über StoreKit. Im
|
||||
App-Store-Connect "no In-App-Purchases" auswählen, **außer**
|
||||
wir wollen vor Submission StoreKit für `mana-credits` einführen
|
||||
(separate Architektur-Frage).
|
||||
|
||||
### Hub-App vs Standalone-App (siehe MANA_SWIFT.md)
|
||||
|
||||
- [x] Entschieden: separate Apps. memoro-native und cards-native sind
|
||||
eigenständige App-Store-Einträge. Keine Hub-App.
|
||||
|
||||
## Carryover-Tasks (β-6 / β-7-Reste)
|
||||
|
||||
- [x] Siri-Shortcut via App Intents (`StudyCardsIntent`) — funktional,
|
||||
v1: nur "App öffnen". Erweiterung "Direkt in Default-Deck-Study"
|
||||
kann später kommen.
|
||||
- [x] Share-Extension "Save as Card" — Pragma-Lösung: Extension
|
||||
speichert `PendingShare` in App-Group, Haupt-App zeigt Banner,
|
||||
User wählt Ziel-Deck und Back-Text. Kein direkter API-Call aus
|
||||
der Extension (Auth-State wäre kompliziert, Pragma reicht für v1).
|
||||
- [ ] **Card-Edit** (PATCH `/cards/:id`): heute deferred, ergänzen wenn
|
||||
Beta-User danach fragen.
|
||||
- [ ] **Anki-Import**: heute deferred, weil Web client-side parsed
|
||||
und kein Server-Endpoint existiert. Native bräuchte eigenen
|
||||
`.apkg`-Parser (sqlite-basiert) — eigener Sprint.
|
||||
|
||||
## Nach Submission
|
||||
|
||||
- [ ] **Monitoring**: nach Release `cardecky-api.mana.how/healthz` und
|
||||
Rate-Limit-Auslastung beobachten — Native-App kann Last-Spitzen
|
||||
erzeugen.
|
||||
- [ ] **DSGVO-Endpoint** (`/api/v1/dsgvo/export`, `/delete`) testweise
|
||||
aus Native triggerbar machen (β-7-Extension oder β-8).
|
||||
- [ ] **Update-Cadence**: erstmal alle 2-4 Wochen ein Build.
|
||||
Build-Nummer monoton, Marketing-Version semver.
|
||||
Loading…
Add table
Add a link
Reference in a new issue