Choose the correct operation
Consultant-prompted rescheduling
- The owning consultant calls
POST /sessions/:id/request-reschedulewith no body. The session must bemissed, its booking must not be cancelled, rescheduling must be enabled, and the configured positive reschedule limit must not be exhausted. A pending reschedule payment or missing booked student also prevents prompting. Admin status alone does not grant permission to send the prompt. - The backend triggers email and in-app notifications to the booked student.
Notification data includes
sessionId,consultationId, and actionSESSION_RESCHEDULE_REQUESTED. The frontend opens the rescheduling UI for that session and refetches its state. - The student submits a replacement
newStartTimetoPOST /sessions/:id/reschedule. The consultant cannot select a time on the student’s behalf through this endpoint. The student does not need to receive a prompt before rescheduling an eligible session. - With no fee, the backend applies the new dates immediately. With a fee, it returns
payment information and marks the session
pending_payment; dates change only after backend payment processing succeeds. Once applied, the session isrescheduled. - The owning consultant or an admin calls
POST /sessions/:id/approve-reschedule. This changesrescheduledtoscheduledand attempts a student approval notification. Approval does not select or apply another time. There is no reschedule-rejection endpoint or automatic restoration of the previous time in this flow.
Rules and side effects
- Sending a prompt does not modify dates, status, attendance, payment, or the reschedule count. It does not reserve a slot or waive fees or cooldowns.
- Repeated successful prompt requests send repeated notifications. There is no prompt-specific deduplication; disable the action while submitting and do not blindly retry an ambiguous network error.
- The reschedule endpoint accepts
upcoming,scheduled,rescheduled, andmissed. Minimum notice for a missed session is measured against the replacement start time. For the other eligible statuses, notice is measured against the original start time. - The backend checks future time, availability, ownership, reschedule limits, pending payments, and cooldowns. Missed sessions additionally require enabled rescheduling and a non-cancelled booking.
- Applying the replacement time resets attendance timestamps and
bothPartiesJoined, updates the session’s date and end time, replaces reminder/status/finalization jobs, and triggers rescheduling notifications for both participants. - Session statuses are lowercase. The separate reschedule-record statuses are
uppercase, such as
PENDING_PAYMENTandCOMPLETED.
Rebooking the consultation
Use the existingPRODUCT_PURCHASE flow through POST /orders, directly or after
adding the consultation to the cart. Keep the consultation ID and recipient and
supply the newly selected date/time. No rebook flag or new endpoint is required.
Current pricing and availability apply; do not reuse an earlier order/payment reference
or submit a RESCHEDULE_FEE order for another purchase.
A prior consultation enrollment does not block another purchase, even when the prior
booking is still active. Courses keep their existing duplicate-purchase checks. The
same consultation cannot be added twice to a single cart; this change permits a new
purchase, not duplicate entries within one cart.
The backend rechecks cart slots at checkout because availability can change after
insertion. Self-booking and inactive-product checks remain in place. Fulfillment
links each new session to the enrollment for its own order, rather than an earlier
enrollment for the same student and consultation. Processing the same order item
again must not create another booking or credit.
For recurring consultations, the purchase creates a new session set using the
configured recurrence. If explicit metadata.requestedStartTimes are supplied, they
must contain the replacement purchase’s dates rather than old session dates.
Frontend integration responsibility
GET /enrollment/check/:productType/:productId returns isEnrolled and canPurchase.
For consultations, both can be true. The frontend must use canPurchase to gate the
booking action, scheduling page, and checkout. Existing clients that block whenever
isEnrolled is true will continue to prevent rebooking until updated.
Purchase eligibility is not a reservation or an availability guarantee. Enrollment
information keeps its existing meaning; the backend does not hide old enrollments
just to enable checkout. Read these fields from HTTP data unless the API client
already unwraps the standard response envelope.
Sources of truth and verification
Detailed request/response contracts belong in the separate API documentation: Their source files aredocs/flows/reschedule_flow.mdx and
docs/flows/booking_frontend_integration.mdx in the sibling API docs repository.
Published pages reflect these changes only after that repository is deployed.
Backend implementation references (paths within the server repository):
src/consultation/sessions.controller.tsandsessions.service.ts: prompt, reschedule, approval, attendance, and completion.src/cart/cart.service.tsandsrc/order/order.service.ts: repeat purchases and checkout validation.src/consultation/consultation.service.ts: separate booking/session fulfillment and order-scoped enrollment linking.src/enrollment/enrollment.controller.ts: purchase-eligibility response.