feat(operations): add source diagnosis workspace

This commit is contained in:
lingniu
2026-07-16 17:35:10 +08:00
parent df7d9799b3
commit 96cad7eef7
18 changed files with 881 additions and 10 deletions

View File

@@ -216,6 +216,59 @@ func TestCustomerSourceEvidenceUsesOnlyCompleteAuthorizedDays(t *testing.T) {
}
}
func TestVehicleSourceDiagnosticExposesOpaqueReferencesAndElectionReasons(t *testing.T) {
service := NewService(NewMockStore())
ctx := WithPrincipal(context.Background(), Principal{Name: "运维员", Role: "operator", UserType: "operator"})
diagnostic, err := service.VehicleSourceDiagnostic(ctx, "LB9A32A24R0LS1426")
if err != nil {
t.Fatalf("VehicleSourceDiagnostic returned error: %v", err)
}
if diagnostic.Policy.Version != 1 || diagnostic.Access == nil || diagnostic.Evidence.RecommendedLocationProtocol != "JT808" {
t.Fatalf("diagnostic lost access or policy evidence: %+v", diagnostic)
}
if diagnostic.RecommendationReason == "" || diagnostic.RefreshHint == "" {
t.Fatalf("diagnostic must explain recommendation and refresh boundary: %+v", diagnostic)
}
for _, source := range diagnostic.Evidence.LocationSources {
if len(source.SourceRef) != 64 || source.SelectionReason == "" || source.FirstSeenAt == "" {
t.Fatalf("source diagnostic is incomplete: %+v", source)
}
if strings.Contains(source.SourceRef, "jt808") || strings.Contains(source.SourceRef, "g7") {
t.Fatalf("source reference must stay opaque: %+v", source)
}
}
}
func TestVehicleSourcePolicyUpdateRequiresAdminAndUsesOptimisticVersion(t *testing.T) {
service := NewService(NewMockStore())
operator := WithPrincipal(context.Background(), Principal{Name: "运维员", Role: "operator", UserType: "operator"})
diagnostic, err := service.VehicleSourceDiagnostic(operator, "LB9A32A24R0LS1426")
if err != nil {
t.Fatal(err)
}
source := diagnostic.Evidence.LocationSources[1]
if _, err := service.UpdateVehicleSourcePolicy(operator, diagnostic.Evidence.VIN, VehicleSourcePolicyUpdate{
Version: diagnostic.Policy.Version, SourceRef: source.SourceRef, Enabled: false, Priority: source.Priority, Remark: "人工核验",
}); err == nil {
t.Fatal("operator must not modify source policy")
}
admin := WithPrincipal(context.Background(), Principal{Name: "平台管理员", Role: "admin", UserType: "admin"})
updated, err := service.UpdateVehicleSourcePolicy(admin, diagnostic.Evidence.VIN, VehicleSourcePolicyUpdate{
Version: diagnostic.Policy.Version, SourceRef: source.SourceRef, Enabled: false, Priority: source.Priority, Remark: "人工核验",
})
if err != nil {
t.Fatalf("admin source policy update failed: %v", err)
}
if updated.Policy.Version != 2 || len(updated.Policy.Audit) != 1 || updated.Policy.Audit[0].Actor != "平台管理员" {
t.Fatalf("source policy update must version and audit: %+v", updated.Policy)
}
if _, err := service.UpdateVehicleSourcePolicy(admin, diagnostic.Evidence.VIN, VehicleSourcePolicyUpdate{
Version: 1, SourceRef: source.SourceRef, Enabled: true, Priority: source.Priority,
}); err == nil {
t.Fatal("stale source policy update must conflict")
}
}
func (s *countingStore) VehicleServiceOverviews(ctx context.Context, query VehicleOverviewBatchQuery) (Page[VehicleServiceOverview], error) {
s.overviewBatchCalls++
return s.MockStore.VehicleServiceOverviews(ctx, query)