mirror of
https://github.com/Dvorinka/Bookra.git
synced 2026-10-28 15:51:15 +00:00
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:
1 parent
55fc0d06e3
commit
65a693cf38
17 files changed
+840
-230
No files matched your search
@@ -369,19 +369,19 @@ func NewServer(cfg config.Config, pools *db.Pools) (*Server, error) {
|
||||
|
||||
server.router.POST("/v1/public/bookings", publicRateLimiter.Middleware(), func(c *gin.Context) {
|
||||
var request struct {
|
||||
TenantSlug string `json:"tenantSlug" binding:"required"`
|
||||
BookingMode string `json:"bookingMode" binding:"required"`
|
||||
ServiceID *string `json:"serviceId"`
|
||||
ClassSessionID *string `json:"classSessionId"`
|
||||
StaffID *string `json:"staffId"`
|
||||
LocationID *string `json:"locationId"`
|
||||
CustomerName string `json:"customerName" binding:"required"`
|
||||
CustomerEmail string `json:"customerEmail" binding:"required,email"`
|
||||
CustomerPhone string `json:"customerPhone"`
|
||||
Notes string `json:"notes"`
|
||||
TenantSlug string `json:"tenantSlug" binding:"required"`
|
||||
BookingMode string `json:"bookingMode" binding:"required"`
|
||||
ServiceID *string `json:"serviceId"`
|
||||
ClassSessionID *string `json:"classSessionId"`
|
||||
StaffID *string `json:"staffId"`
|
||||
LocationID *string `json:"locationId"`
|
||||
CustomerName string `json:"customerName" binding:"required"`
|
||||
CustomerEmail string `json:"customerEmail" binding:"required,email"`
|
||||
CustomerPhone string `json:"customerPhone"`
|
||||
Notes string `json:"notes"`
|
||||
Intake map[string]string `json:"intake,omitempty"`
|
||||
StartsAt string `json:"startsAt" binding:"required"`
|
||||
EndsAt string `json:"endsAt" binding:"required"`
|
||||
StartsAt string `json:"startsAt" binding:"required"`
|
||||
EndsAt string `json:"endsAt" binding:"required"`
|
||||
}
|
||||
if err := c.ShouldBindJSON(&request); err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": "invalid_request"})
|
||||
@@ -1148,6 +1148,26 @@ func NewServer(cfg config.Config, pools *db.Pools) (*Server, error) {
|
||||
}
|
||||
c.JSON(http.StatusCreated, response)
|
||||
})
|
||||
protected.PATCH("/catalog/class-schedules/:scheduleID", func(c *gin.Context) {
|
||||
var request domain.UpdateClassScheduleRequest
|
||||
if err := c.ShouldBindJSON(&request); err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": "invalid_request"})
|
||||
return
|
||||
}
|
||||
response, err := catalogService.UpdateClassSchedule(c.Request.Context(), auth.PrincipalFromContext(c), c.Param("scheduleID"), request)
|
||||
if err != nil {
|
||||
status := http.StatusInternalServerError
|
||||
switch {
|
||||
case errors.Is(err, catalog.ErrTenantMembership), errors.Is(err, catalog.ErrClassSessionNotFound), errors.Is(err, catalog.ErrLocationNotFound):
|
||||
status = http.StatusNotFound
|
||||
case errors.Is(err, catalog.ErrInvalidInput):
|
||||
status = http.StatusBadRequest
|
||||
}
|
||||
c.JSON(status, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
c.JSON(http.StatusOK, response)
|
||||
})
|
||||
protected.DELETE("/catalog/class-schedules/:scheduleID", func(c *gin.Context) {
|
||||
err := catalogService.DeleteClassSchedule(c.Request.Context(), auth.PrincipalFromContext(c), c.Param("scheduleID"))
|
||||
if err != nil {
|
||||
|
||||
Reference in new issue
Block a user