fix(exporter): populate Present on exported Memory/PSU so reanimator re-import keeps them

ReanimatorMemory.Present and ReanimatorPSU.Present were already declared as
*bool fields (matching ReanimatorStorage.Present), but convertMemoryFromDevices
and convertPSUsFromDevices never set them, unlike convertStorageFromDevices.
Exported JSON therefore had "present" for storage but not for memory/PSU
items. Re-importing a previously exported reanimator.json via
parseUploadedSnapshot (a direct json.Unmarshal into models.AnalysisResult)
left Present=false on those two categories, and the existing
IsInstalledInventory()/present-required filters then dropped them on the next
/chart/current render — reproduced live: fresh TSR upload showed Memory and
Power Supplies correctly, re-uploading the exported reanimator.json for the
same result did not.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
Mikhail Chusavitin
2026-08-11 11:11:39 +03:00
co-authored by Claude Sonnet 5
parent f599215760
commit eb6cc207ce
4 changed files with 150 additions and 42 deletions
+10 -6
View File
@@ -43,12 +43,12 @@ func ConvertToReanimator(result *models.AnalysisResult) (*ReanimatorExport, erro
TargetHost: targetHost,
CollectedAt: collectedAt,
Hardware: ReanimatorHardware{
Board: convertBoard(result.Hardware.BoardInfo),
Firmware: dedupeFirmware(convertFirmware(result.Hardware.Firmware)),
CPUs: dedupeCPUs(convertCPUsFromDevices(devices, collectedAt, result.Hardware.BoardInfo.SerialNumber, buildCPUMicrocodeBySocket(result.Hardware.Firmware))),
Memory: dedupeMemory(convertMemoryFromDevices(devices, collectedAt)),
Storage: dedupeStorage(convertStorageFromDevices(devices, collectedAt)),
PCIeDevices: dedupePCIe(convertPCIeFromDevices(devices, collectedAt)),
Board: convertBoard(result.Hardware.BoardInfo),
Firmware: dedupeFirmware(convertFirmware(result.Hardware.Firmware)),
CPUs: dedupeCPUs(convertCPUsFromDevices(devices, collectedAt, result.Hardware.BoardInfo.SerialNumber, buildCPUMicrocodeBySocket(result.Hardware.Firmware))),
Memory: dedupeMemory(convertMemoryFromDevices(devices, collectedAt)),
Storage: dedupeStorage(convertStorageFromDevices(devices, collectedAt)),
PCIeDevices: dedupePCIe(convertPCIeFromDevices(devices, collectedAt)),
PowerSupplies: dedupePSUs(convertPSUsFromDevices(devices, collectedAt)),
Sensors: convertSensors(result.Sensors),
BMCEventSummary: buildBMCEventSummary(result.Events, collectedAt),
@@ -716,9 +716,11 @@ func convertMemoryFromDevices(devices []models.HardwareDevice, collectedAt strin
continue
}
meta := buildStatusMeta(status, d.StatusCheckedAt, d.StatusChangedAt, d.StatusHistory, d.ErrorDescription, collectedAt)
presentValue := present
result = append(result, ReanimatorMemory{
Slot: d.Slot,
Location: d.Location,
Present: &presentValue,
SizeMB: d.SizeMB,
Type: d.Type,
MaxSpeedMHz: intFromDetailMap(d.Details, "max_speed_mhz"),
@@ -990,8 +992,10 @@ func convertPSUsFromDevices(devices []models.HardwareDevice, collectedAt string)
}
status := normalizeStatus(d.Status, false)
meta := buildStatusMeta(status, d.StatusCheckedAt, d.StatusChangedAt, d.StatusHistory, d.ErrorDescription, collectedAt)
presentValue := present
result = append(result, ReanimatorPSU{
Slot: d.Slot,
Present: &presentValue,
Model: d.Model,
Vendor: d.Manufacturer,
WattageW: d.WattageW,