mirror of
https://github.com/rcourtman/Pulse.git
synced 2026-10-03 12:47:49 +00:00
List the continuity-aware registry once, decorate one owned host projection, and sort final frontend rows rather than a second estate-sized conversion array. Encode concrete frontend resources directly into immutable snapshot buffers, decoding every authoritative ID from those bytes; leave generic marshalers and all other fields on the existing path. Keep live freshness, alert and lifecycle semantics without a cache. Change-source: pulse-maintainer
92 lines
2.9 KiB
Go
92 lines
2.9 KiB
Go
package monitoring
|
|
|
|
import (
|
|
"encoding/json"
|
|
"github.com/rcourtman/pulse-go-rewrite/internal/models"
|
|
"github.com/rcourtman/pulse-go-rewrite/internal/unifiedresources"
|
|
"sort"
|
|
"strings"
|
|
)
|
|
|
|
// Retain the pre-repair projection as a content oracle, including its second
|
|
// coalesce and input-first sorting. This is never production or persistence code.
|
|
func convertResourcesForBroadcastReference(
|
|
allResources []unifiedresources.Resource,
|
|
metricsTargetResolvers ...MetricsTargetResourceStore,
|
|
) ([]models.ResourceFrontend, broadcastResourceCatalogs) {
|
|
if len(allResources) == 0 {
|
|
return []models.ResourceFrontend{}, broadcastResourceCatalogs{}
|
|
}
|
|
allResources = attachBroadcastMetricsTargets(
|
|
allResources,
|
|
firstBroadcastMetricsTargetResolver(metricsTargetResolvers),
|
|
)
|
|
allResources = unifiedresources.CoalescePresentationHostResources(allResources)
|
|
type broadcastResource struct {
|
|
input models.ResourceConvertInput
|
|
sortKey string
|
|
resourceID string
|
|
}
|
|
|
|
converted := make([]broadcastResource, 0, len(allResources))
|
|
catalogs := broadcastResourceCatalogs{
|
|
capabilities: make(map[string]json.RawMessage),
|
|
policies: make(map[string]json.RawMessage),
|
|
aiSafeSummaries: make(map[string]string),
|
|
}
|
|
for _, r := range allResources {
|
|
input := monitorResourceToConvertInput(r)
|
|
if len(input.Capabilities) > 0 {
|
|
id := capabilityCatalogID(input.Capabilities)
|
|
catalogs.capabilities[id] = input.Capabilities
|
|
input.CapabilitiesRef = id
|
|
input.Capabilities = nil
|
|
}
|
|
// Non-default policies and AI-safe summaries dedupe the same way:
|
|
// estates carry a handful of distinct postures and templated summary
|
|
// strings, so refs replace per-resource inline duplication.
|
|
if len(input.Policy) > 0 {
|
|
id := capabilityCatalogID(input.Policy)
|
|
catalogs.policies[id] = input.Policy
|
|
input.PolicyRef = id
|
|
input.Policy = nil
|
|
}
|
|
if input.AISafeSummary != "" {
|
|
id := capabilityCatalogID(json.RawMessage(input.AISafeSummary))
|
|
catalogs.aiSafeSummaries[id] = input.AISafeSummary
|
|
input.AISafeSummaryRef = id
|
|
input.AISafeSummary = ""
|
|
}
|
|
sortKey := strings.ToLower(input.DisplayName)
|
|
if sortKey == "" {
|
|
sortKey = strings.ToLower(input.Name)
|
|
}
|
|
converted = append(converted, broadcastResource{
|
|
input: input,
|
|
sortKey: sortKey,
|
|
resourceID: input.ID,
|
|
})
|
|
}
|
|
|
|
sort.Slice(converted, func(i, j int) bool {
|
|
if converted[i].sortKey == converted[j].sortKey {
|
|
return converted[i].resourceID < converted[j].resourceID
|
|
}
|
|
return converted[i].sortKey < converted[j].sortKey
|
|
})
|
|
|
|
result := make([]models.ResourceFrontend, len(converted))
|
|
for i, resource := range converted {
|
|
result[i] = models.ConvertResourceToFrontend(resource.input)
|
|
}
|
|
if len(catalogs.capabilities) == 0 {
|
|
catalogs.capabilities = nil
|
|
}
|
|
if len(catalogs.policies) == 0 {
|
|
catalogs.policies = nil
|
|
}
|
|
if len(catalogs.aiSafeSummaries) == 0 {
|
|
catalogs.aiSafeSummaries = nil
|
|
}
|
|
return result, catalogs
|
|
}
|