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

7.2 KiB
Raw Blame History

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 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

  • 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.
  • 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.
  • 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 — 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.
  • Privacy-Policy-URL: https://cardecky.mana.how/privacy (live seit 2026-05-13, SvelteKit-Route mit Verein-Content).
  • 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)

  • Entschieden: separate Apps. memoro-native und cards-native sind eigenständige App-Store-Einträge. Keine Hub-App.

Carryover-Tasks (β-6 / β-7-Reste)

  • Siri-Shortcut via App Intents (StudyCardsIntent) — funktional, v1: nur "App öffnen". Erweiterung "Direkt in Default-Deck-Study" kann später kommen.
  • 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.