feat(platform): keep canonical source summary slots

This commit is contained in:
lingniu
2026-07-04 07:54:38 +08:00
parent 422ac684ed
commit 1d691306db
6 changed files with 72 additions and 5 deletions

View File

@@ -261,6 +261,7 @@ func (m *MockStore) VehicleServiceSummary(ctx context.Context) (VehicleServiceSu
for _, protocol := range protocolCounts {
summary.Protocols = append(summary.Protocols, *protocol)
}
summary.Protocols = completeProtocolStats(summary.Protocols)
for _, protocol := range canonicalVehicleProtocols {
missing := 0
for _, row := range coverage.Items {
@@ -271,7 +272,6 @@ func (m *MockStore) VehicleServiceSummary(ctx context.Context) (VehicleServiceSu
summary.MissingSources = append(summary.MissingSources, MissingSourceStat{Protocol: protocol, Count: missing})
}
sort.Slice(summary.ServiceStatuses, func(i, j int) bool { return summary.ServiceStatuses[i].Status < summary.ServiceStatuses[j].Status })
sort.Slice(summary.Protocols, func(i, j int) bool { return summary.Protocols[i].Protocol < summary.Protocols[j].Protocol })
return summary, nil
}

View File

@@ -923,7 +923,10 @@ func (s *ProductionStore) protocolStats(ctx context.Context) ([]ProtocolStat, er
}
out = append(out, row)
}
return out, rows.Err()
if err := rows.Err(); err != nil {
return nil, err
}
return completeProtocolStats(out), nil
}
func parsedFieldsFromString(value string) map[string]any {

View File

@@ -58,6 +58,37 @@ type Service struct {
var canonicalVehicleProtocols = []string{"GB32960", "JT808", "YUTONG_MQTT"}
func completeProtocolStats(stats []ProtocolStat) []ProtocolStat {
byProtocol := make(map[string]ProtocolStat, len(stats)+len(canonicalVehicleProtocols))
for _, stat := range stats {
protocol := strings.TrimSpace(stat.Protocol)
if protocol == "" {
continue
}
stat.Protocol = protocol
byProtocol[protocol] = stat
}
out := make([]ProtocolStat, 0, len(byProtocol)+len(canonicalVehicleProtocols))
seen := map[string]struct{}{}
for _, protocol := range canonicalVehicleProtocols {
stat := byProtocol[protocol]
stat.Protocol = protocol
out = append(out, stat)
seen[protocol] = struct{}{}
}
extra := make([]string, 0)
for protocol := range byProtocol {
if _, ok := seen[protocol]; !ok {
extra = append(extra, protocol)
}
}
sort.Strings(extra)
for _, protocol := range extra {
out = append(out, byProtocol[protocol])
}
return out
}
func missingCanonicalProtocols(protocols []string) []string {
missing := make([]string, 0, len(canonicalVehicleProtocols))
for _, protocol := range canonicalVehicleProtocols {

View File

@@ -83,3 +83,22 @@ func TestVehicleServiceSummaryCountsProtocolOnlineByProtocolSlot(t *testing.T) {
t.Fatalf("GB32960 online count must use GB32960 source status only, got %+v", gb32960)
}
}
func TestCompleteProtocolStatsIncludesCanonicalSlots(t *testing.T) {
stats := completeProtocolStats([]ProtocolStat{{Protocol: "JT808", Online: 2, Total: 5}})
byProtocol := map[string]ProtocolStat{}
for _, stat := range stats {
byProtocol[stat.Protocol] = stat
}
for _, protocol := range canonicalVehicleProtocols {
if _, ok := byProtocol[protocol]; !ok {
t.Fatalf("canonical protocol %s should be present, got %+v", protocol, stats)
}
}
if byProtocol["JT808"].Online != 2 || byProtocol["JT808"].Total != 5 {
t.Fatalf("existing protocol stats should be preserved, got %+v", byProtocol["JT808"])
}
if byProtocol["GB32960"].Online != 0 || byProtocol["GB32960"].Total != 0 {
t.Fatalf("missing canonical protocol should be exposed as zero slot, got %+v", byProtocol["GB32960"])
}
}