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>
118 lines
5.3 KiB
Markdown
118 lines
5.3 KiB
Markdown
# 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
|
|
+ Erfolgs-Kriterien in [`docs/NATIVE_LIFT_PLAN.md`](docs/NATIVE_LIFT_PLAN.md).
|
|
|
|
> **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)**
|
|
|
|
- [x] `Sources/Core/WebShell/CookieBridge.swift` gelöscht +
|
|
WebShell-Verzeichnis entfernt.
|
|
- [x] `ManaWebShell`-Dep aus `project.yml` raus.
|
|
- [x] `RootView.swift` auf vier native Tabs umgestellt; Lesen +
|
|
Erkunden zeigen Platzhalter-Views (η-2/η-4-Hinweis).
|
|
- [x] DocComments in `DeepLinkRouter.swift`, `AppConfig.swift`,
|
|
`AccountView.swift`, `SettingsView.swift` von WebView-Verweisen
|
|
befreit.
|
|
- [x] `CLAUDE.md` Invarianten ersetzt (Hybrid → η).
|
|
- [x] `xcodegen generate` + iOS-Simulator-Build grün (iPhone 16e, Xcode
|
|
26.2 SDK).
|
|
- [x] `nm ZitareNative` zeigt 0 WKWebView-Referenzen; `otool -L`
|
|
kein WebKit-Framework-Link. Binary ist WebView-frei.
|
|
- [x] 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).
|
|
- [x] 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`](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.
|