screen-locker/stronglift_replacement/workout_app/lib/services
Krzysztof kuhy Rudnicki 81ebccb51a
Some checks are pending
md-naming / markdown naming convention (push) Waiting to run
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
Stop the phone counting deleted and empty manual workouts
The app said "manual budget exhausted for this window" (2/2w, 4/10m) while
the PC read 1/2w, 2/10m for the same records. The PC was right; two
independent Dart defects each inflated a window by one.

`_readMergedPayloads` never looked at `Record.deleted`, so the tombstoned
duplicate `manual:2026-08-21T21:00` -- the second of two logged on 08-21,
already deleted -- kept consuming a weekly slot. Suppression is collected
across the whole device union and applied after the merge, not per file:
one device tombstoning a record while another still holds it live must
delete it, and a per-file skip would just let the live copy win. This
mirrors the PC's `_tombstoned_ids`.

`countManualBudget` also counted `manual_workout:2026-08-15`, a bare
`{type, kind, date}` stub with no evidence fields. The PC refuses to ingest
those ("no workout data to ingest; skipping permanently"), so the phone was
charging budget for a workout neither device ever accepted. The filter lives
in the counter rather than the shared reader because `runnerup_verified` and
`pc_workout_verified` payloads legitimately carry no `start_time`, and the
history view must keep showing them.

Covered by a shared literal fixture both languages read, rather than two
independent round-trips: each side's own tests passed while the pair
disagreed, which is exactly how this shipped. Verified by reverting each
guard in turn and watching the twin fail.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AWq9MRemX9ZWvNmnhNWUP2
2026-08-27 20:13:12 +02:00
..
backup_service_session.dart Split backup_service.dart; partly split workout_sync_service.dart 2026-08-15 21:38:42 +02:00
backup_service.dart Split backup_service.dart; partly split workout_sync_service.dart 2026-08-15 21:38:42 +02:00
firebase_backend_desktop.dart Run the workout app on Linux, and let it hold the screen lock 2026-08-22 11:18:48 +02:00
firebase_backend_google.dart Run the workout app on Linux, and let it hold the screen lock 2026-08-22 11:18:48 +02:00
firebase_backend.dart Run the workout app on Linux, and let it hold the screen lock 2026-08-22 11:18:48 +02:00
github_device_auth.dart Carry progression through Firebase, and stop demanding storage permission 2026-08-10 16:54:21 +02:00
google_platform_io.dart workout_app: add Google sign-in support for the Firebase sync account 2026-08-14 10:56:16 +02:00
google_platform_web.dart workout_app: add Google sign-in support for the Firebase sync account 2026-08-14 10:56:16 +02:00
google_platform.dart workout_app: add Google sign-in support for the Firebase sync account 2026-08-14 10:56:16 +02:00
google_sign_in_backend.dart workout_app: add Google sign-in support for the Firebase sync account 2026-08-14 10:56:16 +02:00
http_server_service.dart Carry progression through Firebase, and stop demanding storage permission 2026-08-10 16:54:21 +02:00
lock_mode.dart Run the workout app on Linux, and let it hold the screen lock 2026-08-22 11:18:48 +02:00
progression_sync_service_pull.dart Split progression_sync_service.dart (433) into four 2026-08-15 21:44:43 +02:00
progression_sync_service_push.dart Split progression_sync_service.dart (433) into four 2026-08-15 21:44:43 +02:00
progression_sync_service_session.dart Split progression_sync_service.dart (433) into four 2026-08-15 21:44:43 +02:00
progression_sync_service.dart Split progression_sync_service.dart (433) into four 2026-08-15 21:44:43 +02:00
storage_service_backup.dart Split storage_service.dart (781) into part extensions 2026-08-15 21:12:08 +02:00
storage_service_exercises.dart Split storage_service.dart (781) into part extensions 2026-08-15 21:12:08 +02:00
storage_service_schema.dart Run the workout app on Linux, and let it hold the screen lock 2026-08-22 11:18:48 +02:00
storage_service_sessions.dart Split storage_service.dart (781) into part extensions 2026-08-15 21:12:08 +02:00
storage_service.dart Run the workout app on Linux, and let it hold the screen lock 2026-08-22 11:18:48 +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 Carry progression through Firebase, and stop demanding storage permission 2026-08-10 16:54:21 +02:00
sync_settings.dart Carry progression through Firebase, and stop demanding storage permission 2026-08-10 16:54:21 +02:00
sync_state_factory.dart Sync workouts through Firebase, mirroring to GitHub during the cutover 2026-08-05 08:12:40 +02:00
sync_status.dart Add sync-status card and duration-threshold fixture 2026-08-15 18:41:31 +02:00
workout_sync_service_read.dart Stop the phone counting deleted and empty manual workouts 2026-08-27 20:13:12 +02:00
workout_sync_service.dart Stop the relaxed-day popup from re-firing every 30 minutes after Skip 2026-08-18 21:55:59 +02:00
workout_sync_session.dart Extract WorkoutSyncSession from workout_sync_service.dart (322 -> 218) 2026-08-15 22:28:02 +02:00