@withpotter/booking — module reference
HTTP routes this module mounts, plus its internal use-cases, entities, and repositories. The exhaustive request/response contract is the engine’s OpenAPI document at /docs; the layered structure below follows the package internal architecture.
HTTP routes
BookingAssetsController /booking-assets
| Method | Path | Auth | Description |
|---|---|---|---|
GET | /booking-assets/:id/calendar.ics | — | Get calendar ics |
GET | /booking-assets/:id/qr.png | — | Get qr png |
GET | /booking-assets/:id/tickets/pdf | — | Get tickets pdf |
BookingController /bookings
| Method | Path | Auth | Description |
|---|---|---|---|
GET | /bookings | Yes | List bookings |
GET | /bookings/:id | Yes | Get booking |
GET | /bookings/:id/calendar.ics | Yes | Download calendar |
GET | /bookings/:id/tickets | Yes | Get booking tickets |
GET | /bookings/:id/tickets/:ticketId/pdf | Yes | Download single ticket pdf |
GET | /bookings/:id/tickets/:ticketId/wallet/apple | Yes | Get apple wallet pass |
GET | /bookings/:id/tickets/:ticketId/wallet/google | Yes | Get google wallet url |
GET | /bookings/:id/tickets/pdf | Yes | Download all tickets pdf |
GET | /bookings/:id/tickets/wallet/availability | Yes | Get wallet availability |
GET | /bookings/availability | Yes | Get availability |
GET | /bookings/by-code/:ticketCode | Yes | Get by ticket code |
GET | /bookings/calendar-events | Yes | Get calendar events |
GET | /bookings/export | Yes | Export bookings |
GET | /bookings/number/:bookingNumber | Yes | Get by booking number |
GET | /bookings/qr/resolve | Yes | Resolve public qr |
GET | /bookings/resources | Yes | List resources |
GET | /bookings/resources/:id | Yes | Get resource |
GET | /bookings/stats | Yes | Get stats |
GET | /bookings/upcoming | Yes | Get upcoming |
POST | /bookings | Yes | Create booking |
POST | /bookings/:id/pay | Yes | Initialize booking payment |
POST | /bookings/availability/block | Yes | Block time |
POST | /bookings/qr/generate | Yes | Generate public qr |
POST | /bookings/resources | Yes | Create resource |
POST | /bookings/resources/reorder | Yes | Reorder resources |
POST | /bookings/scan | Yes | Scan code |
POST | /bookings/scan/booking | Yes | Scan booking |
POST | /bookings/scan/ticket | Yes | Scan ticket |
POST | /bookings/waitlist | Yes | Join waitlist |
POST | /bookings/walk-in | Yes | Create walk in booking |
PUT | /bookings/:id | Yes | Update booking |
PUT | /bookings/resources/:id | Yes | Update resource |
PATCH | /bookings/:id/cancel | Yes | Cancel booking |
PATCH | /bookings/:id/check-in | Yes | Check in |
PATCH | /bookings/:id/complete | Yes | Complete booking |
PATCH | /bookings/:id/confirm | Yes | Confirm booking |
PATCH | /bookings/:id/no-show | Yes | Mark no show |
PATCH | /bookings/:id/reschedule | Yes | Reschedule booking |
PATCH | /bookings/resources/:id/activate | Yes | Activate resource |
PATCH | /bookings/resources/:id/deactivate | Yes | Deactivate resource |
DELETE | /bookings/availability/block | Yes | Unblock time |
DELETE | /bookings/resources/:id | Yes | Delete resource |
Calendar Sync /bookings/calendar
| Method | Path | Auth | Description |
|---|---|---|---|
GET | /bookings/calendar/busy-times/:resourceId | — | Get busy times from external calendar |
GET | /bookings/calendar/google/auth | Yes | Get Google Calendar OAuth URL |
GET | /bookings/calendar/google/callback | — | Handle Google OAuth callback |
GET | /bookings/calendar/ical/resource/:resourceId | — | Get iCal feed for a resource |
GET | /bookings/calendar/ical/tenant | — | Get iCal feed for all tenant bookings |
POST | /bookings/calendar/sync/booking/:bookingId | Yes | Sync a single booking to calendar |
POST | /bookings/calendar/sync/resource/:resourceId | Yes | Sync all bookings for a resource |
DELETE | /bookings/calendar/disconnect | Yes | Disconnect calendar integration |
DELETE | /bookings/calendar/sync/booking/:bookingId | Yes | Remove a booking from calendar |
PublicBookingController /public/bookings
| Method | Path | Auth | Description |
|---|---|---|---|
GET | /public/bookings/:bookingNumber | — | Get booking |
POST | /public/bookings/:bookingNumber/cancel | — | Cancel booking |
POST | /public/bookings/:bookingNumber/reschedule | — | Reschedule booking |
POST | /public/bookings/verify | — | Verify booking |
ResourceCategoryController /resource-categories
| Method | Path | Auth | Description |
|---|---|---|---|
GET | /resource-categories | Yes | List categories |
GET | /resource-categories/content/:contentId/requirements | Yes | Get content requirements |
POST | /resource-categories | Yes | Create category |
PUT | /resource-categories/:id | Yes | Update category |
PUT | /resource-categories/content/:contentId/requirements | Yes | Set content requirements |
DELETE | /resource-categories/:id | Yes | Delete category |
Internals
Use-cases
Application operations. Each is a single-purpose class with one execute() method.
| Use-case | Signature |
|---|---|
ActivateResourceUseCase | execute(tenantId: string, resourceId: string): Promise<void> |
BlockTimeUseCase | execute(tenantId: string, dto: BlockTimeDto): Promise<void> |
CancelBookingUseCase | execute(tenantId: string, bookingId: string, dto: CancelBookingDto, accountId?: string, cancelledBy: 'customer' | 'business' = 'business'): Promise<BookingResponseDto> |
CheckInBookingUseCase | execute(tenantId: string, bookingId: string, accountId?: string): Promise<BookingResponseDto> |
CompleteBookingUseCase | execute(tenantId: string, bookingId: string, accountId?: string): Promise<BookingResponseDto> |
ConfirmBookingUseCase | execute(tenantId: string, bookingId: string, accountId?: string): Promise<BookingResponseDto> |
CreateBookingUseCase | execute(tenantId: string, dto: CreateBookingDto, // eslint-disable-next-line @typescript-eslint/no-unused-vars accountId?: string): Promise<BookingResponseDto> |
CreateRecurringBookingUseCase | execute(tenantId: string, dto: CreateRecurringBookingDto): Promise<CreateRecurringBookingResult> |
CreateResourceCategoryUseCase | execute(tenantId: string, dto: CreateResourceCategoryDto): Promise<ResourceCategoryResponseDto> |
CreateResourceUseCase | execute(tenantId: string, dto: CreateResourceDto): Promise<ResourceResponseDto> |
CreateWalkInBookingUseCase | execute(tenantId: string, dto: CreateBookingDto, accountId: string): Promise<BookingResponseDto> |
DeactivateResourceUseCase | execute(tenantId: string, resourceId: string): Promise<void> |
DeleteResourceCategoryUseCase | execute(tenantId: string, categoryId: string): Promise<void> |
DeleteResourceUseCase | execute(tenantId: string, resourceId: string): Promise<void> |
ExportBookingsUseCase | execute(tenantId: string, filters: ExportBookingsFilters): Promise<string> |
GenerateBookingCalendarUseCase | execute(tenant: Tenant, bookingId: string): Promise<BookingCalendarResult> |
GeneratePublicQrUseCase | execute(tenant: Tenant, dto: GeneratePublicQrDto): Promise<PublicQrGenerateResponseDto> |
GenerateTicketPdfUseCase | execute(input: GenerateTicketPdfInput): Promise<Buffer> |
GenerateWalletPassUseCase | execute(input: { action: 'availability' }): WalletPassAvailability; execute(input: { action: 'apple'; tenantId: string; bookingId: string; ticketId: string; }): Promise<Buffer | null>; execute(input: { action: 'google'; tenantId: string; bookingId: string; ticketId: string; }): Promise<string | null>; execute( input: GenerateWalletPassInput, ): WalletPassAvailability | Promise<Buffer | null> | Promise<string | null> |
GetAvailabilityUseCase | execute(tenantId: string, dto: GetAvailabilityDto): Promise<AvailabilityResponseDto> |
GetBookingByIdUseCase | execute(tenantId: string, bookingId: string): Promise<BookingResponseDto> |
GetBookingByNumberUseCase | execute(tenantId: string, bookingNumber: string): Promise<BookingResponseDto> |
GetBookingStatsUseCase | execute(tenantId: string, dateFrom?: string, dateTo?: string, type?: string | string[], bookingMode?: string | string[]): Promise<BookingStatsDto> |
GetBookingTicketsUseCase | execute(tenantId: string, bookingId: string): Promise<Ticket[]> |
GetCalendarEventsUseCase | execute(tenantId: string, startDate: Date, endDate: Date, resourceId?: string): Promise<CalendarEventDto[]> |
GetContentRequirementsUseCase | execute(contentId: string): Promise<ContentResourceRequirementResponseDto[]> |
GetEligibleResourcesUseCase | execute(tenantId: string, dto: GetEligibleResourcesDto): Promise<ResolvedResource[]> |
GetMemberBookingsUseCase | execute(tenantId: string, memberId: string, page = 1, limit = 20): Promise<{ data: BookingResponseDto[]; total: number }> |
GetResourceByIdUseCase | execute(tenantId: string, resourceId: string): Promise<ResourceResponseDto> |
GetUpcomingBookingsUseCase | execute(tenantId: string, page = 1, limit = 20): Promise<{ data: BookingResponseDto[]; total: number }> |
InitializeBookingPaymentUseCase | execute(tenantId: string, input: InitializeBookingPaymentInput): Promise<InitializeBookingPaymentOutput> |
JoinWaitlistUseCase | execute(tenantId: string, dto: JoinWaitlistDto): Promise<{ position: number; bookingNumber: string }> |
ListBookingsUseCase | execute(tenantId: string, query: BookingQueryDto): Promise<{ data: BookingResponseDto[]; total: number; page: number; limit: number; }> |
ListResourceCategoriesUseCase | execute(tenantId: string, kind?: ResourceCategoryKind): Promise<ResourceCategoryResponseDto[]> |
ListResourcesUseCase | execute(tenantId: string, query: ResourceQueryDto): Promise<{ data: ResourceResponseDto[]; total: number }> |
LookupBookingByTicketCodeUseCase | execute(tenantId: string, ticketCode: string): Promise<BookingResponseDto> |
MarkNoShowUseCase | execute(tenantId: string, bookingId: string, notes?: string, accountId?: string): Promise<BookingResponseDto> |
ProcessBookingRemindersUseCase | execute(): Promise<ReminderResult[]> |
PurchaseTicketUseCase | execute(tenantId: string, dto: PurchaseTicketDto): Promise<PurchaseTicketResult> |
ReleaseExpiredHoldsUseCase | execute(): Promise<{ released: number }> |
ReorderResourcesUseCase | execute(tenantId: string, orderedIds: string[]): Promise<void> |
RescheduleBookingUseCase | execute(tenantId: string, bookingId: string, dto: RescheduleBookingDto, accountId?: string): Promise<BookingResponseDto> |
ResolvePublicQrUseCase | execute(tenantId: string, token: string): PublicQrResolveResponseDto |
ResolveScanCodeUseCase | execute(tenantId: string, ticketCode: string): Promise<ResolvedScanCode> |
ScanBookingUseCase | execute(tenantId: string, ticketCode: string, accountId?: string): Promise<ScanTicketResult> |
ScanTicketUseCase | execute(tenantId: string, ticketCode: string, accountId?: string): Promise<ScanTicketResult> |
SendBookingReminderUseCase | execute(tenantId: string, bookingId: string, config?: ReminderConfig): Promise<ReminderResult> |
SetContentRequirementsUseCase | execute(tenantId: string, contentId: string, dto: SetContentRequirementsDto): Promise<ContentResourceRequirementResponseDto[]> |
UnblockTimeUseCase | execute(tenantId: string, resourceId: string, date: string, startTime: string): Promise<void> |
UpdateBookingUseCase | execute(tenantId: string, bookingId: string, dto: UpdateBookingDto, accountId?: string): Promise<BookingResponseDto> |
UpdateResourceCategoryUseCase | execute(tenantId: string, categoryId: string, dto: UpdateResourceCategoryDto): Promise<ResourceCategoryResponseDto> |
UpdateResourceUseCase | execute(tenantId: string, resourceId: string, dto: UpdateResourceDto): Promise<ResourceResponseDto> |
VerifyBookingOwnershipUseCase | execute(tenantId: string, input: VerifyBookingInput): Promise<BookingResponseDto> |
Entities
Sequelize models owned by this module.
BookableResource — table bookable_resources
| Field | Type |
|---|---|
id | string |
tenantId | string |
tenant | Tenant |
categoryId | string | null |
category | ResourceCategory |
type | ResourceType |
status | ResourceStatus |
name | string |
shortName | string | null |
description | string | null |
imageUrl | string | null |
timezone | string |
schedule | ResourceSchedule | null |
defaultDurationMinutes | number |
bufferMinutes | number |
advanceBookingDays | number | null |
minNoticeHours | number | null |
maxBookingsPerSlot | number | null |
price | number | null |
pricePerHour | number | null |
currency | string |
skills | string[] |
metadata | ResourceMetadata |
sortOrder | number |
createdAt | Date |
updatedAt | Date |
deletedAt | Date | null |
Booking — table bookings
| Field | Type |
|---|---|
id | string |
tenantId | string |
tenant | Tenant |
customerId | string | null |
contentId | string | null |
content | Content |
orderId | string | null |
type | BookingType |
bookingMode | BookingMode |
schedulePayload | Record<string, unknown> | null |
actorType | BookingActorType |
origin | BookingOrigin |
bookingNumber | string |
status | BookingStatus |
startsAt | Date |
endsAt | Date | null |
durationMinutes | number | null |
resourceId | string | null |
resourceData | Record<string, unknown> | null |
guestCount | number |
guests | Array<{ name?: string |
customerName | string | null |
customerEmail | string | null |
customerPhone | string | null |
customerNote | string | null |
internalNote | string | null |
data | BookingMetadata |
createdAt | Date |
updatedAt | Date |
confirmedAt | Date | null |
cancelledAt | Date | null |
ticketCode | string | null |
checkedInAt | Date | null |
ContentResourceRequirement — table content_resource_requirements
| Field | Type |
|---|---|
id | string |
contentId | string |
content | Content |
categoryId | string |
category | ResourceCategory |
tenantId | string |
tenant | Tenant |
isRequired | boolean |
assignmentStrategy | AssignmentStrategy |
requiredSkills | string[] |
eligibleResourceIds | string[] | null |
sortOrder | number |
createdAt | Date |
updatedAt | Date |
InventoryHold — table inventory_holds
| Field | Type |
|---|---|
id | string |
tenantId | string |
contentId | string |
resourceId | string | null |
holdType | HoldType |
sessionId | string |
quantity | number |
startsAt | Date | null |
endsAt | Date | null |
expiresAt | Date |
createdAt | Date |
updatedAt | Date |
ResourceCategory — table resource_categories
| Field | Type |
|---|---|
id | string |
tenantId | string |
tenant | Tenant |
label | string |
labelPlural | string |
kind | ResourceCategoryKind |
icon | string | null |
customFields | ResourceCategoryCustomField[] |
sortOrder | number |
isActive | boolean |
createdAt | Date |
updatedAt | Date |
Ticket — table tickets
| Field | Type |
|---|---|
id | string |
tenantId | string |
bookingId | string |
booking | Booking |
ticketCode | string | null |
tierId | string | null |
seatLabel | string | null |
attendeeName | string | null |
attendeeEmail | string | null |
checkedInAt | Date | null |
status | TicketStatus |
data | Record<string, unknown> |
createdAt | Date |
updatedAt | Date |
TimeSlot — table time_slots
| Field | Type |
|---|---|
id | string |
tenantId | string |
tenant | Tenant |
resourceId | string |
resource | BookableResource |
bookingId | string | null |
date | Date |
startTime | string |
endTime | string |
durationMinutes | number |
timezone | string |
status | TimeSlotStatus |
capacity | number |
bookedCount | number |
priceOverride | number | null |
metadata | TimeSlotMetadata |
createdAt | Date |
updatedAt | Date |
Repositories
Data-access classes wrapping the entities.
BookingRepository
findByTenantAndId · updateByTenantAndId · findByBookingNumber · findByTicketCode · findByCustomer · findByMember · findByResource · findUpcoming · findByDateRange · countByStatus · findNeedingReminders · list · getStats · getEventStats · findConflicts · hasConflict · getCheckInCountsByOrderIds · countOrderBookingsByStatus
ContentResourceRequirementRepository
findByContentId · findByCategoryId · existsForContentAndCategory · deleteByContentId · setForContent
InventoryHoldRepository
findActiveHoldsForResource · hasActiveHold · releaseBySession · releaseHold · deleteExpired
ResourceCategoryRepository
findByTenant · findByKind · findByTenantAndId · list · reorder · countByTenant
ResourceRepository
findByTenant · findByType · findActive · findByAccountId · list · softDelete · restore · reorder
TicketRepository
create · bulkCreate · findById · findByTicketCode · findByBookingId · findActiveByBookingId · update · countByBookingId · countCheckedInByBookingId
TimeSlotRepository
findBlocksByTenant · findByResource · findAvailable · findByDateAndTime · findByBooking · isSlotAvailable · blockSlot · unblockSlot · bookSlot · releaseSlot · createMany · deleteByDateRange · generateSlotsForResource
Services
AppleWalletServiceAssignmentEngineServiceCalendarSyncServiceDynamicPricingServiceGoogleWalletServiceInventoryHoldSchedulerServiceInventoryHoldServiceNoShowProtectionServicePublicBookingSessionServicePublicQrServiceReminderServiceTicketTierService
Ports
DI contracts other modules bind adapters to.
NotificationRecipient,NotificationEmailAttachment,NotificationPayload,BookingNotifier— tokenBOOKING_NOTIFIERBookingSessionStore— tokenBOOKING_SESSION_STORE
Generated from the module’s source. Routes are relative to the engine root
(default http://localhost:3001). For full request/response schemas use the live
OpenAPI document.