fix: pass resolved therapist ID and time slot to Supabase on appointment booking#220
Conversation
|
Warning Rate limit exceeded
Your organization is not enrolled in usage-based pricing. Contact your admin to enable usage-based pricing to continue reviews beyond the rate limit, or try again in 53 minutes and 49 seconds. ⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (1)
📝 WalkthroughWalkthroughAppointment booking now preserves selected time slots and therapist IDs by parsing slot strings into full DateTime timestamps, propagating the resolved timestamp through model/entity conversion, and adding submission guards, booking error state, and therapistId tracking in the provider. Changes
Sequence Diagram(s)sequenceDiagram
participant UI as Client/UI
participant P as AppointmentsProvider
participant R as AppointmentsRepository
participant DB as Supabase/API
UI->>P: schedule request (selectedDate, selectedTimeSlot, service)
P->>P: validate inputs & guard _isSubmitting
P->>P: _parseSlotToDateTime(selectedTimeSlot, selectedDate)
alt parse success
P->>R: createAppointment(therapistId, resolvedDateTime, service, ...)
R->>DB: insert session (timestamp = resolvedDateTime, therapist_id)
DB-->>R: success
R-->>P: success
P->>P: refresh appointments, reset _isSubmitting
P-->>UI: success
else parse failure or validation error
P-->>UI: set bookingError, notify listeners
end
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related PRs
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Pull request overview
Fixes multiple data-integrity issues in the patient appointment booking flow so that bookings sent to Supabase include the resolved therapist ID, the selected time slot (not midnight), and the correct appointment name, while also surfacing booking errors to the UI and preventing duplicate submissions.
Changes:
- Add therapist ID tracking + submission/error state to
AppointmentsProvider, including slot parsing into a fullDateTime. - Ensure
PatientScheduleAppointmentModel.toEntity()uses a localDateTimewhen building the entity timestamp. - Fix
ConsultationRequestEntity.namemapping to useappointmentNameinstead ofserviceType.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 4 comments.
| File | Description |
|---|---|
| patient/lib/provider/appointments_provider.dart | Adds therapist ID propagation, validation + error messaging, submission guard, and slot→DateTime parsing for correct timestamps. |
| patient/lib/model/patient_models/patient_schedule_appointment_model.dart | Updates entity conversion to local time when parsing the timestamp string. |
| patient/lib/core/entities/patient_entities/patient_schedule_appointment_entity.dart | Fixes request mapping to persist the correct appointment name. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
There was a problem hiding this comment.
Actionable comments posted: 3
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@patient/lib/provider/appointments_provider.dart`:
- Around line 45-47: The booking UI must use the provider's exposed state:
change the create appointment screen to read provider.isSubmitting to disable
the submit button (set onPressed to null or show loading) to prevent duplicate
submissions, and read provider.bookingError to display the specific error
message in the form or beneath the button instead of the generic failure text;
update any submit handler to avoid triggering another submit when
AppointmentsProvider.isSubmitting is true and surface
AppointmentsProvider.bookingError in the UI for user-facing errors.
- Around line 135-138: The code sets _therapistId before verifying the fetch
token, which can leave a stale therapist ID if _availableBookingSlots returns
early or fails; modify the logic in the appointments provider so that
_therapistId is only assigned after the token equality check (_fetchToken)
passes and after _availableBookingSlots completes successfully, or ensure you
clear/reset _therapistId on every early return/failure path inside
_availableBookingSlots so stale IDs are never left in state.
- Around line 287-295: The parser currently allows out-of-range 12-hour inputs
like "13:00 PM" or "00:15 AM" because meridiem-specific bounds aren't enforced;
update the validation around parsedHour/parsedMinute and the meridiem flags
(parsedHour, parsedMinute, isPM, isAM) so that if a meridiem is present
(parts.length > 1) the hour must be in 1..12 and otherwise keep the 0..23 check;
return null immediately for invalid meridiem-hour combos before applying the
12->24 conversion (the existing adjustments to hour for isPM/isAM and the final
DateTime(date.year, date.month, date.day, hour, minute) remain the same).
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: ad6a4229-ecb0-4b8e-ae8c-b22105b0a146
📒 Files selected for processing (3)
patient/lib/core/entities/patient_entities/patient_schedule_appointment_entity.dartpatient/lib/model/patient_models/patient_schedule_appointment_model.dartpatient/lib/provider/appointments_provider.dart
…ment, fetchingSlots guard, tighten slot parser, surface ActionResultFailure error message
There was a problem hiding this comment.
Actionable comments posted: 1
♻️ Duplicate comments (1)
patient/lib/provider/appointments_provider.dart (1)
87-90:⚠️ Potential issue | 🟠 MajorClear
_therapistIdon all early/failure paths to prevent stale therapist bookings.Line 137 assigns
_therapistIdonly on success, but Line 87 and Line 117 early returns plus Line 147 catch path do not clear prior state. That can leave an old therapist ID and allow booking against the wrong therapist.Suggested patch
@@ if (currentUser == null) { + _therapistId = ''; availableTimeSlots = []; return; } @@ if (therapistId == null || therapistId.isEmpty) { + _therapistId = ''; availableTimeSlots = []; return; } @@ } catch(e) { print(e); if (token == _fetchToken) { + _therapistId = ''; availableTimeSlots = []; } } finally {Also applies to: 117-120, 137-138, 145-149
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@patient/lib/provider/appointments_provider.dart` around lines 87 - 90, In the appointment loading flow in appointments_provider.dart (the method that sets availableTimeSlots and _therapistId), ensure you clear stale state by assigning _therapistId = null on all early/failure paths: when currentUser is null (the branch that sets availableTimeSlots = []), on any other early-return branches (the path around the check that currently returns before assigning _therapistId), and inside the catch/failure handler that currently only clears availableTimeSlots; set _therapistId = null alongside availableTimeSlots = [] so the provider never retains a stale therapist ID after errors or early exits.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@patient/lib/provider/appointments_provider.dart`:
- Around line 195-205: Before submitting, ensure the currently chosen slot is
still present in the latest available slots: in the booking flow where you check
_selectedTimeSlot, add a validation that _selectedTimeSlot exists in the
collection of availableTimeSlots (e.g., compare by slot id or exact datetime)
and if not set _bookingError to a message like 'Selected time slot is no longer
available.', call notifyListeners(), and return false; apply the same existence
check around the other booking guards that reference
_selectedTimeSlot/_isFetchingSlots (the blocks at 207-211 and 217-223) so you
never proceed with a stale selection.
---
Duplicate comments:
In `@patient/lib/provider/appointments_provider.dart`:
- Around line 87-90: In the appointment loading flow in
appointments_provider.dart (the method that sets availableTimeSlots and
_therapistId), ensure you clear stale state by assigning _therapistId = null on
all early/failure paths: when currentUser is null (the branch that sets
availableTimeSlots = []), on any other early-return branches (the path around
the check that currently returns before assigning _therapistId), and inside the
catch/failure handler that currently only clears availableTimeSlots; set
_therapistId = null alongside availableTimeSlots = [] so the provider never
retains a stale therapist ID after errors or early exits.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 5a2c1c5b-dea2-40af-afa1-987878b2043b
📒 Files selected for processing (1)
patient/lib/provider/appointments_provider.dart
… slot still available before booking
Closes #219
📝 Description
Three separate bugs in the appointment booking flow caused every booking to be written to Supabase with a midnight timestamp, an empty therapist_id, and the wrong name. The selected time slot was captured in the model but toEntity() always called DateTime.parse(date) on a date-only string. therapistId was hardcoded to '' .
name was wired to serviceType instead of appointmentName.
Additionally there were no pre-submission guards - the booking call could fire with a null date, empty slot, or empty therapist ID and either crash or insert garbage. The slot parser had no error handling, so a malformed slot would throw uncaught. The UI had no way to surface what went wrong since catch(e) silently returned false.
🔧 Changes Made
_therapistIdfield populated after the availability fetch, passed correctly into the model instead of hardcoded empty string_bookingErrorfield andbookingErrorgetter so the UI can display specific error messages instead of silently failingisSubmittinggetter so the UI can disable the booking button during an in-flight request_parseSlotToDateTime()helper that safely parses slot strings like "10:00 AM" into a full DateTime, returns null on any malformed input instead of throwingcreateAppointment()now checks the parsed DateTime for null and sets a user facing error instead of crashingname: serviceTypetoname: appointmentNameintoConsultationRequestEntity()so the correct appointment name is stored.toLocal()intoEntity()so the timestamp is stored in local timeclearSelections()now resets_therapistId,_isSubmitting, and_bookingErroralongside existing fields📷 Screenshots or Visual Changes (if applicable)
Not applicable. The fix is in data written to Supabase, not visible in the UI.
🤝 Collaboration
Collaborated with: NONE
✅ Checklist
Summary by CodeRabbit
Bug Fixes
Improvements