feat(platform): expose source consistency in vehicle coverage

This commit is contained in:
lingniu
2026-07-04 07:12:54 +08:00
parent df78bb5e20
commit c9a809d13d
9 changed files with 134 additions and 14 deletions

View File

@@ -94,8 +94,9 @@ func TestHandlerVehicleCoverage(t *testing.T) {
}
var rawBody struct {
Data Page[struct {
VIN string `json:"vin"`
MissingProtocols []string `json:"missingProtocols"`
VIN string `json:"vin"`
MissingProtocols []string `json:"missingProtocols"`
SourceConsistency *VehicleSourceConsistency `json:"sourceConsistency"`
}] `json:"data"`
}
if err := json.Unmarshal(rec.Body.Bytes(), &rawBody); err != nil {
@@ -104,6 +105,12 @@ func TestHandlerVehicleCoverage(t *testing.T) {
if len(rawBody.Data.Items) == 0 || !containsString(rawBody.Data.Items[0].MissingProtocols, "YUTONG_MQTT") {
t.Fatalf("coverage row should expose missing canonical protocols, got %+v body=%s", rawBody.Data.Items, rec.Body.String())
}
if len(rawBody.Data.Items) == 0 || rawBody.Data.Items[0].SourceConsistency == nil {
t.Fatalf("coverage row should expose vehicle-level source consistency: %s", rec.Body.String())
}
if rawBody.Data.Items[0].SourceConsistency.Status != "degraded" || !containsString(rawBody.Data.Items[0].SourceConsistency.MissingProtocols, "YUTONG_MQTT") {
t.Fatalf("coverage source consistency should diagnose missing source evidence, got %+v body=%s", rawBody.Data.Items[0].SourceConsistency, rec.Body.String())
}
}
func TestHandlerVehicleCoverageFiltersServiceStatus(t *testing.T) {

View File

@@ -134,6 +134,7 @@ func (m *MockStore) VehicleCoverage(_ context.Context, query url.Values) (Page[V
for _, row := range byVIN {
row.MissingProtocols = missingCanonicalProtocols(row.Protocols)
row.ServiceStatus = buildVehicleCoverageServiceStatus(*row)
row.SourceConsistency = buildVehicleCoverageSourceConsistency(*row)
if keepCoverageRow(*row, query) {
items = append(items, *row)
}

View File

@@ -50,18 +50,19 @@ type VehicleRow struct {
}
type VehicleCoverageRow struct {
VIN string `json:"vin"`
Plate string `json:"plate"`
Phone string `json:"phone"`
OEM string `json:"oem"`
Protocols []string `json:"protocols"`
MissingProtocols []string `json:"missingProtocols"`
SourceCount int `json:"sourceCount"`
OnlineSourceCount int `json:"onlineSourceCount"`
Online bool `json:"online"`
LastSeen string `json:"lastSeen"`
BindingStatus string `json:"bindingStatus"`
ServiceStatus *VehicleServiceStatus `json:"serviceStatus,omitempty"`
VIN string `json:"vin"`
Plate string `json:"plate"`
Phone string `json:"phone"`
OEM string `json:"oem"`
Protocols []string `json:"protocols"`
MissingProtocols []string `json:"missingProtocols"`
SourceCount int `json:"sourceCount"`
OnlineSourceCount int `json:"onlineSourceCount"`
Online bool `json:"online"`
LastSeen string `json:"lastSeen"`
BindingStatus string `json:"bindingStatus"`
ServiceStatus *VehicleServiceStatus `json:"serviceStatus,omitempty"`
SourceConsistency *VehicleSourceConsistency `json:"sourceConsistency,omitempty"`
}
type VehicleCoverageSummary struct {

View File

@@ -272,6 +272,7 @@ func (s *ProductionStore) VehicleCoverage(ctx context.Context, query url.Values)
row.MissingProtocols = missingCanonicalProtocols(row.Protocols)
row.Online = online == 1
row.ServiceStatus = buildVehicleCoverageServiceStatus(row)
row.SourceConsistency = buildVehicleCoverageSourceConsistency(row)
items = append(items, row)
}
if err := rows.Err(); err != nil {

View File

@@ -1052,6 +1052,18 @@ func buildVehicleCoverageServiceStatus(row VehicleCoverageRow) *VehicleServiceSt
}
}
func buildVehicleCoverageSourceConsistency(row VehicleCoverageRow) *VehicleSourceConsistency {
consistency := &VehicleSourceConsistency{
SourceCount: row.SourceCount,
OnlineSourceCount: row.OnlineSourceCount,
MissingProtocols: row.MissingProtocols,
Scope: "coverage",
LocatedSourceCount: 0,
}
applyVehicleSourceConsistencyDiagnosis(consistency)
return consistency
}
func buildRealtimeServiceStatus(row VehicleRealtimeRow) *VehicleServiceStatus {
return buildVehicleCoverageServiceStatus(VehicleCoverageRow{
VIN: row.VIN,