screen-locker/stronglift_replacement/workout_app/lib/services
Krzysztof kuhy Rudnicki 4095e0ae5d
Some checks are pending
pre-commit / pre-commit (push) Waiting to run
Tests / test (3.10) (push) Waiting to run
Tests / test (3.11) (push) Waiting to run
Tests / test (3.12) (push) Waiting to run
Tests / lock-popup-safety (push) Waiting to run
release-apk / release (APK) (push) Waiting to run
Report a failed workout push instead of hiding it in debugPrint
A workout completed on 2026-08-09 never reached the sync repo and nothing
anywhere said why. The cause was structural: workout_screen.dart fired
`unawaited(WorkoutSyncService().push(session))` and `push()` caught ONLY
GitHubSyncError, reporting it via `debugPrint` -- which goes nowhere in a
release build. A Firebase error, an auth failure, a dropped connection or a
backgrounded app all produced exactly that symptom: silence.

This repo's CLAUDE.md already forbids it in as many words ("an invisible log
is a silent failure with extra steps", "return something meaningful"), so
this brings the Dart side up to the contract the Python side already meets
with `_manual_push.PushResult`.

- push()/pushManual() return a PushResult(pushed, reason) instead of void.
- The catch is deliberately broad, and logs at level 1000 (error) with the
  stack trace via dart:developer, not debugPrint.
- Still never rethrows: a sync failure must not cost the user their finished
  workout. The caller stays unawaited so a slow backend can't delay the
  summary dialog, but it now logs when the push did not happen.

Tests assert the reason, not just that the future completes -- the old test
("a GitHubSyncError is swallowed, not rethrown") would have passed against
the broken behaviour.

Note this does NOT explain the 2026-08-09 miss retroactively: that session
ran at 12:35 UTC on the pre-migration build, ~3h before the new APK was
installed, so its failure is unrecoverable. It is in Firebase anyway via the
PC's independent verification (phone_verified:2026-08-09, "68 min, partial").
This makes the next one diagnosable.

314 tests, analyzer clean.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GZH89WEqAjuJT8WZdqc7AP
2026-08-09 18:50:48 +02:00
..
backup_service.dart Mirror the in-progress session so an app-data wipe can't lose your set 2026-07-17 09:57:54 +02:00
firebase_backend.dart Sync workouts through Firebase, mirroring to GitHub during the cutover 2026-08-05 08:12:40 +02:00
github_device_auth.dart Add phone-workout GitHub sync via shared crdt_sync (Workstream C) 2026-07-11 00:06:59 +02:00
http_server_service.dart Cover services + app bootstrap toward 100% flutter coverage 2026-07-13 13:27:18 +02:00
storage_service.dart Mirror the in-progress session so an app-data wipe can't lose your set 2026-07-17 09:57:54 +02:00
sync_device_id.dart Push under a persisted per-install uuid, not a fixed role id 2026-08-09 17:31:15 +02:00
sync_service.dart Fix flutter analyze infos for the push gate 2026-07-13 14:28:45 +02:00
sync_settings.dart Recover the sync token from backup when the stored one is rejected 2026-07-17 09:45:12 +02:00
sync_state_factory.dart Sync workouts through Firebase, mirroring to GitHub during the cutover 2026-08-05 08:12:40 +02:00
workout_sync_service.dart Report a failed workout push instead of hiding it in debugPrint 2026-08-09 18:50:48 +02:00