cards-native/docs/RELEASE_CHECKLIST.md
Till JS b5edf5cf2e fix: User-facing Strings Cards → Cardecky komplett, Build 3
User-facing Rebrand:
- LoginView Heading (war schon in v0.8.5)
- NotificationManager.title (war schon in v0.8.5)
- ShareEditorView Footer-Text: "...in der Cards-App" → "...in der Cardecky-App"
- StudyAppIntents Description: "Öffnet Cards" → "Öffnet Cardecky"
- Localizable.xcstrings: "Cards" key → "Cardecky"
- NSPhotoLibraryUsageDescription: "Cards greift..." → "Cardecky greift..."
- Log.app.info("Cards starting") → "Cardecky starting"
- MARKETING_COPY.md: alle "Cards"-Treffer in DE + EN auf Cardecky
- RELEASE_CHECKLIST: App-Name "Cards" → "Cardecky"

Build-Nummer 2 → 3 (Apple lehnt doppelte Build-Nummern ab, Code-
Hash hat sich geändert).

Code-Identifier bleiben: CardsAPI, CardsTheme, CardsNativeApp,
CardsWidgetExtension, CardsShareExtension — interne Symbol-Namen,
nicht user-facing.

Archive verifiziert: CFBundleDisplayName=Cardecky, Build=3.

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

153 lines
7.2 KiB
Markdown
Raw Permalink 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: "Cardecky"
- 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.