My App
RoomKitBackend

BookingService

Create, manage, and query room bookings

Overview

BookingService is the primary service for booking lifecycle management. It handles creation with idempotency and atomic conflict checking, state transitions, optimistic concurrency on modifications, delegation, and person/room queries.

import { BookingService } from '@roomkit/nestjs';

Methods

create

Create a new booking. Validates the time range, checks idempotency, resolves the priority tier, and creates the booking with an atomic conflict check. Emits BookingRequested on success.

async create(dto: CreateBookingDto): Promise<Booking>
ParameterTypeDescription
dtoCreateBookingDtoBooking creation data
const booking = await bookingService.create({
    roomId: 'room-a1',
    personId: 'user-42',
    title: 'Project Standup',
    startsAt: new Date('2026-03-02T09:00:00'),
    endsAt: new Date('2026-03-02T09:30:00'),
    priorityName: 'standard',
    idempotencyKey: 'standup-2026-03-02',
});

Throws InvalidTimeRangeError if endsAt is not after startsAt.

Throws RoomNotFoundError if the room does not exist.

Throws BookingConflictError if the room has an overlapping booking.

confirm

Transition a booking from REQUESTED to CONFIRMED. Emits BookingConfirmed.

async confirm(id: string, triggeredBy: string): Promise<Booking>
ParameterTypeDescription
idstringBooking ID
triggeredBystringID of the user or system triggering the transition
const confirmed = await bookingService.confirm('booking-1', 'admin-5');

Throws BookingNotFoundError if the booking does not exist.

Throws InvalidStateTransitionError if the booking is not in REQUESTED state.

checkIn

Transition a booking from CONFIRMED to IN_PROGRESS. Emits BookingStarted.

async checkIn(id: string, triggeredBy: string): Promise<Booking>
ParameterTypeDescription
idstringBooking ID
triggeredBystringID of the user or system triggering the transition
const active = await bookingService.checkIn('booking-1', 'user-42');

Throws BookingNotFoundError if the booking does not exist.

Throws InvalidStateTransitionError if the booking is not in CONFIRMED state.

complete

Transition a booking from IN_PROGRESS to COMPLETED. Emits BookingCompleted.

async complete(id: string, triggeredBy: string): Promise<Booking>
ParameterTypeDescription
idstringBooking ID
triggeredBystringID of the user or system triggering the transition
const done = await bookingService.complete('booking-1', 'user-42');

Throws BookingNotFoundError if the booking does not exist.

Throws InvalidStateTransitionError if the booking is not in IN_PROGRESS state.

cancel

Cancel a booking from any non-terminal state. Emits BookingCancelled.

async cancel(id: string, triggeredBy: string, reason?: string): Promise<Booking>
ParameterTypeDescription
idstringBooking ID
triggeredBystringID of the user or system triggering the cancellation
reasonstringOptional cancellation reason
const cancelled = await bookingService.cancel('booking-1', 'admin-5', 'Room maintenance');

Throws BookingNotFoundError if the booking does not exist.

Throws InvalidStateTransitionError if the booking is already in a terminal state (COMPLETED or CANCELLED).

modify

Update a booking with optimistic concurrency control. Re-checks conflicts when the time range or room changes. Emits BookingModified.

async modify(id: string, changes: UpdateBookingDto, expectedVersion: number): Promise<Booking>
ParameterTypeDescription
idstringBooking ID
changesUpdateBookingDtoFields to update
expectedVersionnumberExpected version for optimistic locking
const updated = await bookingService.modify(
    'booking-1',
    {
        startsAt: new Date('2026-03-02T10:00:00'),
        endsAt: new Date('2026-03-02T10:30:00'),
    },
    1, // expectedVersion
);

Throws BookingNotFoundError if the booking does not exist.

Throws BookingConflictError if the updated time/room has an overlapping booking.

delegate

Update the delegation of a booking to another person. Emits BookingModified.

async delegate(id: string, onBehalfOfId: string, triggeredBy: string): Promise<Booking>
ParameterTypeDescription
idstringBooking ID
onBehalfOfIdstringID of the person the booking is being delegated to
triggeredBystringID of the user performing the delegation
const delegated = await bookingService.delegate('booking-1', 'user-99', 'admin-5');

Throws BookingNotFoundError if the booking does not exist.

getByPerson

Retrieve bookings for a person within a time range.

async getByPerson(
    personId: string,
    timeRange: TimeRange,
    pagination?: Pagination,
): Promise<PaginatedResult<Booking>>
ParameterTypeDescription
personIdstringPerson ID
timeRangeTimeRangeStart and end dates to filter by
paginationPaginationOptional cursor-based pagination
const result = await bookingService.getByPerson('user-42', {
    startsAt: new Date('2026-03-01'),
    endsAt: new Date('2026-03-31'),
});

getByRoom

Retrieve bookings for a room within a time range.

async getByRoom(
    roomId: string,
    timeRange: TimeRange,
    pagination?: Pagination,
): Promise<PaginatedResult<Booking>>
ParameterTypeDescription
roomIdstringRoom ID
timeRangeTimeRangeStart and end dates to filter by
paginationPaginationOptional cursor-based pagination
const result = await bookingService.getByRoom('room-a1', {
    startsAt: new Date('2026-03-02'),
    endsAt: new Date('2026-03-02T23:59:59'),
});

getById

Retrieve a single booking by ID.

async getById(id: string): Promise<Booking | null>
ParameterTypeDescription
idstringBooking ID

Returns the booking or null if not found.

const booking = await bookingService.getById('booking-1');

On this page