feat: series-aware schedule edits + waitlist ledger removal (M32)

PATCH /v1/catalog/class-schedules/:id patches a recurring rule and,
with applyToFuture, retimes materialized future sessions to the new
local start time on their existing dates — moving confirmed and
waitlisted bookings with them and re-arming reminders. Zones-page
schedule rows gain an inline editor (CS/EN).

Also drops the vestigial waitlist_entries table (migration 00020):
positions derive from bookings.created_at, so the ledger was written
but never read.

Generated with [Devin](https://devin.ai)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
This commit is contained in:
Tomas DvorakandDevin committed 2026-09-22 20:59:34 +02:00
1 parent 55fc0d06e3
commit 65a693cf38
17 files changed
+840 -230

No files matched your search

+53
View File
@@ -1395,6 +1395,35 @@ paths:
"404":
description: Template or location not found
/v1/catalog/class-schedules/{scheduleID}:
patch:
tags: [Catalog]
operationId: updateClassSchedule
security:
- bearerAuth: []
parameters:
- in: path
name: scheduleID
required: true
schema:
type: string
format: uuid
requestBody:
required: true
content:
application/json:
schema:
$ref: "#/components/schemas/UpdateClassScheduleRequest"
responses:
"200":
description: Updated class schedule
content:
application/json:
schema:
$ref: "#/components/schemas/ClassSchedule"
"400":
description: Invalid request
"404":
description: Class schedule not found
delete:
tags: [Catalog]
operationId: deleteClassSchedule
@@ -3054,6 +3083,30 @@ components:
startsLocal:
type: string
description: Tenant-local start time, HH:MM
UpdateClassScheduleRequest:
type: object
description: >-
Patches a recurring rule; absent fields are kept. locationId set to the
empty string clears the location. When applyToFuture is true and time or
location changed, already-materialized future sessions move to the new
start time (keeping their local date) and location, and their live
bookings follow. A dayOfWeek change only steers sessions materialized
afterwards.
properties:
dayOfWeek:
type: integer
minimum: 0
maximum: 6
startsLocal:
type: string
description: Tenant-local start time, HH:MM
locationId:
type: string
description: Location UUID, or empty string to clear
active:
type: boolean
applyToFuture:
type: boolean
PlanEntitlements:
type: object
required: [maxLocations, maxStaff, emailReminders, advancedReporting, widgetEmbedding, umamiTracking]