Appointments API
Appointment action endpoint: confirm/reject/cancel/paid/complete/no_show
Appointments API
This page details the appointment action endpoint, which allows clients and professionals to perform state-changing actions on appointments via a PATCH request. Supported actions include confirm, reject, cancel, paid, complete, and no_show.
Overview of Actions
The endpoint processes actions defined in the ALLOWED_ACTIONS set in src/app/api/appointments/[id]/route.ts:10. These are:
confirmrejectcancelpaidcompleteno_show
Requests with an action not in this set return 400 Bad Request if the user is associated with the appointment, or 403 Forbidden otherwise. The check occurs after ownership resolution to avoid leaking existence via error codes.
Cancel Action
The cancel action can be initiated by either the client or the professional. It updates the appointment's status to cancelled in the appointments table.
Precondition Check
Cancellation is only allowed if the current status is pending_confirmation or confirmed (src/app/api/appointments/[id]/route.ts:70). Attempts to cancel in other states (e.g., completed, cancelled) result in a 400 Bad Request.
Notifications
- Client cancellation: A notification is inserted into the
notificationstable for the professional, and WhatsApp messages are sent to both parties. - Professional cancellation: A WhatsApp message is sent to the client (
msgCancelledByProToClient) and to the professional (msgBookingCancelled).
Implementation: src/app/api/appointments/[id]/route.ts:72–88.
Professional-Only Actions
The following actions are restricted to the professional (professional.userId === user.id). Unauthorized attempts return 403 Forbidden.
Paid
- Updates
paymentStatustocaptured. - Sends WhatsApp messages to both client (
msgPaymentConfirmedToClient) and professional (msgPaymentConfirmedToPro). - No precondition check on current
paymentStatusorstatus.
Complete
- Updates
statustocompleted. - Sends WhatsApp messages to both parties (
msgAppointmentCompletedToClient,msgAppointmentCompletedToPro). - No precondition check on current
status.
No Show
- Updates
statustono_show. - Sends WhatsApp messages to both parties (
msgNoShowToClient,msgNoShowToPro). - No precondition check on current
status.
All three actions are handled in sequence after the isProfessional check (src/app/api/appointments/[id]/route.ts:90–115).
Confirm and Reject Actions
These actions are restricted to the professional and modify both status and paymentStatus:
confirm→status: confirmed,paymentStatus: authorizedreject→status: rejected,paymentStatus: refunded
Notifications
- A database notification is inserted for the client if
client.userIdexists. - WhatsApp messages are sent to both parties.
- For confirmed appointments, an email is sent to the client if
client.emailis present.
Messages used: msgBookingConfirmed, msgBookingConfirmedReceipt, msgBookingRejected, msgBookingRejectedReceipt. Email functions: sendBookingConfirmedEmailToClient, sendBookingRejectedEmailToClient.
Implementation: src/app/api/appointments/[id]/route.ts:117–150.
Implementation Details
The endpoint is a PATCH handler in src/app/api/appointments/[id]/route.ts. Key steps:
- Authentication:
getUser()verifies session. - Data Fetching: Retrieves appointment, professional, and client using Drizzle ORM.
- Ownership Check: Determines if user is client or professional via
userIdmatch. - Action Validation: Ensures
actionis inALLOWED_ACTIONS. - Action Execution: Branches by action, updates database, and dispatches notifications.
All WhatsApp messages are sent asynchronously using sendWhatsApp, with context metadata for tracking.
Known Gaps
The paid, complete, and no_show actions lack precondition checks on the appointment's current status or paymentStatus. This allows illogical transitions, such as marking a cancelled appointment as completed or setting paymentStatus to captured on an already refunded record. In contrast, the cancel action explicitly validates prior state (src/app/api/appointments/[id]/route.ts:70), indicating a deliberate check was possible but not applied uniformly.
Why this Shape
The endpoint consolidates all appointment state transitions into a single PATCH interface to minimize API surface area. This reduces client complexity and centralizes business logic for auditability. The sequential branching structure ensures mutual exclusivity of actions, while early ownership and validation checks prevent unauthorized or malformed requests from progressing. The pattern of updating state followed by side effects (notifications) is consistent across actions, improving maintainability.