All files / src/utils sessionImport.ts

100% Statements 36/36
100% Branches 22/22
100% Functions 8/8
100% Lines 35/35

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 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144                                          6x 6x     6x 1x       4x 9x 1x   8x 3x   5x     4x 1x     3x   3x 1x   2x                     7x 13x                   13x 13x   13x                                         12x                   3x   3x 6x 6x 6x     3x                                 5x 5x   5x 12x 5x   7x       5x    
/**
 * Session Import Utilities
 *
 * Functions for parsing, validating, and transforming legacy session JSON
 * (sessions.json) into API-compatible format for batch import.
 */
 
import type {
  LegacySession,
  SessionImportCandidate,
  BatchImportSessionRequest,
} from '@/types/sessionImport.types';
 
/**
 * Parses sessions.json content and validates structure
 *
 * @param jsonContent - Raw JSON file content
 * @returns Array of parsed legacy sessions
 * @throws Error if JSON is invalid or structure is unexpected
 */
export function parseSessionsJson(jsonContent: string): LegacySession[] {
  try {
    const parsed = JSON.parse(jsonContent);
 
    // Sessions.json is an array of session objects
    if (!Array.isArray(parsed)) {
      throw new Error('sessions.json must be an array');
    }
 
    // Validate each session has required fields
    const sessions = parsed.filter((session) => {
      if (typeof session !== 'object' || session === null) {
        return false;
      }
      if (typeof session.bat !== 'number' || !session.title) {
        return false;
      }
      return true;
    });
 
    if (sessions.length === 0) {
      throw new Error('No valid sessions found in file');
    }
 
    return sessions as LegacySession[];
  } catch (error) {
    if (error instanceof SyntaxError) {
      throw new Error(`Invalid JSON format: ${error.message}`, { cause: error });
    }
    throw error;
  }
}
 
/**
 * Transforms legacy sessions into import candidates
 *
 * @param sessions - Array of legacy sessions from sessions.json
 * @returns Array of import candidates ready for API submission
 */
export function createSessionImportCandidates(sessions: LegacySession[]): SessionImportCandidate[] {
  return sessions.map((session) => {
    const apiPayload: BatchImportSessionRequest = {
      title: session.title,
      abstract: session.abstract || '',
      pdf: session.pdf,
      materialUrl: session.materialUrl, // From generate-staging-sessions-json.js
      bat: session.bat,
      referenten: session.referenten,
      authoren: session.authoren,
    };
 
    const eventCode = `BATbern${session.bat}`;
    const speakersCount = session.referenten?.length || 0;
 
    return {
      source: session,
      apiPayload,
      importStatus: 'pending',
      eventCode,
      speakersCount,
    };
  });
}
 
/**
 * Filters sessions by event number
 *
 * @param sessions - Array of sessions
 * @param eventNumber - Event number to filter by
 * @returns Filtered array of sessions
 */
export function filterSessionsByEvent(
  sessions: LegacySession[],
  eventNumber: number
): LegacySession[] {
  return sessions.filter((session) => session.bat === eventNumber);
}
 
/**
 * Groups sessions by event number
 *
 * @param sessions - Array of sessions
 * @returns Map of event number to sessions
 */
export function groupSessionsByEvent(sessions: LegacySession[]): Map<number, LegacySession[]> {
  const grouped = new Map<number, LegacySession[]>();
 
  for (const session of sessions) {
    const existing = grouped.get(session.bat) || [];
    existing.push(session);
    grouped.set(session.bat, existing);
  }
 
  return grouped;
}
 
/**
 * Validates that all sessions reference valid event numbers
 *
 * @param sessions - Array of sessions
 * @param validEventNumbers - Set of valid event numbers
 * @returns Object with valid and invalid sessions
 */
export function validateSessionEventReferences(
  sessions: LegacySession[],
  validEventNumbers: Set<number>
): {
  valid: LegacySession[];
  invalid: LegacySession[];
} {
  const valid: LegacySession[] = [];
  const invalid: LegacySession[] = [];
 
  for (const session of sessions) {
    if (validEventNumbers.has(session.bat)) {
      valid.push(session);
    } else {
      invalid.push(session);
    }
  }
 
  return { valid, invalid };
}