cards-native/docs/RELEASE_CHECKLIST.md
Till JS 6a4d66fd74 chore: Sendable-Warning + AppIcon-Asset-Cleanup
- CardEditorView: pickerLabel als separate computed property
  extrahiert (PhotosPicker-Sendable-Closure-Warning auf
  occlusionImage). Warning bleibt cosmetisch auf der neuen Property,
  Swift-6-Strict-Edge-Case mit SwiftUI ViewBuilders.
- AppIcon.appiconset/Contents.json: mac-Idiom-Slot entfernt
  (iOS-only erstmal — macOS-Support kommt mit eigenem Icon-Satz).
  Behebt "unassigned child"-Warnings.
- RELEASE_CHECKLIST: /privacy + /help URLs als done markiert
  (live deployed in cards-Repo Commit c6488c0).

Archive verifiziert: ARCHIVE SUCCEEDED, drei Provisioning Profiles
(ev.mana.cardecky + .widget + .share) automatisch geholt und gesigned.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-13 14:12:29 +02:00

153 lines
7.2 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 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
- [x] **Team-ID gesetzt** (`QP3GLU8PH3`, mana e.V.) — `DEVELOPMENT_TEAM`
in `project.yml > settings > base`. Greift bei Archive automatisch.
- [ ] **App-ID `ev.mana.cardecky`** im Developer-Portal anlegen, falls
noch nicht da. Mit Capabilities: App Groups, Keychain Sharing,
Associated Domains.
- [ ] **App-ID `ev.mana.cardecky.share`** + **`ev.mana.cardecky.widget`** für
die Extensions analog anlegen, ebenfalls mit App Groups.
- [ ] **App-Group `group.ev.mana.cardecky`** im Portal anlegen und allen
drei App-IDs zuweisen.
- [ ] **Keychain-Access-Group**: heute `ev.mana.cardecky`. 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
- [x] **AASA-Endpoint** auf `cardecky.mana.how/.well-known/apple-app-site-association`
— SvelteKit-Server-Route gebaut in
`cards/apps/web/src/routes/.well-known/apple-app-site-association/+server.ts`
(2026-05-13). Content-Type `application/json`, paths `/d/*` und
`/u/*`. Lokal mit `node build` + curl verifiziert.
- [x] **`PUBLIC_APPLE_TEAM_ID=QP3GLU8PH3`** in
`cards/infrastructure/docker-compose.production.yml` hinterlegt
(Commit folgt). Wird zur Runtime von `$env/dynamic/public`
aufgelöst und in den AASA-Response geschrieben.
- [x] **Production-Deploy von cards-web** durchgeführt 2026-05-13.
Probe von außen: `curl https://cardecky.mana.how/.well-known/apple-app-site-association`
liefert `application/json` mit `"appID":"QP3GLU8PH3.ev.mana.cardecky"`.
Cloudflare-Tunnel reicht den Endpoint sauber durch (kein
HTML-Captive, kein Redirect).
- [ ] **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.cardecky`.
- [ ] **App-Name** + **Subtitle** (max 30 Zeichen):
- Name: "Cards"
- Subtitle: "Karteikarten — Verein mana"
- [ ] **Description** (de + en, max 4000 Zeichen). Vorschlag in
[`docs/MARKETING_COPY.md`](MARKETING_COPY.md) — vor Submission
gegenlesen und Vereins-Tonalität schärfen.
- [ ] **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.
- [x] **Privacy-Policy-URL**: `https://cardecky.mana.how/privacy` (live
seit 2026-05-13, SvelteKit-Route mit Verein-Content).
- [x] **Support-URL**: `https://cardecky.mana.how/help` (live, FAQ +
Kontakt-Email kontakt@mana-ev.ch).
- [ ] **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.