diff --git a/vehicle-data-platform/apps/api/internal/platform/service.go b/vehicle-data-platform/apps/api/internal/platform/service.go index 9c66bceb..5c5ee132 100644 --- a/vehicle-data-platform/apps/api/internal/platform/service.go +++ b/vehicle-data-platform/apps/api/internal/platform/service.go @@ -99,6 +99,20 @@ func (s *Service) VehicleRealtime(ctx context.Context, query url.Values) (Page[V func (s *Service) VehicleServiceOverview(ctx context.Context, keyword string, protocol string) (VehicleServiceOverview, error) { keyword = strings.TrimSpace(keyword) protocol = strings.TrimSpace(protocol) + if batchStore, ok := s.store.(VehicleOverviewBatchStore); ok { + page, err := batchStore.VehicleServiceOverviews(ctx, VehicleOverviewBatchQuery{ + Keywords: []string{keyword}, + Protocol: protocol, + Limit: 1, + }) + if err != nil { + return VehicleServiceOverview{}, err + } + if len(page.Items) > 0 { + return page.Items[0], nil + } + return *buildVehicleServiceOverview("", keyword, &VehicleIdentityResolution{LookupKey: keyword, Protocols: []string{}}, nil, nil, nil, Page[HistoryLocationRow]{}, Page[RawFrameRow]{}, Page[DailyMileageRow]{}, Page[QualityIssueRow]{}), nil + } vehicleQuery := url.Values{"keyword": {keyword}, "limit": {"20"}} if protocol != "" { vehicleQuery.Set("protocol", protocol) diff --git a/vehicle-data-platform/apps/api/internal/platform/service_test.go b/vehicle-data-platform/apps/api/internal/platform/service_test.go index 1b1e263f..43b4e95c 100644 --- a/vehicle-data-platform/apps/api/internal/platform/service_test.go +++ b/vehicle-data-platform/apps/api/internal/platform/service_test.go @@ -10,6 +10,7 @@ type countingStore struct { *MockStore vehiclesCalls int vehicleRealtimeCalls int + overviewBatchCalls int } func newCountingStore() *countingStore { @@ -26,6 +27,26 @@ func (s *countingStore) VehicleRealtime(ctx context.Context, query url.Values) ( return s.MockStore.VehicleRealtime(ctx, query) } +func (s *countingStore) VehicleServiceOverviews(ctx context.Context, query VehicleOverviewBatchQuery) (Page[VehicleServiceOverview], error) { + s.overviewBatchCalls++ + return s.MockStore.VehicleServiceOverviews(ctx, query) +} + +func TestVehicleServiceOverviewUsesBatchDataPath(t *testing.T) { + store := newCountingStore() + service := NewService(store) + overview, err := service.VehicleServiceOverview(context.Background(), "粤AG18312", "") + if err != nil { + t.Fatalf("VehicleServiceOverview returned error: %v", err) + } + if overview.VIN != "LB9A32A24R0LS1426" { + t.Fatalf("expected canonical VIN from overview, got %+v", overview) + } + if store.overviewBatchCalls != 1 || store.vehiclesCalls != 0 || store.vehicleRealtimeCalls != 0 { + t.Fatalf("single overview should use one batch store call, batch=%d vehicles=%d realtime=%d", store.overviewBatchCalls, store.vehiclesCalls, store.vehicleRealtimeCalls) + } +} + func TestVehicleServiceOverviewsUsesBatchDataPath(t *testing.T) { store := newCountingStore() service := NewService(store)