zitare-native/PLAN.md
Till JS 1d770123f5 η-0: De-Hybrid — WKWebView raus, native Tabs mit Platzhaltern
Lift von Hybrid (WKWebView für Lesen/Erkunden) auf fully-native ist
beschlossen. Diese Phase entfernt die WebShell-Infrastruktur; das volle
native Read-Surface folgt in η-2..η-5 nach docs/NATIVE_LIFT_PLAN.md.

- ManaWebShell-Dep raus aus project.yml
- Sources/Core/WebShell/CookieBridge.swift gelöscht
- RootView auf vier native Tabs (Lesen + Erkunden = Platzhalter,
  Submit + Konto unverändert nativ)
- DocComments in DeepLinkRouter / AppConfig / Account / Settings von
  WebView-Verweisen befreit
- CLAUDE.md Invarianten von Hybrid auf η umgestellt (13 Invarianten,
  pure SwiftUI + Offline-first + SafariView-Ausnahme für Legal)
- PLAN.md auf η-0 + Phasenübersicht η-0..η-10
- AppConfigTests.test_keychainService_matchesSharedGroup auf
  ManaSharedKeychainGroup aktualisiert (war drift seit Cross-App-SSO)

Verifikation:
- xcodebuild iOS-Simulator iPhone 16e: BUILD SUCCEEDED
- nm ZitareNative | grep WKWebView: 0 Referenzen
- otool -L: kein WebKit-Framework-Link
- 20/20 Tests grün

Cross-Repo-Follow-up (η-1 Blocker):
- zitare/apps/zitare/ muss index-full.json + 7 Stammdaten-JSONs liefern
- zitare/apps/api/ Volltext-Search-Endpoint bestätigen/ergänzen

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

5.3 KiB

Plan — zitare-native (η = fully native)

Stand: 2026-05-22 — Phase η-0 in Arbeit. Hybrid-Strategie ist revidiert. Lese-Surfaces werden nativ. Vollständige Phasen-Begründung

SOT: der NATIVE_LIFT_PLAN. Dieses File ist nur die App-lokale Status-Spur.

Archiv: Phasen ζ-0 bis ζ-2 (Hybrid, abgeschlossen)

Code aus diesen Phasen lebt teils weiter, teils ist er entfernt:

  • ζ-0 Setup — Repo-Skelett, project.yml, iOS-Simulator-Build, ManaCore-Login + Healthz-Probe live (2026-05-14).
  • ζ-1 WebShellView + Cookie-Bridge — gebaut, dann in η-0 (heute) wieder gelöscht. CookieBridge.swift weg, ManaWebShell-Dep raus aus project.yml.
  • 🚧 ζ-2 Snapshot-Sync + DailyQuoteWidget (Code-Done) — Widget-Code
    • SwiftData-Stub-Modelle existieren, Endpoint im Web-Repo (Snapshot v1 index-min.json) + Apple-Dev-Portal-App-Group fehlen für E2E. Wird in η-1 auf Snapshot v2 erweitert.

Aktuell

η-0 — De-Hybrid (2026-05-22, abgeschlossen)

  • Sources/Core/WebShell/CookieBridge.swift gelöscht + WebShell-Verzeichnis entfernt.
  • ManaWebShell-Dep aus project.yml raus.
  • RootView.swift auf vier native Tabs umgestellt; Lesen + Erkunden zeigen Platzhalter-Views (η-2/η-4-Hinweis).
  • DocComments in DeepLinkRouter.swift, AppConfig.swift, AccountView.swift, SettingsView.swift von WebView-Verweisen befreit.
  • CLAUDE.md Invarianten ersetzt (Hybrid → η).
  • xcodegen generate + iOS-Simulator-Build grün (iPhone 16e, Xcode 26.2 SDK).
  • nm ZitareNative zeigt 0 WKWebView-Referenzen; otool -L kein WebKit-Framework-Link. Binary ist WebView-frei.
  • Tests grün: 20/20 (AppConfigTests + DeepLinkRouterTests + SnapshotSyncTests + SmokeUITests). Pre-existing Keychain-Service- Test auf ManaSharedKeychainGroup aktualisiert (war out-of-sync seit Cross-App-SSO-Konsolidierung).
  • Greenfield-Playbook mana/docs/playbooks/ZITARE_NATIVE_GREENFIELD.md als überholt markiert (Banner + status-Header).

Phasen-Übersicht (η)

Phase Ziel Erfolg Status
η-0 De-Hybrid Build grün, kein WKWebView im Binary
η-1 Snapshot v2 + volles SwiftData-Schema Cold-Start lädt vollen Korpus, ETag spart Bytes (Web-Repo-Blocker)
η-2 Read-Core (Heute, Quote, Author) Flugmodus + UL aus Mail-App zeigt Quote nativ
η-3 Read-Browse (Source/Theme/Place/Role/Epoch/Lang) Alle Deep-Link-Pattern aus app-manifest.json nativ
η-4 Explore + Filter „Roman + DE + lang" Filter live ohne Server
η-5 Search (lokal + Server-Fallback) Offline-Treffer + Online-Ergänzung
η-6 Account nativ Sign-In/Out + Submissions-Liste nativ
η-7 Legal via SafariView Impressum/Datenschutz/Lizenz als SFSafariViewController
η-8 Submit + ShareExt + Spotlight an Snapshot v2 Spotlight findet via Volltext
η-9 Polish (iPad / Accessibility / macOS) Solo-Nutzung ohne Browser-Tab eine Woche
η-10 TestFlight Approved

Externe Blocker (nicht von Native-Code lösbar)

  • Apple-Dev-Portal: App-Group group.ev.mana.zitare registrieren — sonst kein macOS-Build und kein Widget auf realem Gerät. Selbe Aktion wie für cards/memoro/moodlit/herbatrium nötig.
  • Cloudflare: DNS-CNAME für zitare.com (Apex) auf 1435166a-0e3f-4222-8de6-744f32cea5c9.cfargotunnel.com proxied. Plus Cleanup des versehentlichen zitare.com.mana.how-CNAME. Anleitung in docs/CLOUDFLARE_TODO.md.

Web-Vorbedingungen (Aufgabe an ../zitare/)

η-1-Blocker — ohne diese Endpoints kein Offline-Lesen:

  • https://zitare.com/index-full.json mit allen Quote-Feldern inkl. Volltext.
  • Stammdaten-Collections: authors.json, sources.json, themes.json, places.json, epochs.json, roles.json, languages.json auf zitare.com/.
  • ETag-Header für jeden dieser Endpoints (Cache-Control: 1h).

η-5-Voraussetzung:

  • GET /api/v1/quotes?q=<query> Volltext-Search bestätigt / ergänzt in zitare/apps/api/.

η-6-Voraussetzung:

  • GET /api/v1/me/submissions (eigene Einreichungen) bestätigt / ergänzt.

Restliche Web-Vorbedingungen (orthogonal):

  • AASA auf https://zitare.com/.well-known/apple-app-site-association mit appID: QP3GLU8PH3.ev.mana.zitare.
  • zitare.com Cloudflare-Zone-Onboarding (steht in zitare/STATUS.md als offen).

Verifikations-Lücken

η-0: keine offenen. Pre-existing 4 swiftlint-strict-Violations in ZitareNativeApp.swift + SubmitQuoteView.swift bleiben — sind aus ζ-3 (Submit-Phase) und nicht η-0-Scope.

Quirks

  • swiftformat läuft aggressiver als die letzte ζ-Phase: entfernt Sendable-Konformanz aus DropRecord/QuoteDraft/SubmittedQuote und self.-Prefix in OS_log_t.info(...)-@autoclosure-Calls. Beides führt zu Strict-Concurrency-Errors. In η-0 wurden die Kollateral-Edits zurückgerollt; swiftformat muss vor η-1 mit expliziter Exclude-Liste oder einer .swiftformat-Regel-Anpassung gezähmt werden, sonst zerstört der nächste Format-Lauf wieder Submit-Code.