- icon_transparent.py: blauer Sky-Hintergrund per RGB-Schwelle entfernt
(b > 0.55, b > r+0.05 …), trimmt auf Content-Bbox
- AppIconHero.imageset mit dem freigestellten Icon
- LoginView komplett neu strukturiert als ScrollView:
- Hero: freigestelltes App-Icon (kein SF Symbol mehr) + Titel + Tagline
- Pitch-Karte: vier Feature-Highlights (Gassi-Tracking, Community,
Tagebuch, Giftköder-Alarm) für Leute, die banyaro nicht kennen
- "Schon angemeldet?"-Karte mit dem klassischen Login-Form
- "Neu hier?"-Karte mit kostenlos/DSGVO/DE-Hosting-Pitch und großem
Register-Button mit person.crop.circle.badge.plus-Icon
D.10 401-Handling: APIError.unauthorized, NotificationCenter-Bridge,
AuthSession.logout() bei 401 → User landet wieder im Login
D.12 PWA-Deep-Links: Settings-Section mit Forum/Hunde/Walks/Settings
öffnet Safari per https://banyaro.app/#fragment
B.4 Auto-Pause: 2-min-Inaktivität → isAutoPaused, automatischer Resume bei
nächstem GPS-Update. Settings-Toggle, im UI eigenes Badge "Auto-Pause"
(grau vs. Pause orange).
C.7 Edit/Delete: RouteUpdateBody + APIClient.patch + APIClient.delete,
EditRouteSheet (Name/Beschreibung/Public), Menu in Toolbar (nur eigene
Touren), Alert für Delete.
C.9 Statistik-Tab: neuer Tab "Statistik" zwischen Hunde und Mehr. Filtert
/api/routes auf meine Touren, rechnet Woche/Monat/Allzeit (Distanz, Dauer,
Touren), Längste Tour, aktuelle Streak (Tage in Folge).
B.5 Walk-Review: Map-Header an die Spitze des FinishWalkSheet-Forms.
B.6 Geo-Fotos: CapturedPhoto (Data + GPSPoint?), PhotoLocation @Model in
SwiftData. Kamera während Walk taggt mit tracker.points.last. Nach Upload:
foto_url aus Response → PhotoLocation persistiert. MiniRouteMap rendert
Annotations mit Tap-Callback, PhotoViewerSheet zeigt Foto fullscreen.
C.8 Share PNG+GPX: RouteShareImage (MKMapSnapshotter + Polyline overlay +
SwiftUI ShareCard via ImageRenderer), GPXExporter (Tempfile mit XML),
ShareSheet (UIActivityViewController-Wrapper), Menu in Route-Toolbar.
D.11 Icon-Varianten: AppIcon-Dark (0.45 Brightness), AppIcon-Tinted
(Grayscale + Kontrastverstärkung), Contents.json mit appearance entries.
A.2 HealthKit: BanYaroGo.entitlements (com.apple.developer.healthkit),
NSHealthShare/UpdateUsageDescription. WalkHealthSync.shared mit
HKWorkoutBuilder (.walking) + HKWorkoutRouteBuilder, Timestamps gleichmäßig
über Walk-Dauer verteilt. Settings-Toggle mit Permission-Request.
LocationTracker:
- isPaused, pausedAt, accumulatedPausedSeconds
- pause()/resume()/restore() Methoden
- effectiveElapsedSeconds rechnet Pausen raus
- restore() für nach App-Crash: Offline-Lücke wird als Pause gezählt
ActiveWalk @Model (SwiftData):
- startedAt, lastUpdate, pausedAt, accumulatedPausedSeconds, pointsData
- Container in BanYaroGoApp registriert
TrackingView:
- Persistenz alle 5s via Timer
- confirmationDialog beim Erscheinen wenn ActiveWalk vorhanden:
Fortsetzen / Jetzt speichern / Verwerfen
- Pause/Resume-Button + Stop-Button
- Floating Kamera-Button rechts unten
- Foto-Counter in der Stats-Karte
- Pause-Badge oben links bei Pause
CameraPicker: UIImagePickerController-Wrapper (Fallback auf Library im Simulator).
FinishWalkSheet: initialPhotos: [Data] für Kamera-Fotos während Tour.
RouteDetailView: PhotosPicker zum Hinzufügen von Fotos zu bestehender Tour,
sequentieller Upload mit Progress, Detail wird nach Upload refreshed.
NSCameraUsageDescription in BanYaroGo-Info.plist.
- APIClient.uploadFile: multipart POST mit Bearer-Token, generischer
field/filename/mime
- ImageResize: längste Kante max 2048px, JPEG q=0.8 — iPhone-Fotos sonst
5-10MB pro Stück
- FinishWalkSheet:
- PhotosPicker (iOS 16+, kein NSPhotoLibraryUsageDescription nötig)
- Thumbnail-Strip der gewählten Fotos
- Sequentieller Upload nach POST /api/routes, Toolbar zeigt "N/M"
- Bei < 50m: orangene Warnung "Sehr kurze Tour — du kannst trotzdem speichern"
- Save-Button blockt korrekt während Upload, Verwerfen auch
Das Backend bool-konvertiert nur is_premium explizit; alle anderen 0/1-Spalten
gehen unverändert durch FastAPI. Decode-Fehler vorher still verschluckt → jetzt
auch geloggt, damit das nicht nochmal passiert.
Login liefert nur {token, name, is_premium}. Für Admin-/Founder-/Tier-Info
holen wir nach Login (und beim Erscheinen von MainTabView) /api/auth/me und
zeigen ein echtes Profil mit Avatar, Email, Rolle und nur dann Premium-Status,
wenn das relevant ist.