My App
CourseKitBackend

AvailabilityService

Manage availability rules and check free slots for instructors and rooms

Overview

AvailabilityService provides CRUD operations for availability rules and methods to check whether entities are available at specific times. All mutations emit domain events.

import { AvailabilityService } from '@hfu.digital/coursekit-nestjs';

Methods

create

Create a new availability rule.

async create(data: Omit<Availability, 'id'>): Promise<Availability>

Emits DOMAIN_EVENTS.AVAILABILITY_CREATED.

const rule = await availability.create({
    entityType: 'instructor',
    entityId: 'instructor-1',
    dayOfWeek: 0, // Monday (0=Mon, 6=Sun)
    specificDate: null,
    startTime: new Date('2026-01-01T08:00:00'),
    endTime: new Date('2026-01-01T12:00:00'),
    type: 'available',
    hardness: 'hard',
    priority: 0,
    recurrenceRule: null,
});

update

Update an existing availability rule.

async update(id: string, data: Partial<Availability>): Promise<Availability>

Emits DOMAIN_EVENTS.AVAILABILITY_UPDATED with both previous and current values.

Throws if the availability rule is not found.

delete

Delete an availability rule.

async delete(id: string): Promise<void>

Emits DOMAIN_EVENTS.AVAILABILITY_DELETED.

Throws if the availability rule is not found.

isAvailable

Check if an entity is available at a specific time.

async isAvailable(
    entityType: AvailabilityEntityType,
    entityId: string,
    start: Date,
    durationMin: number,
): Promise<{ available: boolean; conflicts: Availability[] }>
ParameterTypeDescription
entityType'instructor' | 'room'Type of entity to check
entityIdstringID of the entity
startDateProposed start time
durationMinnumberDuration in minutes

Returns { available: true, conflicts: [] } when no blocking rules apply, or { available: false, conflicts: [...] } with the conflicting availability rules.

Hard blocks (hardness: 'hard') make the entity unavailable. Soft blocks are reported as conflicts but the entity is still considered available.

const result = await availability.isAvailable('instructor', 'inst-1', new Date('2026-03-02T14:00:00'), 90);
if (!result.available) {
    console.log('Blocked by:', result.conflicts);
}

findFreeSlots

Find free time slots for an entity within a date range.

async findFreeSlots(
    entityType: AvailabilityEntityType,
    entityId: string,
    dateRange: DateRange,
    minDurationMin: number,
): Promise<FreeSlot[]>
ParameterTypeDescription
entityType'instructor' | 'room'Type of entity
entityIdstringID of the entity
dateRangeDateRangeThe range to search within
minDurationMinnumberMinimum slot duration in minutes

Returns an array of FreeSlot objects representing gaps between hard-blocked intervals.

const slots = await availability.findFreeSlots('room', 'room-a1', {
    start: new Date('2026-03-02'),
    end: new Date('2026-03-03'),
}, 60); // At least 60-minute slots

On this page