Is there an existing issue for this?
What happened?
📌 Issue Overview
When a patient checks off daily activities as completed, the checkbox toggles only update local in-memory state and are never written to Supabase. All progress is silently lost the moment the user navigates away, switches dates, or restarts the app.
Three interacting defects cause this:
-
toggleTaskCompletion() in task_provider.dart only mutates _allTasks in memory and calls notifyListeners(). It never calls updateActivityCompletion(). The method is marked async but contains no await and is effectively synchronous.
-
The only fallback save path was explicitly commented out in daily_activities_screen.dart:
// context.read().updateActivityInBackground(); // TODO: Uncomment this when the backend is ready
The method updateActivityInBackground does not even exist on TaskProvider, it was never implemented.
updateActivityCompletion() is only called inside setSelectedDate(), meaning the only time data is saved is when the user switches the date picker to a different day. If the user checks activities and presses back without changing dates, nothing is saved. This also introduces a race condition since getTodayActivities() is called immediately
after, potentially overwriting unsaved state with a fresh DB read.
The screen has no PopScope, no WillPopScope, no AppLifecycleObserver, and no
dispose() save logic. There is zero mechanism to flush pending changes on any form of exit.
🔍 Steps to Reproduce
- Log in as a patient who has daily activities assigned
- Navigate to Home → Daily Activities
- Wait for activities to load
- Check 2 or more activity checkboxes - observe they toggle visually
- Press the back arrow to return to home
- Navigate back to Daily Activities
- All checkboxes are unchecked, all progress is lost
- Alternatively: check activities, kill and restart the app, same result
🎯 Expected Behavior
Each checkbox toggle should persist the is_completed state to the daily_activity_logs table in Supabase immediately or on a short debounce. Navigating away and back should restore the previously checked state from the database.
🚨 Actual Behavior
No Supabase call is made on checkbox toggle. The in-memory state is discarded on navigation. The daily_activity_logs table never reflects actual patient completions, which means:
- The Reports screen always shows activities as incomplete
- Therapists see 0% completion for activities the patient believes they completed
- Patient therapy progress data is silently corrupted
📷 Screenshot
Not applicable. The bug is in data not written to Supabase, not visible in the UI.
💡 Suggested Improvements
task_provider.dart:
- Add a
Timer? _debounceTimer field
- In
toggleTaskCompletion(), after mutating _allTasks, start a 1.5s debounce timer that calls updateActivityCompletion(_allTasks)
- Add a
Future<void> saveAndFlush() method that cancels the timer and immediately
awaits updateActivityCompletion(_allTasks) for use on screen exit
daily_activities_screen.dart:
- Wrap the
Scaffold in a PopScope with onPopInvokedWithResult calling taskProvider.saveAndFlush() before allowing pop
- Add
WidgetsBindingObserver and implement didChangeAppLifecycleState to call saveAndFlush() on AppLifecycleState.paused
- Remove the commented-out
updateActivityInBackground line
supabase_patient_repository.dart:
- No changes needed.
updateActivityCompletion() is correctly implemented, it is just never called from the right place
Record
Is there an existing issue for this?
What happened?
📌 Issue Overview
When a patient checks off daily activities as completed, the checkbox toggles only update local in-memory state and are never written to Supabase. All progress is silently lost the moment the user navigates away, switches dates, or restarts the app.
Three interacting defects cause this:
toggleTaskCompletion()intask_provider.dartonly mutates_allTasksin memory and callsnotifyListeners(). It never callsupdateActivityCompletion(). The method is markedasyncbut contains noawaitand is effectively synchronous.The only fallback save path was explicitly commented out in
daily_activities_screen.dart:// context.read().updateActivityInBackground(); // TODO: Uncomment this when the backend is readyThe method
updateActivityInBackgrounddoes not even exist onTaskProvider, it was never implemented.updateActivityCompletion()is only called insidesetSelectedDate(), meaning the only time data is saved is when the user switches the date picker to a different day. If the user checks activities and presses back without changing dates, nothing is saved. This also introduces a race condition sincegetTodayActivities()is called immediatelyafter, potentially overwriting unsaved state with a fresh DB read.
The screen has no
PopScope, noWillPopScope, noAppLifecycleObserver, and nodispose()save logic. There is zero mechanism to flush pending changes on any form of exit.🔍 Steps to Reproduce
🎯 Expected Behavior
Each checkbox toggle should persist the
is_completedstate to thedaily_activity_logstable in Supabase immediately or on a short debounce. Navigating away and back should restore the previously checked state from the database.🚨 Actual Behavior
No Supabase call is made on checkbox toggle. The in-memory state is discarded on navigation. The
daily_activity_logstable never reflects actual patient completions, which means:📷 Screenshot
Not applicable. The bug is in data not written to Supabase, not visible in the UI.
💡 Suggested Improvements
task_provider.dart:Timer? _debounceTimerfieldtoggleTaskCompletion(), after mutating_allTasks, start a 1.5s debounce timer that callsupdateActivityCompletion(_allTasks)Future<void> saveAndFlush()method that cancels the timer and immediatelyawaits
updateActivityCompletion(_allTasks)for use on screen exitdaily_activities_screen.dart:Scaffoldin aPopScopewithonPopInvokedWithResultcallingtaskProvider.saveAndFlush()before allowing popWidgetsBindingObserverand implementdidChangeAppLifecycleStateto callsaveAndFlush()onAppLifecycleState.pausedupdateActivityInBackgroundlinesupabase_patient_repository.dart:updateActivityCompletion()is correctly implemented, it is just never called from the right placeRecord