@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

MethodPathAuthDescription
GET/booking-assets/:id/calendar.icsGet calendar ics
GET/booking-assets/:id/qr.pngGet qr png
GET/booking-assets/:id/tickets/pdfGet tickets pdf

BookingController /bookings

MethodPathAuthDescription
GET/bookingsYesList bookings
GET/bookings/:idYesGet booking
GET/bookings/:id/calendar.icsYesDownload calendar
GET/bookings/:id/ticketsYesGet booking tickets
GET/bookings/:id/tickets/:ticketId/pdfYesDownload single ticket pdf
GET/bookings/:id/tickets/:ticketId/wallet/appleYesGet apple wallet pass
GET/bookings/:id/tickets/:ticketId/wallet/googleYesGet google wallet url
GET/bookings/:id/tickets/pdfYesDownload all tickets pdf
GET/bookings/:id/tickets/wallet/availabilityYesGet wallet availability
GET/bookings/availabilityYesGet availability
GET/bookings/by-code/:ticketCodeYesGet by ticket code
GET/bookings/calendar-eventsYesGet calendar events
GET/bookings/exportYesExport bookings
GET/bookings/number/:bookingNumberYesGet by booking number
GET/bookings/qr/resolveYesResolve public qr
GET/bookings/resourcesYesList resources
GET/bookings/resources/:idYesGet resource
GET/bookings/statsYesGet stats
GET/bookings/upcomingYesGet upcoming
POST/bookingsYesCreate booking
POST/bookings/:id/payYesInitialize booking payment
POST/bookings/availability/blockYesBlock time
POST/bookings/qr/generateYesGenerate public qr
POST/bookings/resourcesYesCreate resource
POST/bookings/resources/reorderYesReorder resources
POST/bookings/scanYesScan code
POST/bookings/scan/bookingYesScan booking
POST/bookings/scan/ticketYesScan ticket
POST/bookings/waitlistYesJoin waitlist
POST/bookings/walk-inYesCreate walk in booking
PUT/bookings/:idYesUpdate booking
PUT/bookings/resources/:idYesUpdate resource
PATCH/bookings/:id/cancelYesCancel booking
PATCH/bookings/:id/check-inYesCheck in
PATCH/bookings/:id/completeYesComplete booking
PATCH/bookings/:id/confirmYesConfirm booking
PATCH/bookings/:id/no-showYesMark no show
PATCH/bookings/:id/rescheduleYesReschedule booking
PATCH/bookings/resources/:id/activateYesActivate resource
PATCH/bookings/resources/:id/deactivateYesDeactivate resource
DELETE/bookings/availability/blockYesUnblock time
DELETE/bookings/resources/:idYesDelete resource

Calendar Sync /bookings/calendar

MethodPathAuthDescription
GET/bookings/calendar/busy-times/:resourceIdGet busy times from external calendar
GET/bookings/calendar/google/authYesGet Google Calendar OAuth URL
GET/bookings/calendar/google/callbackHandle Google OAuth callback
GET/bookings/calendar/ical/resource/:resourceIdGet iCal feed for a resource
GET/bookings/calendar/ical/tenantGet iCal feed for all tenant bookings
POST/bookings/calendar/sync/booking/:bookingIdYesSync a single booking to calendar
POST/bookings/calendar/sync/resource/:resourceIdYesSync all bookings for a resource
DELETE/bookings/calendar/disconnectYesDisconnect calendar integration
DELETE/bookings/calendar/sync/booking/:bookingIdYesRemove a booking from calendar

PublicBookingController /public/bookings

MethodPathAuthDescription
GET/public/bookings/:bookingNumberGet booking
POST/public/bookings/:bookingNumber/cancelCancel booking
POST/public/bookings/:bookingNumber/rescheduleReschedule booking
POST/public/bookings/verifyVerify booking

ResourceCategoryController /resource-categories

MethodPathAuthDescription
GET/resource-categoriesYesList categories
GET/resource-categories/content/:contentId/requirementsYesGet content requirements
POST/resource-categoriesYesCreate category
PUT/resource-categories/:idYesUpdate category
PUT/resource-categories/content/:contentId/requirementsYesSet content requirements
DELETE/resource-categories/:idYesDelete category

Internals

Use-cases

Application operations. Each is a single-purpose class with one execute() method.

Use-caseSignature
ActivateResourceUseCaseexecute(tenantId: string, resourceId: string): Promise<void>
BlockTimeUseCaseexecute(tenantId: string, dto: BlockTimeDto): Promise<void>
CancelBookingUseCaseexecute(tenantId: string, bookingId: string, dto: CancelBookingDto, accountId?: string, cancelledBy: 'customer' | 'business' = 'business'): Promise<BookingResponseDto>
CheckInBookingUseCaseexecute(tenantId: string, bookingId: string, accountId?: string): Promise<BookingResponseDto>
CompleteBookingUseCaseexecute(tenantId: string, bookingId: string, accountId?: string): Promise<BookingResponseDto>
ConfirmBookingUseCaseexecute(tenantId: string, bookingId: string, accountId?: string): Promise<BookingResponseDto>
CreateBookingUseCaseexecute(tenantId: string, dto: CreateBookingDto, // eslint-disable-next-line @typescript-eslint/no-unused-vars accountId?: string): Promise<BookingResponseDto>
CreateRecurringBookingUseCaseexecute(tenantId: string, dto: CreateRecurringBookingDto): Promise<CreateRecurringBookingResult>
CreateResourceCategoryUseCaseexecute(tenantId: string, dto: CreateResourceCategoryDto): Promise<ResourceCategoryResponseDto>
CreateResourceUseCaseexecute(tenantId: string, dto: CreateResourceDto): Promise<ResourceResponseDto>
CreateWalkInBookingUseCaseexecute(tenantId: string, dto: CreateBookingDto, accountId: string): Promise<BookingResponseDto>
DeactivateResourceUseCaseexecute(tenantId: string, resourceId: string): Promise<void>
DeleteResourceCategoryUseCaseexecute(tenantId: string, categoryId: string): Promise<void>
DeleteResourceUseCaseexecute(tenantId: string, resourceId: string): Promise<void>
ExportBookingsUseCaseexecute(tenantId: string, filters: ExportBookingsFilters): Promise<string>
GenerateBookingCalendarUseCaseexecute(tenant: Tenant, bookingId: string): Promise<BookingCalendarResult>
GeneratePublicQrUseCaseexecute(tenant: Tenant, dto: GeneratePublicQrDto): Promise<PublicQrGenerateResponseDto>
GenerateTicketPdfUseCaseexecute(input: GenerateTicketPdfInput): Promise<Buffer>
GenerateWalletPassUseCaseexecute(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>
GetAvailabilityUseCaseexecute(tenantId: string, dto: GetAvailabilityDto): Promise<AvailabilityResponseDto>
GetBookingByIdUseCaseexecute(tenantId: string, bookingId: string): Promise<BookingResponseDto>
GetBookingByNumberUseCaseexecute(tenantId: string, bookingNumber: string): Promise<BookingResponseDto>
GetBookingStatsUseCaseexecute(tenantId: string, dateFrom?: string, dateTo?: string, type?: string | string[], bookingMode?: string | string[]): Promise<BookingStatsDto>
GetBookingTicketsUseCaseexecute(tenantId: string, bookingId: string): Promise<Ticket[]>
GetCalendarEventsUseCaseexecute(tenantId: string, startDate: Date, endDate: Date, resourceId?: string): Promise<CalendarEventDto[]>
GetContentRequirementsUseCaseexecute(contentId: string): Promise<ContentResourceRequirementResponseDto[]>
GetEligibleResourcesUseCaseexecute(tenantId: string, dto: GetEligibleResourcesDto): Promise<ResolvedResource[]>
GetMemberBookingsUseCaseexecute(tenantId: string, memberId: string, page = 1, limit = 20): Promise<{ data: BookingResponseDto[]; total: number }>
GetResourceByIdUseCaseexecute(tenantId: string, resourceId: string): Promise<ResourceResponseDto>
GetUpcomingBookingsUseCaseexecute(tenantId: string, page = 1, limit = 20): Promise<{ data: BookingResponseDto[]; total: number }>
InitializeBookingPaymentUseCaseexecute(tenantId: string, input: InitializeBookingPaymentInput): Promise<InitializeBookingPaymentOutput>
JoinWaitlistUseCaseexecute(tenantId: string, dto: JoinWaitlistDto): Promise<{ position: number; bookingNumber: string }>
ListBookingsUseCaseexecute(tenantId: string, query: BookingQueryDto): Promise<{ data: BookingResponseDto[]; total: number; page: number; limit: number; }>
ListResourceCategoriesUseCaseexecute(tenantId: string, kind?: ResourceCategoryKind): Promise<ResourceCategoryResponseDto[]>
ListResourcesUseCaseexecute(tenantId: string, query: ResourceQueryDto): Promise<{ data: ResourceResponseDto[]; total: number }>
LookupBookingByTicketCodeUseCaseexecute(tenantId: string, ticketCode: string): Promise<BookingResponseDto>
MarkNoShowUseCaseexecute(tenantId: string, bookingId: string, notes?: string, accountId?: string): Promise<BookingResponseDto>
ProcessBookingRemindersUseCaseexecute(): Promise<ReminderResult[]>
PurchaseTicketUseCaseexecute(tenantId: string, dto: PurchaseTicketDto): Promise<PurchaseTicketResult>
ReleaseExpiredHoldsUseCaseexecute(): Promise<{ released: number }>
ReorderResourcesUseCaseexecute(tenantId: string, orderedIds: string[]): Promise<void>
RescheduleBookingUseCaseexecute(tenantId: string, bookingId: string, dto: RescheduleBookingDto, accountId?: string): Promise<BookingResponseDto>
ResolvePublicQrUseCaseexecute(tenantId: string, token: string): PublicQrResolveResponseDto
ResolveScanCodeUseCaseexecute(tenantId: string, ticketCode: string): Promise<ResolvedScanCode>
ScanBookingUseCaseexecute(tenantId: string, ticketCode: string, accountId?: string): Promise<ScanTicketResult>
ScanTicketUseCaseexecute(tenantId: string, ticketCode: string, accountId?: string): Promise<ScanTicketResult>
SendBookingReminderUseCaseexecute(tenantId: string, bookingId: string, config?: ReminderConfig): Promise<ReminderResult>
SetContentRequirementsUseCaseexecute(tenantId: string, contentId: string, dto: SetContentRequirementsDto): Promise<ContentResourceRequirementResponseDto[]>
UnblockTimeUseCaseexecute(tenantId: string, resourceId: string, date: string, startTime: string): Promise<void>
UpdateBookingUseCaseexecute(tenantId: string, bookingId: string, dto: UpdateBookingDto, accountId?: string): Promise<BookingResponseDto>
UpdateResourceCategoryUseCaseexecute(tenantId: string, categoryId: string, dto: UpdateResourceCategoryDto): Promise<ResourceCategoryResponseDto>
UpdateResourceUseCaseexecute(tenantId: string, resourceId: string, dto: UpdateResourceDto): Promise<ResourceResponseDto>
VerifyBookingOwnershipUseCaseexecute(tenantId: string, input: VerifyBookingInput): Promise<BookingResponseDto>

Entities

Sequelize models owned by this module.

BookableResource — table bookable_resources

FieldType
idstring
tenantIdstring
tenantTenant
categoryIdstring | null
categoryResourceCategory
typeResourceType
statusResourceStatus
namestring
shortNamestring | null
descriptionstring | null
imageUrlstring | null
timezonestring
scheduleResourceSchedule | null
defaultDurationMinutesnumber
bufferMinutesnumber
advanceBookingDaysnumber | null
minNoticeHoursnumber | null
maxBookingsPerSlotnumber | null
pricenumber | null
pricePerHournumber | null
currencystring
skillsstring[]
metadataResourceMetadata
sortOrdernumber
createdAtDate
updatedAtDate
deletedAtDate | null

Booking — table bookings

FieldType
idstring
tenantIdstring
tenantTenant
customerIdstring | null
contentIdstring | null
contentContent
orderIdstring | null
typeBookingType
bookingModeBookingMode
schedulePayloadRecord<string, unknown> | null
actorTypeBookingActorType
originBookingOrigin
bookingNumberstring
statusBookingStatus
startsAtDate
endsAtDate | null
durationMinutesnumber | null
resourceIdstring | null
resourceDataRecord<string, unknown> | null
guestCountnumber
guestsArray<{ name?: string
customerNamestring | null
customerEmailstring | null
customerPhonestring | null
customerNotestring | null
internalNotestring | null
dataBookingMetadata
createdAtDate
updatedAtDate
confirmedAtDate | null
cancelledAtDate | null
ticketCodestring | null
checkedInAtDate | null

ContentResourceRequirement — table content_resource_requirements

FieldType
idstring
contentIdstring
contentContent
categoryIdstring
categoryResourceCategory
tenantIdstring
tenantTenant
isRequiredboolean
assignmentStrategyAssignmentStrategy
requiredSkillsstring[]
eligibleResourceIdsstring[] | null
sortOrdernumber
createdAtDate
updatedAtDate

InventoryHold — table inventory_holds

FieldType
idstring
tenantIdstring
contentIdstring
resourceIdstring | null
holdTypeHoldType
sessionIdstring
quantitynumber
startsAtDate | null
endsAtDate | null
expiresAtDate
createdAtDate
updatedAtDate

ResourceCategory — table resource_categories

FieldType
idstring
tenantIdstring
tenantTenant
labelstring
labelPluralstring
kindResourceCategoryKind
iconstring | null
customFieldsResourceCategoryCustomField[]
sortOrdernumber
isActiveboolean
createdAtDate
updatedAtDate

Ticket — table tickets

FieldType
idstring
tenantIdstring
bookingIdstring
bookingBooking
ticketCodestring | null
tierIdstring | null
seatLabelstring | null
attendeeNamestring | null
attendeeEmailstring | null
checkedInAtDate | null
statusTicketStatus
dataRecord<string, unknown>
createdAtDate
updatedAtDate

TimeSlot — table time_slots

FieldType
idstring
tenantIdstring
tenantTenant
resourceIdstring
resourceBookableResource
bookingIdstring | null
dateDate
startTimestring
endTimestring
durationMinutesnumber
timezonestring
statusTimeSlotStatus
capacitynumber
bookedCountnumber
priceOverridenumber | null
metadataTimeSlotMetadata
createdAtDate
updatedAtDate

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

  • AppleWalletService
  • AssignmentEngineService
  • CalendarSyncService
  • DynamicPricingService
  • GoogleWalletService
  • InventoryHoldSchedulerService
  • InventoryHoldService
  • NoShowProtectionService
  • PublicBookingSessionService
  • PublicQrService
  • ReminderService
  • TicketTierService

Ports

DI contracts other modules bind adapters to.

  • NotificationRecipient, NotificationEmailAttachment, NotificationPayload, BookingNotifier — token BOOKING_NOTIFIER
  • BookingSessionStore — token BOOKING_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.