Two models back the coach calendar and trainee self-booking: CalendarEvent for scheduled sessions and AvailabilityWindow for the times a coach accepts bookings. Whether trainees can book at all is the studio setting calendarEnabled. It is on unless explicitly set to false. See Studio settings JSON.

CalendarEvent

Table calendar_events. Indexes: studioId, coachId, (studioId, startsAt), (clientId, startsAt).

No double booking

Migration 20260622200000_calendar_overlap_exclusion adds a constraint Prisma cannot express:
One coach cannot have two overlapping events unless one of them is cancelled. It needs the btree_gist extension, which the same migration creates. Two requests racing for the same slot cannot both succeed: the second insert fails at the database. Handle that error where you create or move events.
This constraint exists only where the migration ran. A database built with prisma db push alone does not have it, because it is not in either schema file. See The two Prisma schemas.

SessionType

CalendarEventStatus

CONFIRMED, CANCELLED, COMPLETED.

AvailabilityWindow

Table availability_windows. A block of time in which a coach accepts bookings.

One request, many rows

createAvailabilityBody in apps/core-api/src/modules/calendar/calendar.schema.ts takes arrays: weekdays or dates, and ranges of startMinute and endMinute. The service expands them into one row per weekday or date and per range. A recurring request must include at least one weekday.

AvailabilityKind

Modules