feat(scheduling): caregiver availability and time-off requests - #191
Merged
Conversation
Caregivers had no way to tell their agency when they can work or when they need a day off, and scheduling had no way to know. Both were happening over text messages and getting lost. Two tables rather than one, because they mean different things to a scheduler and are deliberately weighted differently: Declared availability is a PREFERENCE. Booking outside it produces a warning and goes through. Agencies cover shifts outside someone's usual window constantly, and a hard block would simply be worked around by editing the availability, which makes the data worse rather than the schedule better. Approved time off is a COMMITMENT. Scheduling refuses to book over it, as a hard conflict alongside double-booking. Approving somebody's leave and then putting them on the shift anyway is how an agency loses staff. Only approved requests count: one nobody has answered yet must not block a schedule the agency never agreed to. The two lookups also fail differently, on purpose. The time-off read is not wrapped: if the leave calendar cannot be read we cannot honestly say there is no conflict, so the booking fails rather than risking a double-booked day off. The availability read degrades to no warning, because an advisory that cannot be computed must not block a booking the agency is entitled to make. Reasons stay private. A time-off reason may name a medical or family situation, so it is never echoed into the scheduling conflict message, the notification body, or an audit payload; the block says only that approved leave covers the date. Caregivers manage their own week and requests from the mobile app; staff approve or deny from new Mileage-style review pages. Review only matches still-pending rows, so a second reviewer cannot overturn the first answer. A caregiver may cancel their own request even after approval, because plans change and giving a day back should not need an awkward phone call.
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
Caregivers had no way to tell their agency when they can work or when they need a day off, and scheduling had no way to know. Both were happening over text messages and getting lost.
Two tables, two weights
They mean different things to a scheduler, so they are stored and treated separately:
Declared availability is a PREFERENCE. Booking outside it produces a warning and goes through. Agencies cover shifts outside someone's usual window constantly, and a hard block would simply be worked around by editing the availability, which makes the data worse rather than the schedule better.
Approved time off is a COMMITMENT. Scheduling refuses to book over it, as a hard conflict alongside double-booking. Approving somebody's leave and then putting them on the shift anyway is how an agency loses staff. Only approved requests count: one nobody has answered yet must not block a schedule the agency never agreed to.
The two lookups fail differently, on purpose
The time-off read is deliberately not wrapped. If the leave calendar cannot be read we cannot honestly say there is no conflict, so the booking fails rather than risking a double-booked day off.
The availability read degrades to no warning. An advisory that cannot be computed must not block a booking the agency is entitled to make.
This is the opposite call from the mileage PR's owner lookup, and for the opposite reason: that one guarded a courtesy, this one guards a commitment.
Reasons stay private
A time-off reason may name a medical or family situation. It is never echoed into the scheduling conflict message, the notification body, or an audit payload; the block says only that approved leave covers the date. There's a test asserting the reason does not appear in the 409 body.
Workflow
Caregivers manage their weekly pattern and requests from the mobile app (Me → Availability & Time Off). Staff approve or deny from a new Time Off page. Review only matches still-pending rows, so a second reviewer cannot overturn the first answer. A caregiver may cancel their own request even after approval, because plans change and giving a day back should not need an awkward phone call; it is marked cancelled rather than deleted so the agency can see what happened.
The weekly editor holds one window per day. Split shifts are real but uncommon, and a repeating add/remove UI on a phone is fiddly enough that most people would abandon it. Storage and the API accept several windows per day, so a richer editor lands later without a migration, and a caregiver who already has split windows keeps them until they edit that day.
Migration
2026-08-04-add-availability-and-time-off, two new tables. Needs applying to prod. Note that until it is applied, the time-off lookup in assignment checks will throw, and because that check fails closed, assignment creation with a visit date will 500. This one must go out with the deploy, not after it.Tests
47 new: availability window matching including split windows and the gap between them, weekday derivation that is not thrown off by timezone interpretation of a bare date, grid round-tripping, approved leave blocking a booking, reason absent from the 409 body, availability warning that still books, caregiver-cannot-approve-own, already-answered 404s, cancellation from approved. All four suites pass, plus typecheck, lint,
sql:scan,security:scan.Not included
Partial-day leave. An agency that needs it can approve a day and schedule around it, which is honest, rather than have a half-supported hours field that scheduling ignores.