Fix EQUIP_INST_ID extraction fallbacks and minor cleanups
- Add additional fallback sources for EQUIP_INST_ID in CARD extractGraniteFields (card_flags, ivanti_assets, top-level asset fields) - Add CARD_DEBUG env var gate for troubleshooting extraction logic - Clarify anomaly/latest endpoint comment (only significant rows returned) - Remove stale convention comment in LoaderModal.js
This commit is contained in:
@@ -1215,6 +1215,16 @@ function extractGraniteFields(asset, ip) {
|
||||
const qualys = asset.qualys_hosts || [];
|
||||
const ivanti = asset.ivanti_assets || [];
|
||||
|
||||
// Debug: log available data sources for troubleshooting equip_inst_id extraction
|
||||
if (process.env.CARD_DEBUG === 'true') {
|
||||
console.log(`[card-api] extractGraniteFields for ${ip}:`);
|
||||
console.log(` ncim_discovery: ${ncim.length} records, keys: ${ncim.length > 0 ? Object.keys(ncim[0]).join(',') : 'none'}`);
|
||||
console.log(` netops_granite_allips: ${granite.length} records, keys: ${granite.length > 0 ? Object.keys(granite[0]).join(',') : 'none'}`);
|
||||
console.log(` ise_granite_equipment: ${iseGranite.length} records`);
|
||||
console.log(` card_flags keys: ${Object.keys(flags).join(',')}`);
|
||||
console.log(` top-level asset keys: ${Object.keys(asset).filter(k => k.toLowerCase().includes('equip') || k.toLowerCase().includes('granite')).join(',')}`);
|
||||
}
|
||||
|
||||
// EQUIP_INST_ID — from ncim_discovery or granite (only available from team assets endpoint)
|
||||
let equip_inst_id = null;
|
||||
let site_name = null;
|
||||
@@ -1238,6 +1248,22 @@ function extractGraniteFields(asset, ip) {
|
||||
equip_inst_id = iseGranite[0].EQUIP_INST_ID || null;
|
||||
}
|
||||
|
||||
// Additional fallback: check card_flags for EQUIP_INST_ID (some assets store it here)
|
||||
if (!equip_inst_id && flags.EQUIP_INST_ID) {
|
||||
equip_inst_id = flags.EQUIP_INST_ID;
|
||||
}
|
||||
// Fallback: check ivanti_assets which sometimes carry the EQUIP_INST_ID
|
||||
if (!equip_inst_id && ivanti.length > 0) {
|
||||
equip_inst_id = ivanti[0].EQUIP_INST_ID || ivanti[0].equip_inst_id || null;
|
||||
}
|
||||
// Fallback: top-level asset field (some CARD response formats)
|
||||
if (!equip_inst_id && asset.equip_inst_id) {
|
||||
equip_inst_id = asset.equip_inst_id;
|
||||
}
|
||||
if (!equip_inst_id && asset.EQUIP_INST_ID) {
|
||||
equip_inst_id = asset.EQUIP_INST_ID;
|
||||
}
|
||||
|
||||
// Hostname from card_flags (primary source from owner endpoint)
|
||||
if (!hostname && flags.CARD_HOSTNAME) {
|
||||
const hostnames = Array.isArray(flags.CARD_HOSTNAME) ? flags.CARD_HOSTNAME : [flags.CARD_HOSTNAME];
|
||||
|
||||
@@ -1377,7 +1377,9 @@ function createIvantiFindingsRouter(db, requireAuth) {
|
||||
/**
|
||||
* GET /api/ivanti/findings/anomaly/latest
|
||||
*
|
||||
* Return the most recent anomaly summary row from ivanti_sync_anomaly_log.
|
||||
* Return the most recent significant anomaly summary row from ivanti_sync_anomaly_log.
|
||||
* Only rows where is_significant = true are considered — the UI banner only displays
|
||||
* significant events.
|
||||
*
|
||||
* @returns {Object} 200 - { anomaly: Object|null }
|
||||
* @returns {Object} 500 - { error: string } on database error
|
||||
|
||||
@@ -18,7 +18,6 @@ import { generateLoaderXlsx, generateFilename } from '../utils/graniteLoaderExpo
|
||||
import { COLUMN_PICKLISTS } from '../utils/graniteLoaderPicklists';
|
||||
import SearchableSelect from './SearchableSelect';
|
||||
|
||||
// ⚠️ CONVENTION: Use relative API paths (no absolute URLs). The fallback 'http://localhost:3001/api' should be '/api' instead.
|
||||
// ⚠️ CONVENTION: Fallback should be '/api' (relative), not an absolute URL with host:port
|
||||
const API_BASE = process.env.REACT_APP_API_BASE || 'http://localhost:3001/api';
|
||||
|
||||
|
||||
Reference in New Issue
Block a user