Kaizen
Browse modulesBookingsbookings/serverClasses

Class: TransferService

Defined in: server/bookings/transfer-service.ts:162

BookingService + the §7.1 transfer family (transfer / reschedule / transferMany). Shipped as a subclass so the spec's "BookingService gains transfer(...)" surface (§11) holds — the factory exposes ONE service that is-a BookingService — while the transfer machinery lives in its own module.

Extends

Extended by

Constructors

Constructor

new TransferService(deps: BookingFeatureDeps): TransferService;

Defined in: server/bookings/booking-service.ts:135

Parameters

ParameterType
depsBookingFeatureDeps

Returns

TransferService

Inherited from

BookingService.constructor

Properties

deps

protected readonly deps: BookingFeatureDeps;

Defined in: server/bookings/booking-service.ts:135

Inherited from

BookingService.deps

Methods

applyClaimTransitions()

protected applyClaimTransitions(
   members: readonly ClaimMember[], 
   event: string, 
   input: {
  actorId: string;
  allowLateCancel?: boolean;
  allowOutsideHours?: boolean;
  allowOverbook?: boolean;
  allowTransfer?: boolean;
  expectedVersion?: number;
  reason?: string;
}
): Promise<{
  amountOwedCents: number | null;
  bookingTypeId: string;
  bookingTypeVersionId: string;
  capacityUnits: number;
  createdAt: Date;
  createdBy: string | null;
  currency: string | null;
  deletedAt: Date | null;
  deletedBy: string | null;
  groupId: string | null;
  holdExpiresAt: Date | null;
  id: string;
  organizationId: string;
  origin: BookingOrigin;
  paid: boolean;
  partyEmail: string | null;
  partyName: string | null;
  partyRef: string | null;
  payload: JsonValue;
  paymentRef: string | null;
  pendingExpiresAt: Date | null;
  status: BookingStatus;
  statusUpdatedAt: Date;
  statusUpdatedBy: string | null;
  supersededById: string | null;
  uid: string;
  updatedAt: Date;
  updatedBy: string | null;
  version: number;
}[]>;

Defined in: server/bookings/booking-service.ts:709

The batch CLAIM core (§6.6/§6.10) — every capacity-acquiring transition runs through here; a single claim is the batch of one.

One repos.transaction (15s budget) wrapping ONE explicit savepoint, so all-or-none survives a consumer's ambient outer transaction (§6.6 joined-tx contract). Inside:

  1. hydrate + policy + STRUCTURAL evaluation for EVERY member — no writes;
  2. the §6.6 batch capacity check over the union overlap set (real row locks, sorted-id order) — or, under allowOverbook, skip it and append one overbooked_by_admin event per schedule-bearing member;
  3. only then apply every member's transition: version-CAS + timeline + is_blocking maintenance + outbox rows.

Any member failure throws before/instead of step 3 and rolls back to the savepoint — none commit. A batch of one unwraps to the inner error.

Parameters

ParameterTypeDescription
membersreadonly ClaimMember[]-
eventstring-
input{ actorId: string; allowLateCancel?: boolean; allowOutsideHours?: boolean; allowOverbook?: boolean; allowTransfer?: boolean; expectedVersion?: number; reason?: string; }-
input.actorIdstring-
input.allowLateCancel?booleanAdmin late-cancel override (spec §7): when true, cancel skips the rules-engine cancellation policy guard and records a cancelled_by_admin timeline event instead — the same bypass-and-record contract as allowOverbook (§6.6). The CONSUMER owns the permission decision; taproot only honors + records the flag. Ignored on every event other than cancel.
input.allowOutsideHours?booleanAdmin outside-hours override (spec §6.9): when true, claiming transitions skip the window-containment check and record an hours_overridden_by_admin timeline event instead — the same bypass-and-record contract as allowOverbook. The CONSUMER owns the permission decision.
input.allowOverbook?booleanAdmin overbook override (spec §6.6): when true, claiming transitions skip the capacity/overlap check and record an overbooked_by_admin timeline event instead. The CONSUMER owns the permission decision — taproot is auth-agnostic and only honors + records the flag.
input.allowTransfer?booleanAdmin transfer override (spec §7.1): when true, the transfer/reschedule family skips the rules-engine policy guard for the transfer event and records a transfer_overridden_by_admin timeline event instead — the same bypass-and-record contract as allowLateCancel/allowOverbook. The CONSUMER owns the permission decision; taproot only honors + records the flag. Ignored on every event other than transfer.
input.expectedVersion?number-
input.reason?string-

Returns

Promise<{ amountOwedCents: number | null; bookingTypeId: string; bookingTypeVersionId: string; capacityUnits: number; createdAt: Date; createdBy: string | null; currency: string | null; deletedAt: Date | null; deletedBy: string | null; groupId: string | null; holdExpiresAt: Date | null; id: string; organizationId: string; origin: BookingOrigin; paid: boolean; partyEmail: string | null; partyName: string | null; partyRef: string | null; payload: JsonValue; paymentRef: string | null; pendingExpiresAt: Date | null; status: BookingStatus; statusUpdatedAt: Date; statusUpdatedBy: string | null; supersededById: string | null; uid: string; updatedAt: Date; updatedBy: string | null; version: number; }[]>

Inherited from

BookingService.applyClaimTransitions


applyTransition()

protected applyTransition(
   bookingId: string, 
   event: string, 
   opts: {
  actorId: string;
  allowLateCancel?: boolean;
  allowOutsideHours?: boolean;
  allowOverbook?: boolean;
  allowTransfer?: boolean;
  expectedVersion?: number;
  reason?: string;
}, 
   extras?: TransitionExtras
): Promise<{
  amountOwedCents: number | null;
  bookingTypeId: string;
  bookingTypeVersionId: string;
  capacityUnits: number;
  createdAt: Date;
  createdBy: string | null;
  currency: string | null;
  deletedAt: Date | null;
  deletedBy: string | null;
  groupId: string | null;
  holdExpiresAt: Date | null;
  id: string;
  organizationId: string;
  origin: BookingOrigin;
  paid: boolean;
  partyEmail: string | null;
  partyName: string | null;
  partyRef: string | null;
  payload: JsonValue;
  paymentRef: string | null;
  pendingExpiresAt: Date | null;
  status: BookingStatus;
  statusUpdatedAt: Date;
  statusUpdatedBy: string | null;
  supersededById: string | null;
  uid: string;
  updatedAt: Date;
  updatedBy: string | null;
  version: number;
}>;

Defined in: server/bookings/booking-service.ts:597

Parameters

ParameterTypeDescription
bookingIdstring-
eventstring-
opts{ actorId: string; allowLateCancel?: boolean; allowOutsideHours?: boolean; allowOverbook?: boolean; allowTransfer?: boolean; expectedVersion?: number; reason?: string; }-
opts.actorIdstring-
opts.allowLateCancel?booleanAdmin late-cancel override (spec §7): when true, cancel skips the rules-engine cancellation policy guard and records a cancelled_by_admin timeline event instead — the same bypass-and-record contract as allowOverbook (§6.6). The CONSUMER owns the permission decision; taproot only honors + records the flag. Ignored on every event other than cancel.
opts.allowOutsideHours?booleanAdmin outside-hours override (spec §6.9): when true, claiming transitions skip the window-containment check and record an hours_overridden_by_admin timeline event instead — the same bypass-and-record contract as allowOverbook. The CONSUMER owns the permission decision.
opts.allowOverbook?booleanAdmin overbook override (spec §6.6): when true, claiming transitions skip the capacity/overlap check and record an overbooked_by_admin timeline event instead. The CONSUMER owns the permission decision — taproot is auth-agnostic and only honors + records the flag.
opts.allowTransfer?booleanAdmin transfer override (spec §7.1): when true, the transfer/reschedule family skips the rules-engine policy guard for the transfer event and records a transfer_overridden_by_admin timeline event instead — the same bypass-and-record contract as allowLateCancel/allowOverbook. The CONSUMER owns the permission decision; taproot only honors + records the flag. Ignored on every event other than transfer.
opts.expectedVersion?number-
opts.reason?string-
extras?TransitionExtras-

Returns

Promise<{ amountOwedCents: number | null; bookingTypeId: string; bookingTypeVersionId: string; capacityUnits: number; createdAt: Date; createdBy: string | null; currency: string | null; deletedAt: Date | null; deletedBy: string | null; groupId: string | null; holdExpiresAt: Date | null; id: string; organizationId: string; origin: BookingOrigin; paid: boolean; partyEmail: string | null; partyName: string | null; partyRef: string | null; payload: JsonValue; paymentRef: string | null; pendingExpiresAt: Date | null; status: BookingStatus; statusUpdatedAt: Date; statusUpdatedBy: string | null; supersededById: string | null; uid: string; updatedAt: Date; updatedBy: string | null; version: number; }>

Inherited from

BookingService.applyTransition


approve()

approve(bookingId: string, opts: {
  actorId: string;
  allowLateCancel?: boolean;
  allowOutsideHours?: boolean;
  allowOverbook?: boolean;
  allowTransfer?: boolean;
  expectedVersion?: number;
  reason?: string;
}): Promise<{
  amountOwedCents: number | null;
  bookingTypeId: string;
  bookingTypeVersionId: string;
  capacityUnits: number;
  createdAt: Date;
  createdBy: string | null;
  currency: string | null;
  deletedAt: Date | null;
  deletedBy: string | null;
  groupId: string | null;
  holdExpiresAt: Date | null;
  id: string;
  organizationId: string;
  origin: BookingOrigin;
  paid: boolean;
  partyEmail: string | null;
  partyName: string | null;
  partyRef: string | null;
  payload: JsonValue;
  paymentRef: string | null;
  pendingExpiresAt: Date | null;
  status: BookingStatus;
  statusUpdatedAt: Date;
  statusUpdatedBy: string | null;
  supersededById: string | null;
  uid: string;
  updatedAt: Date;
  updatedBy: string | null;
  version: number;
}>;

Defined in: server/bookings/booking-service.ts:385

pending→confirmed — deliberately NON-claiming, unlike confirm-from-held.

Capacity was acquired at submit (the claim path), and pending blocks UNCONDITIONALLY in the §6.6 truth table — it carries no query-side expiry predicate, so its occupancy can never silently lapse between submit and approve. (pending→expired is a sweeper-driven version-CAS transition; racing it makes this approve throw StaleBookingError rather than double-book.) Contrast held, whose occupancy evaporates the moment holdExpiresAt passes: confirming an expired-but-unswept hold RE-ACQUIRES capacity, so confirm must re-check under the overlap-set lock. Approve acquires nothing — and the claim path's capacity check excludes a member's own booking rows anyway (§6.6 self-exclusion), so routing approve through that capacity check would add no protection.

Parameters

ParameterTypeDescription
bookingIdstring-
opts{ actorId: string; allowLateCancel?: boolean; allowOutsideHours?: boolean; allowOverbook?: boolean; allowTransfer?: boolean; expectedVersion?: number; reason?: string; }-
opts.actorIdstring-
opts.allowLateCancel?booleanAdmin late-cancel override (spec §7): when true, cancel skips the rules-engine cancellation policy guard and records a cancelled_by_admin timeline event instead — the same bypass-and-record contract as allowOverbook (§6.6). The CONSUMER owns the permission decision; taproot only honors + records the flag. Ignored on every event other than cancel.
opts.allowOutsideHours?booleanAdmin outside-hours override (spec §6.9): when true, claiming transitions skip the window-containment check and record an hours_overridden_by_admin timeline event instead — the same bypass-and-record contract as allowOverbook. The CONSUMER owns the permission decision.
opts.allowOverbook?booleanAdmin overbook override (spec §6.6): when true, claiming transitions skip the capacity/overlap check and record an overbooked_by_admin timeline event instead. The CONSUMER owns the permission decision — taproot is auth-agnostic and only honors + records the flag.
opts.allowTransfer?booleanAdmin transfer override (spec §7.1): when true, the transfer/reschedule family skips the rules-engine policy guard for the transfer event and records a transfer_overridden_by_admin timeline event instead — the same bypass-and-record contract as allowLateCancel/allowOverbook. The CONSUMER owns the permission decision; taproot only honors + records the flag. Ignored on every event other than transfer.
opts.expectedVersion?number-
opts.reason?string-

Returns

Promise<{ amountOwedCents: number | null; bookingTypeId: string; bookingTypeVersionId: string; capacityUnits: number; createdAt: Date; createdBy: string | null; currency: string | null; deletedAt: Date | null; deletedBy: string | null; groupId: string | null; holdExpiresAt: Date | null; id: string; organizationId: string; origin: BookingOrigin; paid: boolean; partyEmail: string | null; partyName: string | null; partyRef: string | null; payload: JsonValue; paymentRef: string | null; pendingExpiresAt: Date | null; status: BookingStatus; statusUpdatedAt: Date; statusUpdatedBy: string | null; supersededById: string | null; uid: string; updatedAt: Date; updatedBy: string | null; version: number; }>

Inherited from

BookingService.approve


assertPolicyAllows()

protected assertPolicyAllows(
   booking: ComposedBookingRow, 
   event: string, 
   opts: {
  actorId: string;
  allowLateCancel?: boolean;
  allowOutsideHours?: boolean;
  allowOverbook?: boolean;
  allowTransfer?: boolean;
  expectedVersion?: number;
  reason?: string;
}
): Promise<void>;

Defined in: server/bookings/booking-service.ts:955

POLICY seam (§8.1 step a / §8.3): approval routing from the PINNED policy bag (§6.2) + domain: "bookings" rules evaluation — throws PolicyDeniedError on deny. Protected so a consumer subclass can extend/replace the policy layer.

Parameters

ParameterTypeDescription
bookingComposedBookingRow-
eventstring-
opts{ actorId: string; allowLateCancel?: boolean; allowOutsideHours?: boolean; allowOverbook?: boolean; allowTransfer?: boolean; expectedVersion?: number; reason?: string; }-
opts.actorIdstring-
opts.allowLateCancel?booleanAdmin late-cancel override (spec §7): when true, cancel skips the rules-engine cancellation policy guard and records a cancelled_by_admin timeline event instead — the same bypass-and-record contract as allowOverbook (§6.6). The CONSUMER owns the permission decision; taproot only honors + records the flag. Ignored on every event other than cancel.
opts.allowOutsideHours?booleanAdmin outside-hours override (spec §6.9): when true, claiming transitions skip the window-containment check and record an hours_overridden_by_admin timeline event instead — the same bypass-and-record contract as allowOverbook. The CONSUMER owns the permission decision.
opts.allowOverbook?booleanAdmin overbook override (spec §6.6): when true, claiming transitions skip the capacity/overlap check and record an overbooked_by_admin timeline event instead. The CONSUMER owns the permission decision — taproot is auth-agnostic and only honors + records the flag.
opts.allowTransfer?booleanAdmin transfer override (spec §7.1): when true, the transfer/reschedule family skips the rules-engine policy guard for the transfer event and records a transfer_overridden_by_admin timeline event instead — the same bypass-and-record contract as allowLateCancel/allowOverbook. The CONSUMER owns the permission decision; taproot only honors + records the flag. Ignored on every event other than transfer.
opts.expectedVersion?number-
opts.reason?string-

Returns

Promise<void>

Inherited from

BookingService.assertPolicyAllows


cancel()

cancel(bookingId: string, opts: {
  actorId: string;
  allowLateCancel?: boolean;
  allowOutsideHours?: boolean;
  allowOverbook?: boolean;
  allowTransfer?: boolean;
  expectedVersion?: number;
  reason?: string;
}): Promise<{
  amountOwedCents: number | null;
  bookingTypeId: string;
  bookingTypeVersionId: string;
  capacityUnits: number;
  createdAt: Date;
  createdBy: string | null;
  currency: string | null;
  deletedAt: Date | null;
  deletedBy: string | null;
  groupId: string | null;
  holdExpiresAt: Date | null;
  id: string;
  organizationId: string;
  origin: BookingOrigin;
  paid: boolean;
  partyEmail: string | null;
  partyName: string | null;
  partyRef: string | null;
  payload: JsonValue;
  paymentRef: string | null;
  pendingExpiresAt: Date | null;
  status: BookingStatus;
  statusUpdatedAt: Date;
  statusUpdatedBy: string | null;
  supersededById: string | null;
  uid: string;
  updatedAt: Date;
  updatedBy: string | null;
  version: number;
}>;

Defined in: server/bookings/booking-service.ts:322

Parameters

ParameterTypeDescription
bookingIdstring-
opts{ actorId: string; allowLateCancel?: boolean; allowOutsideHours?: boolean; allowOverbook?: boolean; allowTransfer?: boolean; expectedVersion?: number; reason?: string; }-
opts.actorIdstring-
opts.allowLateCancel?booleanAdmin late-cancel override (spec §7): when true, cancel skips the rules-engine cancellation policy guard and records a cancelled_by_admin timeline event instead — the same bypass-and-record contract as allowOverbook (§6.6). The CONSUMER owns the permission decision; taproot only honors + records the flag. Ignored on every event other than cancel.
opts.allowOutsideHours?booleanAdmin outside-hours override (spec §6.9): when true, claiming transitions skip the window-containment check and record an hours_overridden_by_admin timeline event instead — the same bypass-and-record contract as allowOverbook. The CONSUMER owns the permission decision.
opts.allowOverbook?booleanAdmin overbook override (spec §6.6): when true, claiming transitions skip the capacity/overlap check and record an overbooked_by_admin timeline event instead. The CONSUMER owns the permission decision — taproot is auth-agnostic and only honors + records the flag.
opts.allowTransfer?booleanAdmin transfer override (spec §7.1): when true, the transfer/reschedule family skips the rules-engine policy guard for the transfer event and records a transfer_overridden_by_admin timeline event instead — the same bypass-and-record contract as allowLateCancel/allowOverbook. The CONSUMER owns the permission decision; taproot only honors + records the flag. Ignored on every event other than transfer.
opts.expectedVersion?number-
opts.reason?string-

Returns

Promise<{ amountOwedCents: number | null; bookingTypeId: string; bookingTypeVersionId: string; capacityUnits: number; createdAt: Date; createdBy: string | null; currency: string | null; deletedAt: Date | null; deletedBy: string | null; groupId: string | null; holdExpiresAt: Date | null; id: string; organizationId: string; origin: BookingOrigin; paid: boolean; partyEmail: string | null; partyName: string | null; partyRef: string | null; payload: JsonValue; paymentRef: string | null; pendingExpiresAt: Date | null; status: BookingStatus; statusUpdatedAt: Date; statusUpdatedBy: string | null; supersededById: string | null; uid: string; updatedAt: Date; updatedBy: string | null; version: number; }>

Inherited from

BookingService.cancel


complete()

complete(bookingId: string, opts: {
  actorId: string;
  allowLateCancel?: boolean;
  allowOutsideHours?: boolean;
  allowOverbook?: boolean;
  allowTransfer?: boolean;
  expectedVersion?: number;
  reason?: string;
}): Promise<{
  amountOwedCents: number | null;
  bookingTypeId: string;
  bookingTypeVersionId: string;
  capacityUnits: number;
  createdAt: Date;
  createdBy: string | null;
  currency: string | null;
  deletedAt: Date | null;
  deletedBy: string | null;
  groupId: string | null;
  holdExpiresAt: Date | null;
  id: string;
  organizationId: string;
  origin: BookingOrigin;
  paid: boolean;
  partyEmail: string | null;
  partyName: string | null;
  partyRef: string | null;
  payload: JsonValue;
  paymentRef: string | null;
  pendingExpiresAt: Date | null;
  status: BookingStatus;
  statusUpdatedAt: Date;
  statusUpdatedBy: string | null;
  supersededById: string | null;
  uid: string;
  updatedAt: Date;
  updatedBy: string | null;
  version: number;
}>;

Defined in: server/bookings/booking-service.ts:401

Parameters

ParameterTypeDescription
bookingIdstring-
opts{ actorId: string; allowLateCancel?: boolean; allowOutsideHours?: boolean; allowOverbook?: boolean; allowTransfer?: boolean; expectedVersion?: number; reason?: string; }-
opts.actorIdstring-
opts.allowLateCancel?booleanAdmin late-cancel override (spec §7): when true, cancel skips the rules-engine cancellation policy guard and records a cancelled_by_admin timeline event instead — the same bypass-and-record contract as allowOverbook (§6.6). The CONSUMER owns the permission decision; taproot only honors + records the flag. Ignored on every event other than cancel.
opts.allowOutsideHours?booleanAdmin outside-hours override (spec §6.9): when true, claiming transitions skip the window-containment check and record an hours_overridden_by_admin timeline event instead — the same bypass-and-record contract as allowOverbook. The CONSUMER owns the permission decision.
opts.allowOverbook?booleanAdmin overbook override (spec §6.6): when true, claiming transitions skip the capacity/overlap check and record an overbooked_by_admin timeline event instead. The CONSUMER owns the permission decision — taproot is auth-agnostic and only honors + records the flag.
opts.allowTransfer?booleanAdmin transfer override (spec §7.1): when true, the transfer/reschedule family skips the rules-engine policy guard for the transfer event and records a transfer_overridden_by_admin timeline event instead — the same bypass-and-record contract as allowLateCancel/allowOverbook. The CONSUMER owns the permission decision; taproot only honors + records the flag. Ignored on every event other than transfer.
opts.expectedVersion?number-
opts.reason?string-

Returns

Promise<{ amountOwedCents: number | null; bookingTypeId: string; bookingTypeVersionId: string; capacityUnits: number; createdAt: Date; createdBy: string | null; currency: string | null; deletedAt: Date | null; deletedBy: string | null; groupId: string | null; holdExpiresAt: Date | null; id: string; organizationId: string; origin: BookingOrigin; paid: boolean; partyEmail: string | null; partyName: string | null; partyRef: string | null; payload: JsonValue; paymentRef: string | null; pendingExpiresAt: Date | null; status: BookingStatus; statusUpdatedAt: Date; statusUpdatedBy: string | null; supersededById: string | null; uid: string; updatedAt: Date; updatedBy: string | null; version: number; }>

Inherited from

BookingService.complete


completeBooking()

completeBooking(bookingId: string, opts: {
  actorId: string | null;
  expectedVersion?: number;
  idempotencyKey?: string;
}): Promise<{
  amountOwedCents: number | null;
  bookingTypeId: string;
  bookingTypeVersionId: string;
  capacityUnits: number;
  createdAt: Date;
  createdBy: string | null;
  currency: string | null;
  deletedAt: Date | null;
  deletedBy: string | null;
  groupId: string | null;
  holdExpiresAt: Date | null;
  id: string;
  organizationId: string;
  origin: BookingOrigin;
  paid: boolean;
  partyEmail: string | null;
  partyName: string | null;
  partyRef: string | null;
  payload: JsonValue;
  paymentRef: string | null;
  pendingExpiresAt: Date | null;
  status: BookingStatus;
  statusUpdatedAt: Date;
  statusUpdatedBy: string | null;
  supersededById: string | null;
  uid: string;
  updatedAt: Date;
  updatedBy: string | null;
  version: number;
}>;

Defined in: server/bookings/booking-service.ts:456

System-actor confirmed→completed transition used by the completion sweeper (§11). Structural guard (endsAt <= now) must pass; the host is hydrated inside applyTransition from the schedule join.

Parameters

ParameterType
bookingIdstring
opts{ actorId: string | null; expectedVersion?: number; idempotencyKey?: string; }
opts.actorIdstring | null
opts.expectedVersion?number
opts.idempotencyKey?string

Returns

Promise<{ amountOwedCents: number | null; bookingTypeId: string; bookingTypeVersionId: string; capacityUnits: number; createdAt: Date; createdBy: string | null; currency: string | null; deletedAt: Date | null; deletedBy: string | null; groupId: string | null; holdExpiresAt: Date | null; id: string; organizationId: string; origin: BookingOrigin; paid: boolean; partyEmail: string | null; partyName: string | null; partyRef: string | null; payload: JsonValue; paymentRef: string | null; pendingExpiresAt: Date | null; status: BookingStatus; statusUpdatedAt: Date; statusUpdatedBy: string | null; supersededById: string | null; uid: string; updatedAt: Date; updatedBy: string | null; version: number; }>

Inherited from

BookingService.completeBooking


confirm()

confirm(bookingId: string, opts: {
  actorId: string;
  allowLateCancel?: boolean;
  allowOutsideHours?: boolean;
  allowOverbook?: boolean;
  allowTransfer?: boolean;
  expectedVersion?: number;
  reason?: string;
}): Promise<{
  amountOwedCents: number | null;
  bookingTypeId: string;
  bookingTypeVersionId: string;
  capacityUnits: number;
  createdAt: Date;
  createdBy: string | null;
  currency: string | null;
  deletedAt: Date | null;
  deletedBy: string | null;
  groupId: string | null;
  holdExpiresAt: Date | null;
  id: string;
  organizationId: string;
  origin: BookingOrigin;
  paid: boolean;
  partyEmail: string | null;
  partyName: string | null;
  partyRef: string | null;
  payload: JsonValue;
  paymentRef: string | null;
  pendingExpiresAt: Date | null;
  status: BookingStatus;
  statusUpdatedAt: Date;
  statusUpdatedBy: string | null;
  supersededById: string | null;
  uid: string;
  updatedAt: Date;
  updatedBy: string | null;
  version: number;
}>;

Defined in: server/bookings/booking-service.ts:293

Parameters

ParameterTypeDescription
bookingIdstring-
opts{ actorId: string; allowLateCancel?: boolean; allowOutsideHours?: boolean; allowOverbook?: boolean; allowTransfer?: boolean; expectedVersion?: number; reason?: string; }-
opts.actorIdstring-
opts.allowLateCancel?booleanAdmin late-cancel override (spec §7): when true, cancel skips the rules-engine cancellation policy guard and records a cancelled_by_admin timeline event instead — the same bypass-and-record contract as allowOverbook (§6.6). The CONSUMER owns the permission decision; taproot only honors + records the flag. Ignored on every event other than cancel.
opts.allowOutsideHours?booleanAdmin outside-hours override (spec §6.9): when true, claiming transitions skip the window-containment check and record an hours_overridden_by_admin timeline event instead — the same bypass-and-record contract as allowOverbook. The CONSUMER owns the permission decision.
opts.allowOverbook?booleanAdmin overbook override (spec §6.6): when true, claiming transitions skip the capacity/overlap check and record an overbooked_by_admin timeline event instead. The CONSUMER owns the permission decision — taproot is auth-agnostic and only honors + records the flag.
opts.allowTransfer?booleanAdmin transfer override (spec §7.1): when true, the transfer/reschedule family skips the rules-engine policy guard for the transfer event and records a transfer_overridden_by_admin timeline event instead — the same bypass-and-record contract as allowLateCancel/allowOverbook. The CONSUMER owns the permission decision; taproot only honors + records the flag. Ignored on every event other than transfer.
opts.expectedVersion?number-
opts.reason?string-

Returns

Promise<{ amountOwedCents: number | null; bookingTypeId: string; bookingTypeVersionId: string; capacityUnits: number; createdAt: Date; createdBy: string | null; currency: string | null; deletedAt: Date | null; deletedBy: string | null; groupId: string | null; holdExpiresAt: Date | null; id: string; organizationId: string; origin: BookingOrigin; paid: boolean; partyEmail: string | null; partyName: string | null; partyRef: string | null; payload: JsonValue; paymentRef: string | null; pendingExpiresAt: Date | null; status: BookingStatus; statusUpdatedAt: Date; statusUpdatedBy: string | null; supersededById: string | null; uid: string; updatedAt: Date; updatedBy: string | null; version: number; }>

Inherited from

BookingService.confirm


confirmMany()

confirmMany(bookingIds: readonly string[], opts: {
  actorId: string;
  allowLateCancel?: boolean;
  allowOutsideHours?: boolean;
  allowOverbook?: boolean;
  allowTransfer?: boolean;
  expectedVersion?: number;
  reason?: string;
}): Promise<{
  amountOwedCents: number | null;
  bookingTypeId: string;
  bookingTypeVersionId: string;
  capacityUnits: number;
  createdAt: Date;
  createdBy: string | null;
  currency: string | null;
  deletedAt: Date | null;
  deletedBy: string | null;
  groupId: string | null;
  holdExpiresAt: Date | null;
  id: string;
  organizationId: string;
  origin: BookingOrigin;
  paid: boolean;
  partyEmail: string | null;
  partyName: string | null;
  partyRef: string | null;
  payload: JsonValue;
  paymentRef: string | null;
  pendingExpiresAt: Date | null;
  status: BookingStatus;
  statusUpdatedAt: Date;
  statusUpdatedBy: string | null;
  supersededById: string | null;
  uid: string;
  updatedAt: Date;
  updatedBy: string | null;
  version: number;
}[]>;

Defined in: server/bookings/booking-service.ts:302

Batch confirm (§6.10): one transaction, one savepoint, all-or-none.

Parameters

ParameterTypeDescription
bookingIdsreadonly string[]-
opts{ actorId: string; allowLateCancel?: boolean; allowOutsideHours?: boolean; allowOverbook?: boolean; allowTransfer?: boolean; expectedVersion?: number; reason?: string; }-
opts.actorIdstring-
opts.allowLateCancel?booleanAdmin late-cancel override (spec §7): when true, cancel skips the rules-engine cancellation policy guard and records a cancelled_by_admin timeline event instead — the same bypass-and-record contract as allowOverbook (§6.6). The CONSUMER owns the permission decision; taproot only honors + records the flag. Ignored on every event other than cancel.
opts.allowOutsideHours?booleanAdmin outside-hours override (spec §6.9): when true, claiming transitions skip the window-containment check and record an hours_overridden_by_admin timeline event instead — the same bypass-and-record contract as allowOverbook. The CONSUMER owns the permission decision.
opts.allowOverbook?booleanAdmin overbook override (spec §6.6): when true, claiming transitions skip the capacity/overlap check and record an overbooked_by_admin timeline event instead. The CONSUMER owns the permission decision — taproot is auth-agnostic and only honors + records the flag.
opts.allowTransfer?booleanAdmin transfer override (spec §7.1): when true, the transfer/reschedule family skips the rules-engine policy guard for the transfer event and records a transfer_overridden_by_admin timeline event instead — the same bypass-and-record contract as allowLateCancel/allowOverbook. The CONSUMER owns the permission decision; taproot only honors + records the flag. Ignored on every event other than transfer.
opts.expectedVersion?number-
opts.reason?string-

Returns

Promise<{ amountOwedCents: number | null; bookingTypeId: string; bookingTypeVersionId: string; capacityUnits: number; createdAt: Date; createdBy: string | null; currency: string | null; deletedAt: Date | null; deletedBy: string | null; groupId: string | null; holdExpiresAt: Date | null; id: string; organizationId: string; origin: BookingOrigin; paid: boolean; partyEmail: string | null; partyName: string | null; partyRef: string | null; payload: JsonValue; paymentRef: string | null; pendingExpiresAt: Date | null; status: BookingStatus; statusUpdatedAt: Date; statusUpdatedBy: string | null; supersededById: string | null; uid: string; updatedAt: Date; updatedBy: string | null; version: number; }[]>

Inherited from

BookingService.confirmMany


create()

create(raw: {
  bookingTypeId: string;
  capacityUnits?: number;
  organizationId: string;
  partyEmail?: string;
  partyName?: string;
  partyRef?: string;
  payload?: Record<string, unknown>;
  schedule?: {
     endsAt: unknown;
     resourceId: string;
     startsAt: unknown;
     timeZone: string;
  };
}): Promise<{
  amountOwedCents: number | null;
  bookingTypeId: string;
  bookingTypeVersionId: string;
  capacityUnits: number;
  createdAt: Date;
  createdBy: string | null;
  currency: string | null;
  deletedAt: Date | null;
  deletedBy: string | null;
  groupId: string | null;
  holdExpiresAt: Date | null;
  id: string;
  organizationId: string;
  origin: BookingOrigin;
  paid: boolean;
  partyEmail: string | null;
  partyName: string | null;
  partyRef: string | null;
  payload: JsonValue;
  paymentRef: string | null;
  pendingExpiresAt: Date | null;
  status: BookingStatus;
  statusUpdatedAt: Date;
  statusUpdatedBy: string | null;
  supersededById: string | null;
  uid: string;
  updatedAt: Date;
  updatedBy: string | null;
  version: number;
}>;

Defined in: server/bookings/booking-service.ts:155

Create a draft booking, pinning the type's published version (§6.2) and appending booking_created + terms_pinned timeline rows — one tx.

When schedule is provided, a BookingSchedules row is written at isBlocking: false — a draft never blocks capacity (spec §6.6 truth table).

Parameters

ParameterType
raw{ bookingTypeId: string; capacityUnits?: number; organizationId: string; partyEmail?: string; partyName?: string; partyRef?: string; payload?: Record<string, unknown>; schedule?: { endsAt: unknown; resourceId: string; startsAt: unknown; timeZone: string; }; }
raw.bookingTypeIdstring
raw.capacityUnits?number
raw.organizationIdstring
raw.partyEmail?string
raw.partyName?string
raw.partyRef?string
raw.payload?Record<string, unknown>
raw.schedule?{ endsAt: unknown; resourceId: string; startsAt: unknown; timeZone: string; }
raw.schedule.endsAtunknown
raw.schedule.resourceIdstring
raw.schedule.startsAtunknown
raw.schedule.timeZonestring

Returns

Promise<{ amountOwedCents: number | null; bookingTypeId: string; bookingTypeVersionId: string; capacityUnits: number; createdAt: Date; createdBy: string | null; currency: string | null; deletedAt: Date | null; deletedBy: string | null; groupId: string | null; holdExpiresAt: Date | null; id: string; organizationId: string; origin: BookingOrigin; paid: boolean; partyEmail: string | null; partyName: string | null; partyRef: string | null; payload: JsonValue; paymentRef: string | null; pendingExpiresAt: Date | null; status: BookingStatus; statusUpdatedAt: Date; statusUpdatedBy: string | null; supersededById: string | null; uid: string; updatedAt: Date; updatedBy: string | null; version: number; }>

Inherited from

BookingService.create


expireApproval()

expireApproval(bookingId: string, opts: {
  actorId: string | null;
  expectedVersion?: number;
  idempotencyKey?: string;
}): Promise<{
  amountOwedCents: number | null;
  bookingTypeId: string;
  bookingTypeVersionId: string;
  capacityUnits: number;
  createdAt: Date;
  createdBy: string | null;
  currency: string | null;
  deletedAt: Date | null;
  deletedBy: string | null;
  groupId: string | null;
  holdExpiresAt: Date | null;
  id: string;
  organizationId: string;
  origin: BookingOrigin;
  paid: boolean;
  partyEmail: string | null;
  partyName: string | null;
  partyRef: string | null;
  payload: JsonValue;
  paymentRef: string | null;
  pendingExpiresAt: Date | null;
  status: BookingStatus;
  statusUpdatedAt: Date;
  statusUpdatedBy: string | null;
  supersededById: string | null;
  uid: string;
  updatedAt: Date;
  updatedBy: string | null;
  version: number;
}>;

Defined in: server/bookings/booking-service.ts:425

System-actor pending→expired transition used by the approval-expiry sweeper (§11). Mirrors expireHold — same CAS semantics, system actorId, deterministic idempotency key.

Parameters

ParameterType
bookingIdstring
opts{ actorId: string | null; expectedVersion?: number; idempotencyKey?: string; }
opts.actorIdstring | null
opts.expectedVersion?number
opts.idempotencyKey?string

Returns

Promise<{ amountOwedCents: number | null; bookingTypeId: string; bookingTypeVersionId: string; capacityUnits: number; createdAt: Date; createdBy: string | null; currency: string | null; deletedAt: Date | null; deletedBy: string | null; groupId: string | null; holdExpiresAt: Date | null; id: string; organizationId: string; origin: BookingOrigin; paid: boolean; partyEmail: string | null; partyName: string | null; partyRef: string | null; payload: JsonValue; paymentRef: string | null; pendingExpiresAt: Date | null; status: BookingStatus; statusUpdatedAt: Date; statusUpdatedBy: string | null; supersededById: string | null; uid: string; updatedAt: Date; updatedBy: string | null; version: number; }>

Inherited from

BookingService.expireApproval


expireHold()

expireHold(bookingId: string, opts: {
  actorId: string | null;
  expectedVersion?: number;
  idempotencyKey?: string;
  reason?: string;
}): Promise<{
  amountOwedCents: number | null;
  bookingTypeId: string;
  bookingTypeVersionId: string;
  capacityUnits: number;
  createdAt: Date;
  createdBy: string | null;
  currency: string | null;
  deletedAt: Date | null;
  deletedBy: string | null;
  groupId: string | null;
  holdExpiresAt: Date | null;
  id: string;
  organizationId: string;
  origin: BookingOrigin;
  paid: boolean;
  partyEmail: string | null;
  partyName: string | null;
  partyRef: string | null;
  payload: JsonValue;
  paymentRef: string | null;
  pendingExpiresAt: Date | null;
  status: BookingStatus;
  statusUpdatedAt: Date;
  statusUpdatedBy: string | null;
  supersededById: string | null;
  uid: string;
  updatedAt: Date;
  updatedBy: string | null;
  version: number;
}>;

Defined in: server/bookings/booking-service.ts:523

System-actor held→expired transition used by the hold sweeper (§6.3).

Uses the same version-CAS path as every other transition — the sweeper CAS races a concurrent confirm fairly: whichever commits first wins; the loser throws StaleBookingError and is skipped (§6.6 / §14).

actorId is null for the hold sweeper (system actor). expectedVersion is the version hydrated by the sweeper to participate in the CAS race.

Parameters

ParameterType
bookingIdstring
opts{ actorId: string | null; expectedVersion?: number; idempotencyKey?: string; reason?: string; }
opts.actorIdstring | null
opts.expectedVersion?number
opts.idempotencyKey?string
opts.reason?string

Returns

Promise<{ amountOwedCents: number | null; bookingTypeId: string; bookingTypeVersionId: string; capacityUnits: number; createdAt: Date; createdBy: string | null; currency: string | null; deletedAt: Date | null; deletedBy: string | null; groupId: string | null; holdExpiresAt: Date | null; id: string; organizationId: string; origin: BookingOrigin; paid: boolean; partyEmail: string | null; partyName: string | null; partyRef: string | null; payload: JsonValue; paymentRef: string | null; pendingExpiresAt: Date | null; status: BookingStatus; statusUpdatedAt: Date; statusUpdatedBy: string | null; supersededById: string | null; uid: string; updatedAt: Date; updatedBy: string | null; version: number; }>

Inherited from

BookingService.expireHold


generateUid()

protected generateUid(repos: BookingRepositories, organizationId: string): Promise<string>;

Defined in: server/bookings/booking-service.ts:996

8-char external short code, retried on org-uniqueness collision.

Parameters

ParameterType
reposBookingRepositories
organizationIdstring

Returns

Promise<string>

Inherited from

BookingService.generateUid


hold()

hold(bookingId: string, opts: {
  actorId: string;
  allowLateCancel?: boolean;
  allowOutsideHours?: boolean;
  allowOverbook?: boolean;
  allowTransfer?: boolean;
  expectedVersion?: number;
  holdTtlSeconds: number;
  reason?: string;
}): Promise<{
  amountOwedCents: number | null;
  bookingTypeId: string;
  bookingTypeVersionId: string;
  capacityUnits: number;
  createdAt: Date;
  createdBy: string | null;
  currency: string | null;
  deletedAt: Date | null;
  deletedBy: string | null;
  groupId: string | null;
  holdExpiresAt: Date | null;
  id: string;
  organizationId: string;
  origin: BookingOrigin;
  paid: boolean;
  partyEmail: string | null;
  partyName: string | null;
  partyRef: string | null;
  payload: JsonValue;
  paymentRef: string | null;
  pendingExpiresAt: Date | null;
  status: BookingStatus;
  statusUpdatedAt: Date;
  statusUpdatedBy: string | null;
  supersededById: string | null;
  uid: string;
  updatedAt: Date;
  updatedBy: string | null;
  version: number;
}>;

Defined in: server/bookings/booking-service.ts:260

draft→held: sets holdExpiresAt = now + ttl in the same CAS update.

Parameters

ParameterTypeDescription
bookingIdstring-
opts{ actorId: string; allowLateCancel?: boolean; allowOutsideHours?: boolean; allowOverbook?: boolean; allowTransfer?: boolean; expectedVersion?: number; holdTtlSeconds: number; reason?: string; }-
opts.actorIdstring-
opts.allowLateCancel?booleanAdmin late-cancel override (spec §7): when true, cancel skips the rules-engine cancellation policy guard and records a cancelled_by_admin timeline event instead — the same bypass-and-record contract as allowOverbook (§6.6). The CONSUMER owns the permission decision; taproot only honors + records the flag. Ignored on every event other than cancel.
opts.allowOutsideHours?booleanAdmin outside-hours override (spec §6.9): when true, claiming transitions skip the window-containment check and record an hours_overridden_by_admin timeline event instead — the same bypass-and-record contract as allowOverbook. The CONSUMER owns the permission decision.
opts.allowOverbook?booleanAdmin overbook override (spec §6.6): when true, claiming transitions skip the capacity/overlap check and record an overbooked_by_admin timeline event instead. The CONSUMER owns the permission decision — taproot is auth-agnostic and only honors + records the flag.
opts.allowTransfer?booleanAdmin transfer override (spec §7.1): when true, the transfer/reschedule family skips the rules-engine policy guard for the transfer event and records a transfer_overridden_by_admin timeline event instead — the same bypass-and-record contract as allowLateCancel/allowOverbook. The CONSUMER owns the permission decision; taproot only honors + records the flag. Ignored on every event other than transfer.
opts.expectedVersion?number-
opts.holdTtlSecondsnumber-
opts.reason?string-

Returns

Promise<{ amountOwedCents: number | null; bookingTypeId: string; bookingTypeVersionId: string; capacityUnits: number; createdAt: Date; createdBy: string | null; currency: string | null; deletedAt: Date | null; deletedBy: string | null; groupId: string | null; holdExpiresAt: Date | null; id: string; organizationId: string; origin: BookingOrigin; paid: boolean; partyEmail: string | null; partyName: string | null; partyRef: string | null; payload: JsonValue; paymentRef: string | null; pendingExpiresAt: Date | null; status: BookingStatus; statusUpdatedAt: Date; statusUpdatedBy: string | null; supersededById: string | null; uid: string; updatedAt: Date; updatedBy: string | null; version: number; }>

Inherited from

BookingService.hold


holdMany()

holdMany(bookingIds: readonly string[], opts: {
  actorId: string;
  allowLateCancel?: boolean;
  allowOutsideHours?: boolean;
  allowOverbook?: boolean;
  allowTransfer?: boolean;
  expectedVersion?: number;
  holdTtlSeconds: number;
  reason?: string;
}): Promise<{
  amountOwedCents: number | null;
  bookingTypeId: string;
  bookingTypeVersionId: string;
  capacityUnits: number;
  createdAt: Date;
  createdBy: string | null;
  currency: string | null;
  deletedAt: Date | null;
  deletedBy: string | null;
  groupId: string | null;
  holdExpiresAt: Date | null;
  id: string;
  organizationId: string;
  origin: BookingOrigin;
  paid: boolean;
  partyEmail: string | null;
  partyName: string | null;
  partyRef: string | null;
  payload: JsonValue;
  paymentRef: string | null;
  pendingExpiresAt: Date | null;
  status: BookingStatus;
  statusUpdatedAt: Date;
  statusUpdatedBy: string | null;
  supersededById: string | null;
  uid: string;
  updatedAt: Date;
  updatedBy: string | null;
  version: number;
}[]>;

Defined in: server/bookings/booking-service.ts:272

Batch hold (§6.10): one transaction, one savepoint, all-or-none. Every member's structural + capacity check is evaluated BEFORE any transition applies, and the whole group shares ONE holdExpiresAt stamp so the hold sweeper can expire it as a unit.

Parameters

ParameterTypeDescription
bookingIdsreadonly string[]-
opts{ actorId: string; allowLateCancel?: boolean; allowOutsideHours?: boolean; allowOverbook?: boolean; allowTransfer?: boolean; expectedVersion?: number; holdTtlSeconds: number; reason?: string; }-
opts.actorIdstring-
opts.allowLateCancel?booleanAdmin late-cancel override (spec §7): when true, cancel skips the rules-engine cancellation policy guard and records a cancelled_by_admin timeline event instead — the same bypass-and-record contract as allowOverbook (§6.6). The CONSUMER owns the permission decision; taproot only honors + records the flag. Ignored on every event other than cancel.
opts.allowOutsideHours?booleanAdmin outside-hours override (spec §6.9): when true, claiming transitions skip the window-containment check and record an hours_overridden_by_admin timeline event instead — the same bypass-and-record contract as allowOverbook. The CONSUMER owns the permission decision.
opts.allowOverbook?booleanAdmin overbook override (spec §6.6): when true, claiming transitions skip the capacity/overlap check and record an overbooked_by_admin timeline event instead. The CONSUMER owns the permission decision — taproot is auth-agnostic and only honors + records the flag.
opts.allowTransfer?booleanAdmin transfer override (spec §7.1): when true, the transfer/reschedule family skips the rules-engine policy guard for the transfer event and records a transfer_overridden_by_admin timeline event instead — the same bypass-and-record contract as allowLateCancel/allowOverbook. The CONSUMER owns the permission decision; taproot only honors + records the flag. Ignored on every event other than transfer.
opts.expectedVersion?number-
opts.holdTtlSecondsnumber-
opts.reason?string-

Returns

Promise<{ amountOwedCents: number | null; bookingTypeId: string; bookingTypeVersionId: string; capacityUnits: number; createdAt: Date; createdBy: string | null; currency: string | null; deletedAt: Date | null; deletedBy: string | null; groupId: string | null; holdExpiresAt: Date | null; id: string; organizationId: string; origin: BookingOrigin; paid: boolean; partyEmail: string | null; partyName: string | null; partyRef: string | null; payload: JsonValue; paymentRef: string | null; pendingExpiresAt: Date | null; status: BookingStatus; statusUpdatedAt: Date; statusUpdatedBy: string | null; supersededById: string | null; uid: string; updatedAt: Date; updatedBy: string | null; version: number; }[]>

Inherited from

BookingService.holdMany


machineFor()

protected machineFor(vertical: string): ErasedMachine;

Defined in: server/bookings/booking-service.ts:138

Checked vertical → composed-machine lookup; throws UnknownBookingTypeError.

Parameters

ParameterType
verticalstring

Returns

ErasedMachine

Inherited from

BookingService.machineFor


markNoShow()

markNoShow(bookingId: string, opts: {
  actorId: string;
  allowLateCancel?: boolean;
  allowOutsideHours?: boolean;
  allowOverbook?: boolean;
  allowTransfer?: boolean;
  expectedVersion?: number;
  reason?: string;
}): Promise<{
  amountOwedCents: number | null;
  bookingTypeId: string;
  bookingTypeVersionId: string;
  capacityUnits: number;
  createdAt: Date;
  createdBy: string | null;
  currency: string | null;
  deletedAt: Date | null;
  deletedBy: string | null;
  groupId: string | null;
  holdExpiresAt: Date | null;
  id: string;
  organizationId: string;
  origin: BookingOrigin;
  paid: boolean;
  partyEmail: string | null;
  partyName: string | null;
  partyRef: string | null;
  payload: JsonValue;
  paymentRef: string | null;
  pendingExpiresAt: Date | null;
  status: BookingStatus;
  statusUpdatedAt: Date;
  statusUpdatedBy: string | null;
  supersededById: string | null;
  uid: string;
  updatedAt: Date;
  updatedBy: string | null;
  version: number;
}>;

Defined in: server/bookings/booking-service.ts:409

Parameters

ParameterTypeDescription
bookingIdstring-
opts{ actorId: string; allowLateCancel?: boolean; allowOutsideHours?: boolean; allowOverbook?: boolean; allowTransfer?: boolean; expectedVersion?: number; reason?: string; }-
opts.actorIdstring-
opts.allowLateCancel?booleanAdmin late-cancel override (spec §7): when true, cancel skips the rules-engine cancellation policy guard and records a cancelled_by_admin timeline event instead — the same bypass-and-record contract as allowOverbook (§6.6). The CONSUMER owns the permission decision; taproot only honors + records the flag. Ignored on every event other than cancel.
opts.allowOutsideHours?booleanAdmin outside-hours override (spec §6.9): when true, claiming transitions skip the window-containment check and record an hours_overridden_by_admin timeline event instead — the same bypass-and-record contract as allowOverbook. The CONSUMER owns the permission decision.
opts.allowOverbook?booleanAdmin overbook override (spec §6.6): when true, claiming transitions skip the capacity/overlap check and record an overbooked_by_admin timeline event instead. The CONSUMER owns the permission decision — taproot is auth-agnostic and only honors + records the flag.
opts.allowTransfer?booleanAdmin transfer override (spec §7.1): when true, the transfer/reschedule family skips the rules-engine policy guard for the transfer event and records a transfer_overridden_by_admin timeline event instead — the same bypass-and-record contract as allowLateCancel/allowOverbook. The CONSUMER owns the permission decision; taproot only honors + records the flag. Ignored on every event other than transfer.
opts.expectedVersion?number-
opts.reason?string-

Returns

Promise<{ amountOwedCents: number | null; bookingTypeId: string; bookingTypeVersionId: string; capacityUnits: number; createdAt: Date; createdBy: string | null; currency: string | null; deletedAt: Date | null; deletedBy: string | null; groupId: string | null; holdExpiresAt: Date | null; id: string; organizationId: string; origin: BookingOrigin; paid: boolean; partyEmail: string | null; partyName: string | null; partyRef: string | null; payload: JsonValue; paymentRef: string | null; pendingExpiresAt: Date | null; status: BookingStatus; statusUpdatedAt: Date; statusUpdatedBy: string | null; supersededById: string | null; uid: string; updatedAt: Date; updatedBy: string | null; version: number; }>

Inherited from

BookingService.markNoShow


markNoShowBySystem()

markNoShowBySystem(bookingId: string, opts: {
  actorId: string | null;
  expectedVersion?: number;
  idempotencyKey?: string;
}): Promise<{
  amountOwedCents: number | null;
  bookingTypeId: string;
  bookingTypeVersionId: string;
  capacityUnits: number;
  createdAt: Date;
  createdBy: string | null;
  currency: string | null;
  deletedAt: Date | null;
  deletedBy: string | null;
  groupId: string | null;
  holdExpiresAt: Date | null;
  id: string;
  organizationId: string;
  origin: BookingOrigin;
  paid: boolean;
  partyEmail: string | null;
  partyName: string | null;
  partyRef: string | null;
  payload: JsonValue;
  paymentRef: string | null;
  pendingExpiresAt: Date | null;
  status: BookingStatus;
  statusUpdatedAt: Date;
  statusUpdatedBy: string | null;
  supersededById: string | null;
  uid: string;
  updatedAt: Date;
  updatedBy: string | null;
  version: number;
}>;

Defined in: server/bookings/booking-service.ts:487

System-actor confirmed→no_show transition used by the no-show sweeper (§11). No structural guard beyond status check — the sweeper is responsible for enforcing the grace window before calling this.

Parameters

ParameterType
bookingIdstring
opts{ actorId: string | null; expectedVersion?: number; idempotencyKey?: string; }
opts.actorIdstring | null
opts.expectedVersion?number
opts.idempotencyKey?string

Returns

Promise<{ amountOwedCents: number | null; bookingTypeId: string; bookingTypeVersionId: string; capacityUnits: number; createdAt: Date; createdBy: string | null; currency: string | null; deletedAt: Date | null; deletedBy: string | null; groupId: string | null; holdExpiresAt: Date | null; id: string; organizationId: string; origin: BookingOrigin; paid: boolean; partyEmail: string | null; partyName: string | null; partyRef: string | null; payload: JsonValue; paymentRef: string | null; pendingExpiresAt: Date | null; status: BookingStatus; statusUpdatedAt: Date; statusUpdatedBy: string | null; supersededById: string | null; uid: string; updatedAt: Date; updatedBy: string | null; version: number; }>

Inherited from

BookingService.markNoShowBySystem


reject()

reject(bookingId: string, opts: {
  actorId: string;
  allowLateCancel?: boolean;
  allowOutsideHours?: boolean;
  allowOverbook?: boolean;
  allowTransfer?: boolean;
  expectedVersion?: number;
  reason?: string;
}): Promise<{
  amountOwedCents: number | null;
  bookingTypeId: string;
  bookingTypeVersionId: string;
  capacityUnits: number;
  createdAt: Date;
  createdBy: string | null;
  currency: string | null;
  deletedAt: Date | null;
  deletedBy: string | null;
  groupId: string | null;
  holdExpiresAt: Date | null;
  id: string;
  organizationId: string;
  origin: BookingOrigin;
  paid: boolean;
  partyEmail: string | null;
  partyName: string | null;
  partyRef: string | null;
  payload: JsonValue;
  paymentRef: string | null;
  pendingExpiresAt: Date | null;
  status: BookingStatus;
  statusUpdatedAt: Date;
  statusUpdatedBy: string | null;
  supersededById: string | null;
  uid: string;
  updatedAt: Date;
  updatedBy: string | null;
  version: number;
}>;

Defined in: server/bookings/booking-service.ts:393

Parameters

ParameterTypeDescription
bookingIdstring-
opts{ actorId: string; allowLateCancel?: boolean; allowOutsideHours?: boolean; allowOverbook?: boolean; allowTransfer?: boolean; expectedVersion?: number; reason?: string; }-
opts.actorIdstring-
opts.allowLateCancel?booleanAdmin late-cancel override (spec §7): when true, cancel skips the rules-engine cancellation policy guard and records a cancelled_by_admin timeline event instead — the same bypass-and-record contract as allowOverbook (§6.6). The CONSUMER owns the permission decision; taproot only honors + records the flag. Ignored on every event other than cancel.
opts.allowOutsideHours?booleanAdmin outside-hours override (spec §6.9): when true, claiming transitions skip the window-containment check and record an hours_overridden_by_admin timeline event instead — the same bypass-and-record contract as allowOverbook. The CONSUMER owns the permission decision.
opts.allowOverbook?booleanAdmin overbook override (spec §6.6): when true, claiming transitions skip the capacity/overlap check and record an overbooked_by_admin timeline event instead. The CONSUMER owns the permission decision — taproot is auth-agnostic and only honors + records the flag.
opts.allowTransfer?booleanAdmin transfer override (spec §7.1): when true, the transfer/reschedule family skips the rules-engine policy guard for the transfer event and records a transfer_overridden_by_admin timeline event instead — the same bypass-and-record contract as allowLateCancel/allowOverbook. The CONSUMER owns the permission decision; taproot only honors + records the flag. Ignored on every event other than transfer.
opts.expectedVersion?number-
opts.reason?string-

Returns

Promise<{ amountOwedCents: number | null; bookingTypeId: string; bookingTypeVersionId: string; capacityUnits: number; createdAt: Date; createdBy: string | null; currency: string | null; deletedAt: Date | null; deletedBy: string | null; groupId: string | null; holdExpiresAt: Date | null; id: string; organizationId: string; origin: BookingOrigin; paid: boolean; partyEmail: string | null; partyName: string | null; partyRef: string | null; payload: JsonValue; paymentRef: string | null; pendingExpiresAt: Date | null; status: BookingStatus; statusUpdatedAt: Date; statusUpdatedBy: string | null; supersededById: string | null; uid: string; updatedAt: Date; updatedBy: string | null; version: number; }>

Inherited from

BookingService.reject


reschedule()

reschedule(bookingId: string, opts: {
  actorId: string;
  allowLateCancel?: boolean;
  allowOutsideHours?: boolean;
  allowOverbook?: boolean;
  allowTransfer?: boolean;
  endsAt?: Date;
  expectedVersion?: number;
  reason?: string;
  resourceId?: string;
  startsAt?: Date;
  timeZone?: string;
}): Promise<{
  amountOwedCents: number | null;
  bookingTypeId: string;
  bookingTypeVersionId: string;
  capacityUnits: number;
  createdAt: Date;
  createdBy: string | null;
  currency: string | null;
  deletedAt: Date | null;
  deletedBy: string | null;
  groupId: string | null;
  holdExpiresAt: Date | null;
  id: string;
  organizationId: string;
  origin: BookingOrigin;
  paid: boolean;
  partyEmail: string | null;
  partyName: string | null;
  partyRef: string | null;
  payload: JsonValue;
  paymentRef: string | null;
  pendingExpiresAt: Date | null;
  status: BookingStatus;
  statusUpdatedAt: Date;
  statusUpdatedBy: string | null;
  supersededById: string | null;
  uid: string;
  updatedAt: Date;
  updatedBy: string | null;
  version: number;
}>;

Defined in: server/bookings/transfer-service.ts:186

Reschedule convenience wrapper (§7.1/§11): a slot-only transfer. The source carries a rescheduled (not transferred) event.

Parameters

ParameterTypeDescription
bookingIdstring-
opts{ actorId: string; allowLateCancel?: boolean; allowOutsideHours?: boolean; allowOverbook?: boolean; allowTransfer?: boolean; endsAt?: Date; expectedVersion?: number; reason?: string; resourceId?: string; startsAt?: Date; timeZone?: string; }-
opts.actorIdstring-
opts.allowLateCancel?booleanAdmin late-cancel override (spec §7): when true, cancel skips the rules-engine cancellation policy guard and records a cancelled_by_admin timeline event instead — the same bypass-and-record contract as allowOverbook (§6.6). The CONSUMER owns the permission decision; taproot only honors + records the flag. Ignored on every event other than cancel.
opts.allowOutsideHours?booleanAdmin outside-hours override (spec §6.9): when true, claiming transitions skip the window-containment check and record an hours_overridden_by_admin timeline event instead — the same bypass-and-record contract as allowOverbook. The CONSUMER owns the permission decision.
opts.allowOverbook?booleanAdmin overbook override (spec §6.6): when true, claiming transitions skip the capacity/overlap check and record an overbooked_by_admin timeline event instead. The CONSUMER owns the permission decision — taproot is auth-agnostic and only honors + records the flag.
opts.allowTransfer?booleanAdmin transfer override (spec §7.1): when true, the transfer/reschedule family skips the rules-engine policy guard for the transfer event and records a transfer_overridden_by_admin timeline event instead — the same bypass-and-record contract as allowLateCancel/allowOverbook. The CONSUMER owns the permission decision; taproot only honors + records the flag. Ignored on every event other than transfer.
opts.endsAt?Date-
opts.expectedVersion?number-
opts.reason?string-
opts.resourceId?string-
opts.startsAt?Date-
opts.timeZone?string-

Returns

Promise<{ amountOwedCents: number | null; bookingTypeId: string; bookingTypeVersionId: string; capacityUnits: number; createdAt: Date; createdBy: string | null; currency: string | null; deletedAt: Date | null; deletedBy: string | null; groupId: string | null; holdExpiresAt: Date | null; id: string; organizationId: string; origin: BookingOrigin; paid: boolean; partyEmail: string | null; partyName: string | null; partyRef: string | null; payload: JsonValue; paymentRef: string | null; pendingExpiresAt: Date | null; status: BookingStatus; statusUpdatedAt: Date; statusUpdatedBy: string | null; supersededById: string | null; uid: string; updatedAt: Date; updatedBy: string | null; version: number; }>


submit()

submit(bookingId: string, opts: {
  actorId: string;
  allowLateCancel?: boolean;
  allowOutsideHours?: boolean;
  allowOverbook?: boolean;
  allowTransfer?: boolean;
  expectedVersion?: number;
  reason?: string;
}): Promise<{
  amountOwedCents: number | null;
  bookingTypeId: string;
  bookingTypeVersionId: string;
  capacityUnits: number;
  createdAt: Date;
  createdBy: string | null;
  currency: string | null;
  deletedAt: Date | null;
  deletedBy: string | null;
  groupId: string | null;
  holdExpiresAt: Date | null;
  id: string;
  organizationId: string;
  origin: BookingOrigin;
  paid: boolean;
  partyEmail: string | null;
  partyName: string | null;
  partyRef: string | null;
  payload: JsonValue;
  paymentRef: string | null;
  pendingExpiresAt: Date | null;
  status: BookingStatus;
  statusUpdatedAt: Date;
  statusUpdatedBy: string | null;
  supersededById: string | null;
  uid: string;
  updatedAt: Date;
  updatedBy: string | null;
  version: number;
}>;

Defined in: server/bookings/booking-service.ts:358

draft→pending — a CLAIMING transition (§6.6 truth table: pending BLOCKS capacity), so it runs the claim path: overlap-set lock + batch capacity check + window containment. On the old non-claiming path two concurrent submits could both reach pending and double-book the slot.

Parameters

ParameterTypeDescription
bookingIdstring-
opts{ actorId: string; allowLateCancel?: boolean; allowOutsideHours?: boolean; allowOverbook?: boolean; allowTransfer?: boolean; expectedVersion?: number; reason?: string; }-
opts.actorIdstring-
opts.allowLateCancel?booleanAdmin late-cancel override (spec §7): when true, cancel skips the rules-engine cancellation policy guard and records a cancelled_by_admin timeline event instead — the same bypass-and-record contract as allowOverbook (§6.6). The CONSUMER owns the permission decision; taproot only honors + records the flag. Ignored on every event other than cancel.
opts.allowOutsideHours?booleanAdmin outside-hours override (spec §6.9): when true, claiming transitions skip the window-containment check and record an hours_overridden_by_admin timeline event instead — the same bypass-and-record contract as allowOverbook. The CONSUMER owns the permission decision.
opts.allowOverbook?booleanAdmin overbook override (spec §6.6): when true, claiming transitions skip the capacity/overlap check and record an overbooked_by_admin timeline event instead. The CONSUMER owns the permission decision — taproot is auth-agnostic and only honors + records the flag.
opts.allowTransfer?booleanAdmin transfer override (spec §7.1): when true, the transfer/reschedule family skips the rules-engine policy guard for the transfer event and records a transfer_overridden_by_admin timeline event instead — the same bypass-and-record contract as allowLateCancel/allowOverbook. The CONSUMER owns the permission decision; taproot only honors + records the flag. Ignored on every event other than transfer.
opts.expectedVersion?number-
opts.reason?string-

Returns

Promise<{ amountOwedCents: number | null; bookingTypeId: string; bookingTypeVersionId: string; capacityUnits: number; createdAt: Date; createdBy: string | null; currency: string | null; deletedAt: Date | null; deletedBy: string | null; groupId: string | null; holdExpiresAt: Date | null; id: string; organizationId: string; origin: BookingOrigin; paid: boolean; partyEmail: string | null; partyName: string | null; partyRef: string | null; payload: JsonValue; paymentRef: string | null; pendingExpiresAt: Date | null; status: BookingStatus; statusUpdatedAt: Date; statusUpdatedBy: string | null; supersededById: string | null; uid: string; updatedAt: Date; updatedBy: string | null; version: number; }>

Inherited from

BookingService.submit


toHost()

protected toHost(b: ComposedBookingRow): ErasedBookingHost;

Defined in: server/bookings/booking-service.ts:981

Map the hydrated row to the composed host the machine guards read. startsAt/endsAt/timeZone/resourceId are sourced from the joined schedule row (§5.2 hydration spec). When no schedule exists (draft with no schedule), endsAt is undefined and the completable guard (endsAt <= now) correctly fails, so complete is unreachable — by design.

offerExpiresAt is surfaced from the ACTIVE waitlist offer row (§6.4) so the §5.2 offered→confirmed structural guard reads the real accept-by deadline off the host — not undefined from a bare row (a hydration bug). offers is filtered to active rows at hydration; the single offered/ queued row's deadline (or null when none) is what the guard sees. Protected so the transfer family (§7.1) reuses the same hydration.

Parameters

ParameterType
bComposedBookingRow

Returns

ErasedBookingHost

Inherited from

BookingService.toHost


transfer()

transfer(bookingId: string, opts: Omit<{
  actorId: string;
  allowLateCancel?: boolean;
  allowOutsideHours?: boolean;
  allowOverbook?: boolean;
  allowTransfer?: boolean;
  expectedVersion?: number;
  reason?: string;
  to: {
     bookingTypeId?: string;
     capacityUnits?: number;
     groupId?: string | null;
     partyEmail?: string | null;
     partyName?: string | null;
     partyRef?: string | null;
     schedule?: {
        endsAt?: Date;
        resourceId?: string;
        startsAt?: Date;
        timeZone?: string;
     };
  };
}, "to"> & {
  to: {
     bookingTypeId?: string;
     capacityUnits?: number;
     groupId?: string | null;
     partyEmail?: string | null;
     partyName?: string | null;
     partyRef?: string | null;
     schedule?: {
        endsAt?: Date;
        resourceId?: string;
        startsAt?: Date;
        timeZone?: string;
     };
  };
}): Promise<{
  amountOwedCents: number | null;
  bookingTypeId: string;
  bookingTypeVersionId: string;
  capacityUnits: number;
  createdAt: Date;
  createdBy: string | null;
  currency: string | null;
  deletedAt: Date | null;
  deletedBy: string | null;
  groupId: string | null;
  holdExpiresAt: Date | null;
  id: string;
  organizationId: string;
  origin: BookingOrigin;
  paid: boolean;
  partyEmail: string | null;
  partyName: string | null;
  partyRef: string | null;
  payload: JsonValue;
  paymentRef: string | null;
  pendingExpiresAt: Date | null;
  status: BookingStatus;
  statusUpdatedAt: Date;
  statusUpdatedBy: string | null;
  supersededById: string | null;
  uid: string;
  updatedAt: Date;
  updatedBy: string | null;
  version: number;
}>;

Defined in: server/bookings/transfer-service.ts:167

Transfer one booking along the to delta (§7.1) — returns the successor (or the same booking for an in-place repoint). The batch of one.

Parameters

ParameterType
bookingIdstring
optsOmit<{ actorId: string; allowLateCancel?: boolean; allowOutsideHours?: boolean; allowOverbook?: boolean; allowTransfer?: boolean; expectedVersion?: number; reason?: string; to: { bookingTypeId?: string; capacityUnits?: number; groupId?: string | null; partyEmail?: string | null; partyName?: string | null; partyRef?: string | null; schedule?: { endsAt?: Date; resourceId?: string; startsAt?: Date; timeZone?: string; }; }; }, "to"> & { to: { bookingTypeId?: string; capacityUnits?: number; groupId?: string | null; partyEmail?: string | null; partyName?: string | null; partyRef?: string | null; schedule?: { endsAt?: Date; resourceId?: string; startsAt?: Date; timeZone?: string; }; }; }

Returns

Promise<{ amountOwedCents: number | null; bookingTypeId: string; bookingTypeVersionId: string; capacityUnits: number; createdAt: Date; createdBy: string | null; currency: string | null; deletedAt: Date | null; deletedBy: string | null; groupId: string | null; holdExpiresAt: Date | null; id: string; organizationId: string; origin: BookingOrigin; paid: boolean; partyEmail: string | null; partyName: string | null; partyRef: string | null; payload: JsonValue; paymentRef: string | null; pendingExpiresAt: Date | null; status: BookingStatus; statusUpdatedAt: Date; statusUpdatedBy: string | null; supersededById: string | null; uid: string; updatedAt: Date; updatedBy: string | null; version: number; }>


transferMany()

transferMany(members: readonly TransferMember[], opts: {
  actorId: string;
  allowLateCancel?: boolean;
  allowOutsideHours?: boolean;
  allowOverbook?: boolean;
  allowTransfer?: boolean;
  expectedVersion?: number;
  reason?: string;
}): Promise<{
  amountOwedCents: number | null;
  bookingTypeId: string;
  bookingTypeVersionId: string;
  capacityUnits: number;
  createdAt: Date;
  createdBy: string | null;
  currency: string | null;
  deletedAt: Date | null;
  deletedBy: string | null;
  groupId: string | null;
  holdExpiresAt: Date | null;
  id: string;
  organizationId: string;
  origin: BookingOrigin;
  paid: boolean;
  partyEmail: string | null;
  partyName: string | null;
  partyRef: string | null;
  payload: JsonValue;
  paymentRef: string | null;
  pendingExpiresAt: Date | null;
  status: BookingStatus;
  statusUpdatedAt: Date;
  statusUpdatedBy: string | null;
  supersededById: string | null;
  uid: string;
  updatedAt: Date;
  updatedBy: string | null;
  version: number;
}[]>;

Defined in: server/bookings/transfer-service.ts:212

Move a batch of bookings atomically (§7.1): all-or-none, savepoint- wrapped, capacity-checked over the UNION overlap set with excludeBookingIds = the sources — the wedding (hall + kitchen + parking) moves whole or not at all. Returns the successors (or the same booking for in-place members) in member order.

Parameters

ParameterTypeDescription
membersreadonly TransferMember[]-
opts{ actorId: string; allowLateCancel?: boolean; allowOutsideHours?: boolean; allowOverbook?: boolean; allowTransfer?: boolean; expectedVersion?: number; reason?: string; }-
opts.actorIdstring-
opts.allowLateCancel?booleanAdmin late-cancel override (spec §7): when true, cancel skips the rules-engine cancellation policy guard and records a cancelled_by_admin timeline event instead — the same bypass-and-record contract as allowOverbook (§6.6). The CONSUMER owns the permission decision; taproot only honors + records the flag. Ignored on every event other than cancel.
opts.allowOutsideHours?booleanAdmin outside-hours override (spec §6.9): when true, claiming transitions skip the window-containment check and record an hours_overridden_by_admin timeline event instead — the same bypass-and-record contract as allowOverbook. The CONSUMER owns the permission decision.
opts.allowOverbook?booleanAdmin overbook override (spec §6.6): when true, claiming transitions skip the capacity/overlap check and record an overbooked_by_admin timeline event instead. The CONSUMER owns the permission decision — taproot is auth-agnostic and only honors + records the flag.
opts.allowTransfer?booleanAdmin transfer override (spec §7.1): when true, the transfer/reschedule family skips the rules-engine policy guard for the transfer event and records a transfer_overridden_by_admin timeline event instead — the same bypass-and-record contract as allowLateCancel/allowOverbook. The CONSUMER owns the permission decision; taproot only honors + records the flag. Ignored on every event other than transfer.
opts.expectedVersion?number-
opts.reason?string-

Returns

Promise<{ amountOwedCents: number | null; bookingTypeId: string; bookingTypeVersionId: string; capacityUnits: number; createdAt: Date; createdBy: string | null; currency: string | null; deletedAt: Date | null; deletedBy: string | null; groupId: string | null; holdExpiresAt: Date | null; id: string; organizationId: string; origin: BookingOrigin; paid: boolean; partyEmail: string | null; partyName: string | null; partyRef: string | null; payload: JsonValue; paymentRef: string | null; pendingExpiresAt: Date | null; status: BookingStatus; statusUpdatedAt: Date; statusUpdatedBy: string | null; supersededById: string | null; uid: string; updatedAt: Date; updatedBy: string | null; version: number; }[]>

On this page