diff --git a/backend/routes/cardApi.js b/backend/routes/cardApi.js index efd91ee..63151db 100644 --- a/backend/routes/cardApi.js +++ b/backend/routes/cardApi.js @@ -939,12 +939,43 @@ function createCardApiRouter() { const targetIps = new Set(ips.map(ip => (ip || '').trim()).filter(Boolean)); const resultMap = {}; - // Strategy: fetch team assets (paginated) and match against our target IPs. + // Fast path: look up host_ids from ivanti_findings and use asset-search + // The asset-search endpoint returns the full enriched record (same as team assets). + const ipsArray = [...targetIps]; + if (ipsArray.length > 0) { + try { + const { rows: findingRows } = await pool.query( + `SELECT DISTINCT ON (ip_address) ip_address, host_id + FROM ivanti_findings + WHERE ip_address = ANY($1) AND host_id IS NOT NULL`, + [ipsArray] + ); + + for (const row of findingRows) { + if (resultMap[row.ip_address]) continue; + try { + const searchResult = await searchByIvantiHostId(row.host_id); + if (searchResult.ok) { + const searchData = JSON.parse(searchResult.body); + const assets = searchData.assets || []; + if (assets.length > 0) { + resultMap[row.ip_address] = extractGraniteFields(assets[0], row.ip_address); + } + } + } catch (_) { /* fall through to paginated lookup */ } + } + } catch (err) { + console.error('[card-api] enrich-batch: Fast path DB lookup failed:', err.message); + } + } + + let foundCount = Object.keys(resultMap).length; + + // Fallback: paginated team-assets loop for any IPs not resolved by fast path // The team assets endpoint returns the full enriched record with ncim_discovery, // card_flags, netops_granite_allips, etc. const teams = team ? [team] : ['NTS-AEO-STEAM', 'NTS-AEO-ACCESS-ENG']; const dispositions = ['confirmed', 'unconfirmed', 'candidate']; - let foundCount = 0; for (const teamName of teams) { if (foundCount >= targetIps.size) break; @@ -1013,7 +1044,7 @@ function createCardApiRouter() { results.push({ ip: trimmedIp, found: true, ...resultMap[trimmedIp] }); enrichedCount++; } else { - results.push({ ip: trimmedIp, found: false, equip_inst_id: null, hostname: null, error: 'IP not found in CARD team assets' }); + results.push({ ip: trimmedIp, found: false, equip_inst_id: null, hostname: null, error: 'IP not found in CARD' }); notFoundCount++; } }