mirror of
https://github.com/Dvorinka/Bookra.git
synced 2026-10-28 15:51:15 +00:00
feat(bookings): customer self-service rebooking with real slot picker
CustomerBookingView now carries tenantSlug/serviceId/staffId/ classSessionId so the manage page can query live availability; class bookings resolve their session title as the display label. Reschedule rejects waitlisted/completed bookings and session-bound class bookings (400), collapsing a dead branch in the appointment path. The manage page reschedule dialog replaces free-form date/time inputs with a date → availability-slot picker filtered to appointment mode, so customers can only move to a genuinely free slot with the correct duration; 409 surfaces "slot just taken". Actions are status-gated: reschedule for confirmed/pending appointments, cancel for live bookings, explanatory note for class bookings. Generated with [Devin](https://devin.ai) Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
This commit is contained in:
1 parent
1cd5b1ba91
commit
796c06ae66
7 files changed
+311
-87
No files matched your search
@@ -346,6 +346,10 @@ paths:
|
||||
responses:
|
||||
"200":
|
||||
description: Booking details
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/CustomerBookingView"
|
||||
"403":
|
||||
description: Invalid manage token
|
||||
"404":
|
||||
@@ -360,29 +364,37 @@ paths:
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
- in: query
|
||||
name: token
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
description: Manage token issued at booking time
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
required: [token, startsAt]
|
||||
required: [newStartsAt, newEndsAt]
|
||||
properties:
|
||||
token:
|
||||
type: string
|
||||
startsAt:
|
||||
newStartsAt:
|
||||
type: string
|
||||
format: date-time
|
||||
endsAt:
|
||||
newEndsAt:
|
||||
type: string
|
||||
format: date-time
|
||||
reason:
|
||||
type: string
|
||||
responses:
|
||||
"200":
|
||||
description: Booking rescheduled
|
||||
"400":
|
||||
description: Invalid new window, non-reschedulable status, or class booking
|
||||
"403":
|
||||
description: Invalid manage token
|
||||
"409":
|
||||
description: New slot conflicts
|
||||
description: New slot conflicts or booking already cancelled
|
||||
/v1/public/bookings/{reference}/cancel:
|
||||
post:
|
||||
tags: [Public Booking]
|
||||
@@ -1770,6 +1782,46 @@ components:
|
||||
waitlistPosition:
|
||||
type: integer
|
||||
description: 1-based queue spot for waitlisted class bookings; absent otherwise
|
||||
CustomerBookingView:
|
||||
type: object
|
||||
properties:
|
||||
reference:
|
||||
type: string
|
||||
customerName:
|
||||
type: string
|
||||
customerEmail:
|
||||
type: string
|
||||
service:
|
||||
type: string
|
||||
businessName:
|
||||
type: string
|
||||
tenantSlug:
|
||||
type: string
|
||||
serviceId:
|
||||
type: string
|
||||
format: uuid
|
||||
staffId:
|
||||
type: string
|
||||
format: uuid
|
||||
classSessionId:
|
||||
type: string
|
||||
format: uuid
|
||||
description: Present for session-bound bookings, which cannot be rescheduled to arbitrary times
|
||||
startsAt:
|
||||
type: string
|
||||
format: date-time
|
||||
endsAt:
|
||||
type: string
|
||||
format: date-time
|
||||
location:
|
||||
type: string
|
||||
status:
|
||||
type: string
|
||||
notes:
|
||||
type: string
|
||||
waitlistPosition:
|
||||
type: integer
|
||||
description: 1-based queue spot for waitlisted class bookings; absent otherwise
|
||||
DashboardBookingRequest:
|
||||
type: object
|
||||
required: [customerName, customerEmail, startsAt]
|
||||
|
||||
Reference in new issue
Block a user