Skip to content

refactor(mobile): full-sync ratings on startup, SSE only for updates - #46

Merged
cafca merged 5 commits into
mainfrom
claude/pensive-mayer-a8a405
Apr 23, 2026
Merged

refactor(mobile): full-sync ratings on startup, SSE only for updates#46
cafca merged 5 commits into
mainfrom
claude/pensive-mayer-a8a405

Conversation

@cafca

@cafca cafca commented Apr 23, 2026

Copy link
Copy Markdown
Owner

Summary

Mobile was refetching /api/ratings?bbox=… on every onCameraIdle — every pan and zoom hit the network. Swap to:

  • Startup + auth transitions: one full sync over a fixed Berlin bbox (kBerlinSyncBbox, ~5km padding around the Berlin ring).
  • Ongoing updates: SSE invalidate only. Every invalidate refetches the same full bbox.
  • No camera-idle fetching. Panning never touches the network.

If SSE is unavailable (client kill-switch off or server 404s /api/ratings/events), the overlay goes stale until next app start. A one-shot SnackBar tells the user.

Backend unchanged — same /api/ratings?bbox=… endpoint.

Changes

  • mobile/lib/config/berlin_bounds.dart — new; Bbox type + kBerlinSyncBbox constant.
  • mobile/lib/providers/rating_overlay_provider.dart — gutted. Notifier<RatingOverlayState> with a liveSyncDegraded flag. Camera probe / onCameraIdle / _lastFetched / fetch-policy all gone.
  • mobile/lib/services/rating_events_client.dart — new onServerDisabled callback fires once when 404 latches, so the controller can surface the degraded state.
  • mobile/lib/screens/map_screen.dart — removed the onCameraIdle call into the rating overlay; added a ref.listen that shows a SnackBar when liveSyncDegraded flips true.
  • Deleted mobile/lib/services/rating_fetch_policy.dart + its test (viewport expansion, safe-inner dedup, min-zoom gate — all dead with camera-idle gone).
  • Rewrote rating_overlay_controller_test.dart around the new sync model.

Known follow-up

SSE reliability issue ("doesn't work" on device) is not addressed here — tracked as a separate task. This PR only changes when/how syncs are triggered.

Test plan

  • just test-mobile — 113 passed, analyzer clean.
  • just preview (worktree) + just dev-ios-sim, signed-in:
    • Cold start: exactly one GET /api/ratings?bbox=12.9,52.25,13.9,52.75.
    • Pan/zoom around Berlin repeatedly → zero additional /api/ratings requests.
    • Paint via web while signed in as same user → SSE invalidate → one refetch, overlay updates without user pan.
    • Sign out → overlay clears, no fetch. Sign in as different user → one fetch.
  • Flip BEEBEEBIKE_RATINGS_SSE_ENABLED=false, restart backend + app → one startup fetch, SSE 404s, toast appears once, no further fetches.
  • Build with --dart-define=BEEBEEBIKE_RATINGS_SSE_ENABLED=false → startup fetch, no SSE attempt, toast on first map load.

cafca added 5 commits April 23, 2026 02:49
Mobile was refetching /api/ratings?bbox=… on every onCameraIdle (every
pan/zoom). Swap for a single full-sync fetch over a fixed Berlin bbox at
attach + auth-change, and rely on the existing SSE channel for updates.
Panning no longer hits the network.

- New `kBerlinSyncBbox` covers Berlin + ~5km padding; reused for startup
  sync and every SSE invalidate refetch.
- Deleted rating_fetch_policy (viewport expansion, safe-inner dedup,
  min-zoom gate) — all dead with camera-idle gone.
- RatingOverlayController now exposes RatingOverlayState with a
  liveSyncDegraded flag that flips true when SSE is off (client flag or
  server 404). Map screen shows a one-shot SnackBar so users know their
  paintings only sync on app start until they relaunch.
- RatingEventsClient gains an onServerDisabled callback so the 404 latch
  propagates to the UI without polling.
…a8a405

# Conflicts:
#	mobile/lib/screens/map_screen.dart
@cafca
cafca merged commit 7dc59bc into main Apr 23, 2026
7 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant