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[] }>| Parameter | Type | Description |
|---|---|---|
entityType | 'instructor' | 'room' | Type of entity to check |
entityId | string | ID of the entity |
start | Date | Proposed start time |
durationMin | number | Duration 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[]>| Parameter | Type | Description |
|---|---|---|
entityType | 'instructor' | 'room' | Type of entity |
entityId | string | ID of the entity |
dateRange | DateRange | The range to search within |
minDurationMin | number | Minimum 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