Skip to content

Reschedule proposals cannot be answered: accept/decline/counter were never built and the consultee never sees the proposal #1163

Description

@teetangh

Summary

The reschedule-proposal system shipped one-sided. RescheduleRequestStatus defines ACCEPTED, DECLINED, and COUNTERED, and the transition map allows them (lib/booking/transitions.ts:186-200) — but no user-facing endpoint or surface lets the counterparty answer a proposal. This was never built and then lost; the git history shows #1064 shipped withdraw + auto-confirm and stopped there.

Evidence

transitionRescheduleRequest has exactly three production callers: the allocator writes ACCEPTED as a side-effect of the consultant allocating against the request (utils/slotAllocation/SlotAllocationService.ts:636-639), auto-confirm writes AUTO_ACCEPTED (lib/booking/reschedule-auto-confirm.ts:108-115), and withdraw writes WITHDRAWN. The only DECLINED writer in the codebase is the cancel route closing proposals as a side-effect of booking cancellation — and it does so via a raw updateMany that bypasses the CAS helper entirely (app/api/appointments/[appointmentId]/cancel/route.ts:367-377). COUNTERED is written by nothing except seed data.

The consequences compound on both sides of the journey:

  • After a consultant proposes times, the toast says "The consultee has been asked to accept the new time" (useConsultantEventActions.ts:106-111) — but the consultee's queries never include rescheduleRequests (the sole include is the consultant-inbox select at lib/booking/list-selects.ts:58), so the consultee sees only "Awaiting schedule confirmation" and can never respond. Both parties wait for an answer that cannot arrive; the proposal can only expire (≤72h) or be withdrawn.
  • The withdraw endpoint itself (POST /api/appointments/[appointmentId]/reschedule/withdraw) has zero UI callers — a released booking cannot be retracted from any surface.
  • In the consultant inbox, a displayed consultee proposal has no accept affordance: "Use Requested Times" is suppressed whenever released slots exist (components/dashboard/shared/requests/RequestSlotAllocationTab.tsx:1071), so the consultant must manually re-find the proposed time on the grid.

Fix direction

Build the response loop: accept/decline (and counter) endpoints beside the existing withdraw route, CAS transitions for all three statuses (including fixing the cancel route's raw updateMany), a consultee-facing proposal surface with accept/decline affordances, wiring for the orphaned withdraw UI, and the inbox accept path. Lands in the booking + maintenance productionization train (wave 2, lifecycle PR).

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bookingBooking, scheduling, slots, reschedule, cancellationbugSomething isn't workinglaunch: pre-mvpGates launch — money, data, or a failure we would not detect

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions