My App
RoomKitBackend

BulkOperationService

Semester imports, date shifting, and batch cancellations

Overview

BulkOperationService handles large-scale booking operations such as semester imports, date shifting, and batch cancellations. Each operation is tracked as a BulkOperation with progress reporting and conflict counting.

Optional. Enable with features: { bulkOperations: true } in your module registration. Requires BulkOperationStorage to be provided.

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

Types

SemesterImportPayload

interface SemesterImportPayload {
    entries: {
        roomId: string;
        startsAt: Date;
        endsAt: Date;
        requesterId: string;
        purposeType: string;
        title: string;
        recurrence?: RecurrenceInput;
    }[];
}

BulkOperation

interface BulkOperation {
    id: string;
    type: 'semester_import' | 'date_shift' | 'batch_cancel';
    status: 'pending' | 'processing' | 'completed' | 'failed';
    totalItems: number;
    processedItems: number;
    conflictsDetected: number;
    resultSummary: Record<string, unknown>;
    triggeredBy: string;
    createdAt: Date;
    updatedAt: Date;
}

Methods

semesterImport

Create a bulk operation that imports an entire semester of bookings. Iterates through all entries in the payload. Entries with a recurrence field create recurring series via RecurrenceService; entries without create single bookings. Conflicts are counted but do not abort the operation.

Progress is emitted every 10 items via the BulkOperationProgress event. Emits BulkOperationCompleted when the import finishes.

async semesterImport(
    payload: SemesterImportPayload,
    triggeredBy: string,
): Promise<BulkOperation>
ParameterTypeDescription
payloadSemesterImportPayloadImport payload containing an array of booking entries
triggeredBystringID of the user or system triggering the import
const operation = await bulkOperationService.semesterImport(
    {
        entries: [
            {
                roomId: 'room-a1',
                startsAt: new Date('2026-09-01T09:00:00Z'),
                endsAt: new Date('2026-09-01T10:00:00Z'),
                requesterId: 'dept-cs',
                purposeType: 'LECTURE',
                title: 'CS 101 - Intro to Computer Science',
                recurrence: {
                    frequency: 'weekly',
                    interval: 1,
                    until: new Date('2026-12-15T10:00:00Z'),
                },
            },
            {
                roomId: 'room-b2',
                startsAt: new Date('2026-09-02T14:00:00Z'),
                endsAt: new Date('2026-09-02T15:30:00Z'),
                requesterId: 'dept-math',
                purposeType: 'SEMINAR',
                title: 'MATH 201 - Linear Algebra',
            },
        ],
    },
    'admin-1',
);

console.log(operation.status); // 'processing' or 'completed'
console.log(operation.conflictsDetected); // number of conflicts encountered

Throws BulkOperationPartialError if the operation completes with failures.

dateShift

Find matching bookings and shift each booking's start and end times by a number of days. Uses BookingService.modify with optimistic concurrency for each update. Emits BulkOperationProgress events during processing.

async dateShift(
    filter: {
        recurrenceRuleId?: string;
        roomId?: string;
        timeRange?: TimeRange;
    },
    shiftDays: number,
    triggeredBy: string,
): Promise<BulkOperation>
ParameterTypeDescription
filterobjectFilter criteria to select bookings for shifting
filter.recurrenceRuleIdstringOptional recurrence rule ID to match
filter.roomIdstringOptional room ID to match
filter.timeRangeTimeRangeOptional time range to match
shiftDaysnumberNumber of days to shift (positive = forward, negative = backward)
triggeredBystringID of the user or system triggering the shift
// Shift all bookings in room-a1 forward by 7 days
const operation = await bulkOperationService.dateShift(
    {
        roomId: 'room-a1',
        timeRange: {
            startsAt: new Date('2026-03-01'),
            endsAt: new Date('2026-06-30'),
        },
    },
    7,
    'admin-1',
);

batchCancel

Find all non-terminal bookings matching the filter and cancel each via BookingService.cancel. Emits BulkOperationProgress events during processing and BulkOperationCompleted when done.

async batchCancel(
    filter: {
        roomId?: string;
        timeRange?: TimeRange;
        requesterId?: string;
    },
    reason: string,
    triggeredBy: string,
): Promise<BulkOperation>
ParameterTypeDescription
filterobjectFilter criteria to select bookings for cancellation
filter.roomIdstringOptional room ID to match
filter.timeRangeTimeRangeOptional time range to match
filter.requesterIdstringOptional requester ID to match
reasonstringCancellation reason applied to each booking
triggeredBystringID of the user or system triggering the cancellation
// Cancel all bookings in a room due to renovation
const operation = await bulkOperationService.batchCancel(
    {
        roomId: 'room-a1',
        timeRange: {
            startsAt: new Date('2026-06-01'),
            endsAt: new Date('2026-08-31'),
        },
    },
    'Room under renovation',
    'facilities-admin',
);

console.log(operation.totalItems); // total bookings found
console.log(operation.processedItems); // bookings cancelled so far

On this page