My App
RoomKitBackend

BlackoutService

Create and manage blackout windows with impact analysis

Overview

BlackoutService manages blackout windows that block bookings for rooms, floors, buildings, campuses, or entire institutions. It supports impact analysis to identify existing bookings affected by a new blackout and cascades blackouts up the location hierarchy.

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

Methods

create

Create a new blackout window. Validates that startsAt is before endsAt and emits a BlackoutCreated domain event.

async create(data: Omit<BlackoutWindow, 'id' | 'createdAt'>): Promise<BlackoutWindow>
ParameterTypeDescription
dataOmit<BlackoutWindow, 'id' | 'createdAt'>Blackout window data

BlackoutWindow fields:

FieldTypeDescription
locationNodeIdstringThe location node this blackout applies to
scope'room' | 'floor' | 'building' | 'campus' | 'institution'Scope of the blackout
titlestringDisplay title for the blackout
reasonstring | nullOptional reason for the blackout
startsAtDateStart of the blackout window
endsAtDateEnd of the blackout window
isRecurringbooleanWhether the blackout recurs
recurrenceRuleIdstring | nullOptional recurrence rule ID
const blackout = await blackoutService.create({
    locationNodeId: 'building-science',
    scope: 'building',
    title: 'Annual Maintenance',
    reason: 'HVAC system replacement',
    startsAt: new Date('2026-07-01T00:00:00'),
    endsAt: new Date('2026-07-14T23:59:59'),
    isRecurring: false,
    recurrenceRuleId: null,
});

Throws InvalidTimeRangeError if startsAt is not before endsAt.

getActiveBlackouts

Get all active blackout windows for a location node within a time range. Cascades up the location hierarchy, so a blackout on a building also applies to all rooms within it.

async getActiveBlackouts(locationNodeId: string, timeRange: { start: Date; end: Date }): Promise<BlackoutWindow[]>
ParameterTypeDescription
locationNodeIdstringThe location node to check
timeRange{ start: Date; end: Date }Time range to check for active blackouts
const blackouts = await blackoutService.getActiveBlackouts('room-a1', {
    start: new Date('2026-07-01'),
    end: new Date('2026-07-31'),
});
// Returns blackouts on the room itself AND any ancestor nodes (floor, building, etc.)

analyzeImpact

Analyze the impact of a blackout window by resolving all descendant rooms and checking each for overlapping bookings. Emits a BlackoutImpactDetected domain event if any affected bookings are found.

async analyzeImpact(blackout: BlackoutWindow): Promise<Booking[]>
ParameterTypeDescription
blackoutBlackoutWindowThe blackout window to analyze

Returns an array of bookings that overlap with the blackout window.

const affectedBookings = await blackoutService.analyzeImpact(blackout);
if (affectedBookings.length > 0) {
    console.log(`${affectedBookings.length} bookings affected by blackout`);
    for (const booking of affectedBookings) {
        console.log(`- Booking ${booking.id} in room ${booking.roomId}`);
    }
}

delete

Delete a blackout window.

async delete(id: string): Promise<void>
ParameterTypeDescription
idstringThe blackout window ID
await blackoutService.delete('blackout-1');

On this page