{"version":3,"file":"diceCandidateMapper-BjMhHno3.cjs","names":[],"sources":["../src/services/diceCandidateMapper.js"],"sourcesContent":["/**\n * Dice Candidate Response Mapper\n * \n * Transforms Dice API candidate responses into the existing Internal Candidate\n * List API format. This ensures the frontend receives an identical response\n * schema regardless of the data source.\n * \n * Reusable for additional external sources (Monster, CareerBuilder, LinkedIn, etc.)\n */\n\n/**\n * Normalizes skills from various Dice skill formats into a simple string array\n */\nfunction firstPresentValue(...values) {\n  return values.find((value) => value !== undefined && value !== null && String(value).trim() !== '');\n}\n\nfunction getPathValue(record, path) {\n  if (!record || !path) return undefined;\n  if (Object.prototype.hasOwnProperty.call(record, path)) return record[path];\n  return String(path)\n    .split('.')\n    .reduce((value, key) => value?.[key], record);\n}\n\nfunction isLikelyInternalRecordId(value) {\n  return /^[a-f0-9]{24}$/i.test(String(value ?? '').trim());\n}\n\nfunction isLikelyDiceProfileId(value) {\n  const text = String(value ?? '').trim();\n  return (\n    /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(text)\n    || /^[a-f0-9]{40,}$/i.test(text)\n  );\n}\n\nfunction isLikelyDiceCandidateId(value, candidate) {\n  const text = String(value ?? '').trim();\n  const knownCandidateId = firstPresentValue(\n    candidate?.candidateId,\n    candidate?.customFields?.diceProfileData?.candidateId,\n  );\n\n  return (\n    (knownCandidateId && text === String(knownCandidateId).trim())\n    || /^[a-f0-9]{40,}-\\d+$/i.test(text)\n  );\n}\n\nfunction findLikelyDiceProfileId(record) {\n  const seen = new Set();\n  const candidates = [];\n\n  const visit = (value, path = '') => {\n    if (value === null || value === undefined) return;\n    if (typeof value === 'string' || typeof value === 'number') {\n      const text = String(value).trim();\n      const keyLooksRelevant = /(^|[._-])(dice|profile|source|external).*(id|guid|uuid)$|(^|[._-])(id|guid|uuid)$/i.test(path);\n      if (text && keyLooksRelevant && isLikelyDiceProfileId(text)) {\n        candidates.push({ path, value: text });\n      }\n      return;\n    }\n    if (typeof value !== 'object' || seen.has(value)) return;\n    seen.add(value);\n    Object.entries(value).forEach(([key, child]) => {\n      visit(child, path ? `${path}.${key}` : key);\n    });\n  };\n\n  visit(record);\n\n  return candidates.find((candidate) => /dice|profile|source|external/i.test(candidate.path))?.value\n    ?? candidates[0]?.value\n    ?? '';\n}\n\nexport function resolveDiceProfileId(candidate) {\n  if (!candidate || typeof candidate !== 'object') return '';\n\n  // Check if this is a Dice candidate\n  const isDiceCandidate = (() => {\n    const source = candidate?.sourceType\n      ?? candidate?.profileSource\n      ?? candidate?.selectedSource;\n    const normalizedSources = Array.isArray(source) ? source : [source];\n    return normalizedSources.some(\n      (value) => String(value ?? '').trim().toLowerCase() === 'dice',\n    );\n  })();\n\n  const explicitPaths = [\n    'diceId',\n    'diceID',\n    'dice_id',\n    'diceProfileId',\n    'diceProfileID',\n    'diceProfileGuid',\n    'profileId',\n    'profileID',\n    'profileGuid',\n    'sourceId',\n    'sourceProfileId',\n    'externalId',\n    'externalProfileId',\n    'customFields.diceId',\n    'customFields.diceProfileId',\n    'customFields.profileId',\n    'customFields.externalProfileId',\n    'customFields.diceProfileData.diceId',\n    'customFields.diceProfileData.diceID',\n    'customFields.diceProfileData.id',\n    'customFields.diceProfileData._id',\n    'customFields.diceProfileData.profileId',\n    'customFields.diceProfileData.profileID',\n    'customFields.diceProfileData.diceProfileId',\n    'customFields.diceProfileData.diceProfileID',\n    'customFields.diceProfileData.guid',\n    'customFields.diceProfileData.uuid',\n    'customFields.diceProfileData.externalId',\n    'customFields.diceProfileData.candidateid',\n    'customFields.diceProfileData.candidateId',\n  ];\n\n  const explicitDiceId = firstPresentValue(\n    ...explicitPaths.map((path) => getPathValue(candidate, path)),\n  );\n\n  if (explicitDiceId && !isLikelyDiceCandidateId(explicitDiceId, candidate)) {\n    return String(explicitDiceId);\n  }\n\n  const likelyNestedId = findLikelyDiceProfileId(candidate);\n  if (likelyNestedId) return likelyNestedId;\n\n  const genericId = firstPresentValue(candidate.id, candidate._id);\n  \n  // For Dice candidates, accept the ID even if it looks like an internal MongoDB ObjectId\n  // For non-Dice candidates, reject IDs that look like internal record IDs\n  if (genericId && (isDiceCandidate || !isLikelyInternalRecordId(genericId))) {\n    return String(genericId);\n  }\n  \n  return '';\n}\n\nexport function normalizeDiceSkills(skills) {\n  if (!skills) return [];\n  \n  if (Array.isArray(skills)) {\n    return skills\n      .map(skill => {\n        // Handle Dice format: {skill: \"courts\", lastUsed: 2026}\n        if (skill?.skill) return skill.skill;\n        // Handle other object formats\n        if (typeof skill === 'object' && skill !== null) {\n          if (skill?.name) return skill.name;\n          if (skill?.skillName) return skill.skillName;\n          if (skill?.value) return skill.value;\n        }\n        // Handle string skills\n        if (typeof skill === 'string') return skill;\n        return null;\n      })\n      .filter(Boolean);\n  }\n  \n  if (typeof skills === 'string') {\n    return skills.split(',').map(s => s.trim()).filter(Boolean);\n  }\n  \n  return [];\n}\n\n/**\n * Normalizes location from various Dice location formats\n */\nfunction normalizeDiceLocation(candidate) {\n  // Try locations array first (common in Dice)\n  if (Array.isArray(candidate.locations) && candidate.locations.length > 0) {\n    const loc = candidate.locations[0];\n    if (typeof loc === 'string') return loc;\n    if (loc?.region) return loc.region;\n    if (loc?.city) return loc.city;\n    if (loc?.name) return loc.name;\n    if (loc?.location) return loc.location;\n  }\n  \n  // Try direct location fields\n  return (\n    candidate.currentLocation ??\n    candidate.location ??\n    candidate.city ??\n    candidate.region ??\n    ''\n  );\n}\n\n/**\n * Normalizes experience from various Dice experience formats\n */\nfunction normalizeDiceExperience(candidate) {\n  const exp = (\n    candidate.totalExperience ??\n    candidate.experience ??\n    candidate.yearsOfExperience ??\n    candidate.exp ??\n    candidate.totalYearsOfExperience ??\n    candidate.workExperienceYears\n  );\n  \n  return exp != null && exp !== '' ? exp : null;\n}\n\n/**\n * Normalizes date from various Dice date formats\n */\nfunction normalizeDiceDate(candidate) {\n  return (\n    candidate.dateLastUpdated ??\n    candidate.updatedAt ??\n    candidate.createdAt ??\n    candidate.createdDate ??\n    candidate.dateCreated ??\n    null\n  );\n}\n\n/**\n * Normalizes name from various Dice name formats\n */\nfunction normalizeDiceName(candidate) {\n  const parts = [\n    candidate.firstName,\n    candidate.middleName,\n    candidate.lastName,\n  ].filter(Boolean);\n  \n  if (parts.length > 0) return parts.join(' ');\n  \n  return (\n    candidate.fullName ??\n    candidate.name ??\n    candidate.candidateName ??\n    ''\n  );\n}\n\n/**\n * Maps a single Dice candidate to the Internal Candidate format\n * \n * @param {Object} diceCandidate - Raw Dice API candidate object\n * @param {number} index - Index for fallback ID generation\n * @returns {Object} Mapped candidate in Internal format\n */\nexport function mapDiceCandidateToInternal(diceCandidate, index = 0) {\n  if (!diceCandidate || typeof diceCandidate !== 'object') {\n    return {\n      id: `dice-candidate-${index}`,\n      diceId: '',\n      candidateId: '',\n      firstName: '',\n      lastName: '',\n      name: '-',\n      designation: '-',\n      currentLocation: '',\n      location: '',\n      exp: '',\n      totalExperience: null,\n      skills: [],\n      createdAt: null,\n      createdOn: '-',\n      sourceType: 'dice',\n      profileSource: 'dice',\n    };\n  }\n\n  const fullName = normalizeDiceName(diceCandidate);\n  const nameParts = fullName.split(' ');\n  const firstName = nameParts[0] || '';\n  const lastName = nameParts.length > 1 ? nameParts[nameParts.length - 1] : '';\n  \n  const location = normalizeDiceLocation(diceCandidate);\n  const experience = normalizeDiceExperience(diceCandidate);\n  const createdOn = normalizeDiceDate(diceCandidate);\n  const diceProfileId = resolveDiceProfileId(diceCandidate);\n  const candidateId = diceCandidate.candidateId\n    ?? diceCandidate.customFields?.diceProfileData?.candidateId\n    ?? `dice-candidate-${index}`;\n  \n  // Extract skills from various possible fields\n  const rawSkills = diceCandidate.skills ?? \n                    diceCandidate.technicalSkills ?? \n                    diceCandidate.primarySkills ??\n                    diceCandidate.keySkills ??\n                    [];\n  \n  const skills = normalizeDiceSkills(rawSkills);\n  \n  // Debug logging to verify transformation\n  if (process.env.NODE_ENV === 'development') {\n    console.log('[DiceMapper] Original skills:', rawSkills);\n    console.log('[DiceMapper] Mapped skills:', skills);\n    console.log('[DiceMapper] Dice IDs:', {\n      id: diceProfileId,\n      diceId: diceProfileId,\n      candidateId,\n    });\n  }\n\n  return {\n    // Preserve original Dice fields for reference\n    ...diceCandidate,\n    \n    // Map to Internal candidate schema. Keep the Dice profile id as the primary id.\n    id: diceProfileId,\n    diceId: diceProfileId,\n    candidateId,\n    \n    // Name fields\n    firstName,\n    lastName,\n    middleName: diceCandidate.middleName || '',\n    name: fullName || '-',\n    fullName: fullName || '',\n    \n    // Professional info\n    designation: diceCandidate.currentJobTitle ?? diceCandidate.jobTitle ?? diceCandidate.designation ?? diceCandidate.currentDesignation ?? '-',\n    currentDesignation: diceCandidate.currentJobTitle ?? diceCandidate.jobTitle ?? diceCandidate.designation ?? diceCandidate.currentDesignation ?? '',\n    jobTitle: diceCandidate.currentJobTitle ?? diceCandidate.jobTitle ?? diceCandidate.designation ?? '',\n    \n    // Location\n    currentLocation: location || '',\n    location: location || '',\n    city: diceCandidate.city ?? diceCandidate.locations?.[0]?.city ?? '',\n    region: diceCandidate.region ?? diceCandidate.locations?.[0]?.region ?? '',\n    \n    // Experience\n    totalExperience: experience,\n    experience: experience,\n    yearsOfExperience: experience,\n    exp: experience != null && experience !== '' ? `${experience} yrs` : '',\n    \n    // Skills\n    skills,\n    technicalSkills: skills,\n    primarySkills: skills,\n    \n    // Dates\n    createdAt: createdOn,\n    createdOn: createdOn ? String(createdOn) : '-',\n    updatedAt: createdOn,\n    dateLastUpdated: createdOn,\n    \n    // Source identification\n    sourceType: 'dice',\n    profileSource: 'dice',\n    selectedSource: ['dice'],\n    \n    // Additional fields with defaults\n    email: diceCandidate.email ?? diceCandidate.emailAddress ?? '',\n    phone: diceCandidate.phone ?? diceCandidate.phoneNumber ?? diceCandidate.mobile ?? '',\n    summary: diceCandidate.summary ?? diceCandidate.bio ?? diceCandidate.description ?? '',\n    resume: diceCandidate.resume ?? diceCandidate.resumeUrl ?? diceCandidate.cvUrl ?? '',\n    \n    // Status and metadata\n    isActive: true,\n    isDeleted: false,\n  };\n}\n\n/**\n * Maps an array of Dice candidates to the Internal Candidate format\n * \n * @param {Array} diceCandidates - Array of raw Dice API candidate objects\n * @returns {Array} Array of mapped candidates in Internal format\n */\nexport function mapDiceCandidatesToInternal(diceCandidates) {\n  if (!Array.isArray(diceCandidates)) {\n    return [];\n  }\n  \n  return diceCandidates.map((candidate, index) => \n    mapDiceCandidateToInternal(candidate, index)\n  );\n}\n\n/**\n * Transforms a Dice API response to match the existing Candidate List API response format\n * \n * @param {Object} diceResponse - Raw Dice API response\n * @param {Object} originalResponseStructure - The expected response structure from Internal API\n * @returns {Object} Transformed response matching Internal API format\n */\nexport function transformDiceResponseToInternalFormat(diceResponse, originalResponseStructure = {}) {\n  if (!diceResponse || typeof diceResponse !== 'object') {\n    return {\n      status: 'success',\n      data: {\n        fields: [],\n        actions: [],\n        columnActions: [],\n        count: 0,\n        data: [],\n      },\n    };\n  }\n\n  // Extract candidates array from various possible response structures\n  const diceCandidates = Array.isArray(diceResponse) \n    ? diceResponse \n    : diceResponse?.data?.data ?? \n      diceResponse?.data?.applicant ?? \n      diceResponse?.data?.candidates ?? \n      diceResponse?.data?.items ?? \n      diceResponse?.items ?? \n      diceResponse?.candidates ?? \n      diceResponse?.records ?? \n      [];\n\n  // Map Dice candidates to Internal format\n  const mappedCandidates = mapDiceCandidatesToInternal(diceCandidates);\n\n  // Extract count from various possible locations\n  const count = (\n    diceResponse?.data?.count?.searchCount ??\n    diceResponse?.data?.count?.total ??\n    diceResponse?.count?.searchCount ??\n    diceResponse?.count?.total ??\n    diceResponse?.total ??\n    diceResponse?.totalCount ??\n    mappedCandidates.length\n  );\n\n  // Preserve existing metadata from the original response structure\n  return {\n    status: diceResponse?.status ?? 'success',\n    data: {\n      // Preserve fields, actions, columnActions from original structure\n      fields: originalResponseStructure?.fields ?? diceResponse?.data?.fields ?? diceResponse?.fields ?? [],\n      actions: originalResponseStructure?.actions ?? diceResponse?.data?.actions ?? diceResponse?.actions ?? [],\n      columnActions: originalResponseStructure?.columnActions ?? diceResponse?.data?.columnActions ?? diceResponse?.columnActions ?? [],\n      \n      // Count and mapped data\n      count: Number(count) || 0,\n      data: mappedCandidates,\n      \n      // Preserve any additional metadata\n      ...(diceResponse?.data?.actionRules && { actionRules: diceResponse.data.actionRules }),\n      ...(diceResponse?.data?.tabs && { tabs: diceResponse.data.tabs }),\n      ...(diceResponse?.data?.tabField && { tabField: diceResponse.data.tabField }),\n    },\n  };\n}\n\n/**\n * Checks if a response contains Dice candidates\n * \n * @param {Array|Object} response - API response to check\n * @returns {boolean} True if response contains Dice candidates\n */\nexport function isDiceResponse(response) {\n  if (!response) return false;\n  \n  const candidates = Array.isArray(response) \n    ? response \n    : response?.data?.data ?? \n      response?.data?.applicant ?? \n      response?.data?.candidates ?? \n      response?.data?.items ?? \n      response?.items ?? \n      [];\n  \n  if (!Array.isArray(candidates) || candidates.length === 0) {\n    return false;\n  }\n  \n  // Check first few candidates for Dice source indicators\n  const sampleSize = Math.min(candidates.length, 5);\n  for (let i = 0; i < sampleSize; i++) {\n    const candidate = candidates[i];\n    const sourceType = candidate?.sourceType ?? candidate?.profileSource ?? '';\n    if (String(sourceType).toLowerCase() === 'dice') {\n      return true;\n    }\n  }\n  \n  return false;\n}\n\nexport default {\n  mapDiceCandidateToInternal,\n  mapDiceCandidatesToInternal,\n  transformDiceResponseToInternalFormat,\n  isDiceResponse,\n};\n"],"mappings":"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"}