leafittome/docs/handoff.md
cschlaefke da12e3e5ab iOS-Push aktiviert: APNs/Entitlements + Doku
- Push Notifications & Background Mode (remote-notification) als iOS-Capability
  ergänzt (Runner.entitlements, Info.plist, project.pbxproj)
- Apple Developer Account freigeschaltet, APNs-Schlüssel in Firebase hinterlegt
- Doku: firebase-einrichtung.md Schritt 6 auf "erledigt" + Stolperfalle
  "Personal Team versteckt Push-Capability" festgehalten
- Handoff: V1 nun auch iOS vollständig, iOS-Push aus Offen-Liste entfernt

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-20 16:47:05 +02:00

58 lines
6.4 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.

# Handoff: LeafItToMe (Pflanzenpflege-App)
Stand: 2026-07-20. Sprache mit dem Nutzer (Chris): **Deutsch**.
## Projekt in einem Satz
Private Flutter-App (iOS+Android) zur Pflanzenpflege für Haushalt + Pflanzen-Sitter: Foto-Erkennung (PlantNet + Claude), Gieß-/Düngeplan mit Tages-Checkliste, tägliche Sammel-Push, Haushalt-Teilen per Einladungscode mit Rollen.
## Wo alles liegt
- **Code:** `~/Documents/Projekte/Planty` (Ordner heißt noch Planty, Projekt heißt seit Umbenennung `leafittome`, App-Name „LeafItToMe", Bundle-ID-Platzhalter `dev.leafittome.app`)
- **Git-Remote:** selbst gehostetes Forgejo `https://git.cshomelabs.work/cschlaefke/leafittome.git` (HTTPS + Token im macOS-Schlüsselbund, `git push` läuft ohne Abfrage)
- **Doku (im Repo, deutsch, aktuell halten!):** `README.md`, `docs/architektur.md`, `docs/firebase-einrichtung.md` (Schritt-für-Schritt-Historie aller Backend-Einrichtungen), `docs/git-forgejo.md`
- **Claude-Memory:** Projektplan, Nutzerprofil und Backlog liegen im persistenten Memory-Verzeichnis dieser Claude-Code-Installation (werden automatisch geladen)
- **Firebase-Projekt:** `leaf-it-to-me-app` (Blaze aktiv, Budget-Alarm eingerichtet; Firebase CLI ist eingeloggt)
- **Functions:** `functions/` (TypeScript, Node 22, Region europe-west3): `identifyPlant` (PlantNet + Claude, Secrets `PLANTNET_API_KEY`/`ANTHROPIC_API_KEY` im Secret Manager), `sendDailyReminders` (alle 15 Min, sammelt über alle Haushalte eines Nutzers), `joinHousehold` (Einladungs-Einlösung), `leaveHousehold` (Haushalt verlassen), `removeMember` (Mitglied entfernen, nur Besitzer)
## Verifizierter Stand
- **V1 komplett** und auf Android + iOS Ende-zu-Ende getestet: Foto → Erkennung → vorbefülltes Profil; Tages-Checkliste; Sammel-Push kam im regulären Scheduler-Lauf auf dem Sperrbildschirm an. **iOS-Push seit 2026-07-20 eingerichtet und laufend** (Apple Developer Account freigeschaltet, APNs-Schlüssel in Firebase, Push-/Background-Capability in Xcode — Details + Stolperfalle „Personal Team" in `docs/firebase-einrichtung.md` Schritt 6).
- **V2 implementiert, deployt und vom Nutzer erfolgreich getestet** (Einladungscodes member/sitter, `joinHousehold`-Function, Rules-Enforcement für Sitter, „bestätigt von"-Anzeige).
- **V2.1 Multi-Haushalt implementiert und getestet**: Nutzer bleiben Mitglied aller Haushalte (`memberUids` ist Quelle der Wahrheit, `users.householdId` nur noch aktiver Zeiger), `sendDailyReminders` sammelt Aufgaben aus allen Haushalten.
- **V2.2 implementiert, deployt und vom Nutzer vollständig getestet und bestätigt**: Besitzer-Konzept (`ownerUid`, Alt-Haushalte: memberUids[0]), Besitzer-Anzeige, Haushalt umbenennen (Rules: Clients dürfen nur noch `name` ändern), Haushalts-Wechsler im Drawer, Tages-Checkliste gruppiert Aufgaben aus allen Haushalten, Functions `leaveHousehold`/`removeMember` (biegen den aktiven Zeiger des Betroffenen um, legen notfalls frischen Haushalt an). Zwei Nachbesserungen aus dem Live-Test, beide behoben und bestätigt:
- `leaveHousehold`/`removeMember` warfen zunächst HTTP 401 — fehlende Cloud-Run-Invoker-Berechtigung bei frisch angelegten Gen-2-Functions (kein Auth-Bug im Code); Fix war ein gezielter Neu-Deploy dieser beiden Functions.
- Besitzer-Anzeige blieb bei Alt-Haushalten aus der V1-Zeit leer (kein `members`-Eintrag für den Ersteller, die Map kam erst mit V2). Fix: `memberEntrySyncProvider` trägt beim App-Start die eigene E-Mail in allen eigenen Haushalten nach, plus eine eng gefasste Rules-Ausnahme (jeder darf nur den eigenen `members`-Eintrag pflegen, Rollenwechsel bleibt gesperrt).
## Offen / Nächstes
**Zuletzt erledigt (2026-07-20):** iOS-Push eingerichtet — Apple Developer Account war frisch freigeschaltet, APNs-Schlüssel/Firebase/Xcode-Capability durchgezogen, Nutzer bestätigt „läuft jetzt". Damit ist V1 auch auf iOS vollständig.
Bekannte Kandidaten für den nächsten Schritt:
1. **Apple-Login** — braucht denselben (jetzt vorhandenen) Developer Account, wäre logischer Anschluss an iOS-Push (siehe `docs/firebase-einrichtung.md` Schritt 7).
2. **V3:** Krankheits-Diagnose per Foto, Stellplatz-Bewertung (Standort-Analyse pro Stellplatz + Eignungs-Sterne pro Pflanze — Zwei-Ebenen-Konzept siehe Memory), Umtopf-Erinnerungen.
3. **Backlog:** Button „KI-Zweitmeinung" bei unbefriedigendem PlantNet-Ergebnis; Push-Anzeige auch bei App im Vordergrund; App Check vor App-Store-Release; Englisch (`app_en.arb`).
## Stolperfallen (teuer erkauft, nicht erneut zahlen)
- `firebase functions:log` hinkt **1520 Minuten** hinterher — „keine Läufe" heißt meist nur Log-Verzögerung. Scheduler-Status im Cloud-Scheduler-Console prüfen lassen.
- Android zeigt FCM-Pushes **nur bei App im Hintergrund**.
- `flutter_timezone` ≥5 liefert `TimezoneInfo`-Objekt → `.identifier` verwenden (Objekt crasht Firestore-Writes still).
- Storage-Rules mit `firestore.get()` brauchen die IAM-Rolle „Firebase Rules Firestore Service Agent" fürs Storage-Dienstkonto (wurde manuell erteilt).
- Erster Functions-Deploy in frischem Projekt kann mit 403 `iam.serviceaccounts.actAs` scheitern → wenige Minuten warten, erneut deployen.
- Analyzer: `build/` und `ios/build/` sind in `analysis_options.yaml` ausgeschlossen (SwiftPM legt dort Fremdcode ab).
- iOS-Fehler „requires minimum platform version 15.0 … but this target supports 13.0": Das von Flutter generierte SwiftPM-Paket (`ios/Flutter/ephemeral/…/Package.swift`) wird bei `pub get` mit iOS 13 erzeugt; erst `flutter build ios`/`flutter run` hebt es auf das Projekt-Target (15.0) an. Nach `flutter clean` oder beim Bauen direkt aus Xcode daher einmal `flutter build ios --config-only` ausführen.
- Nutzer wünscht zu jedem Backend-Baustein **begleitende deutsche Doku** in `docs/` (keine Firebase-Vorerfahrung).
## Arbeitsabläufe
- Prüfen: `flutter analyze && flutter test` (Tests mocken Firebase via `firebase_auth_mocks`/`fake_cloud_firestore`); Android-Verifikation: `flutter build apk --debug`
- Texte: nur in `lib/l10n/app_de.arb` (typografische Anführungszeichen „…“ verwenden, gerade `"` brechen das JSON), dann `flutter gen-l10n`
- Deploy: `firebase deploy --only functions|firestore|storage --project leaf-it-to-me-app`; nach jedem Arbeitsstand committen + `git push`
## Suggested skills
- `/verify` — nach nichttrivialen Änderungen den echten Flow treiben (Gerät/Simulator), nicht nur Tests
- `/code-review` — vor größeren Merges über den Diff laufen lassen
- `/run` — App starten/screenshotten, wenn Änderungen sichtbar geprüft werden sollen