All files / src/platform/calendar conflict-detection.service.ts

0% Statements 0/15
0% Branches 0/11
0% Functions 0/3
0% Lines 0/12

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61                                                                                                                         
import { Injectable, Logger } from '@nestjs/common';
import { AvailabilityEngine } from './availability.engine';
 
export interface ConflictResult {
  hasConflict: boolean;
  severity: 'warning' | 'blocking' | 'override_allowed' | 'approval_required';
  conflictType?: string;
  reason?: string;
}
 
@Injectable()
export class ConflictDetectionService {
  private readonly logger = new Logger(ConflictDetectionService.name);
 
  constructor(private readonly availabilityEngine: AvailabilityEngine) {}
 
  /**
   * Checks if scheduling a slot conflicts with other attendees or resources.
   */
  async checkConflicts(
    tenantId: string,
    participantIds: string[],
    resourceIds: string[],
    startAt: Date,
    endAt: Date,
    allowDoubleBooking = false
  ): Promise<ConflictResult> {
    const busy = await this.availabilityEngine.findBusyIntervals(
      tenantId,
      participantIds,
      resourceIds,
      startAt,
      endAt,
      false
    );
 
    if (busy.length === 0) {
      return { hasConflict: false, severity: 'warning' }; // no conflict
    }
 
    // Determine type of conflict
    const reasons = busy.map(b => `${b.title || 'Busy'} (${b.startAt.toISOString()} - ${b.endAt.toISOString()})`);
 
    if (allowDoubleBooking) {
      return {
        hasConflict: true,
        severity: 'override_allowed',
        conflictType: 'ParticipantOverlap',
        reason: `Double booking allowed but conflicts exist: ${reasons.join(', ')}`
      };
    }
 
    return {
      hasConflict: true,
      severity: 'blocking',
      conflictType: 'DoubleBooking',
      reason: `Conflict detected: ${reasons.join(', ')}`
    };
  }
}