refactor(platform): remove safety management module

This commit is contained in:
2026-07-27 15:49:51 +08:00
parent 95fb27f596
commit 8739cfd4d6
25 changed files with 27 additions and 391 deletions

View File

@@ -42,16 +42,13 @@ func TestContentUsesCMSResourceAndRemovedDomainsAreAbsent(t *testing.T) {
}
}
func TestSafeResourceContracts(t *testing.T) {
legacySafetyPrefix := "sa" + "f_"
assertContract(t, ExpectedResources(), "safety", "safe_rule", Writable, "list")
assertContract(t, ExpectedResources(), "safety", "safe_event", Writable, "list")
assertContract(t, ExpectedResources(), "safety", "safe_inspection", Writable, "list")
assertContract(t, ExpectedResources(), "safety", "safe_event_disposal", AppendOnly, "list")
func TestSafetyResourcesAreAbsent(t *testing.T) {
removed := map[string]struct{}{
"safe_rule": {}, "safe_event": {}, "safe_inspection": {}, "safe_event_disposal": {},
}
for _, contract := range ExpectedResources() {
if contract.Domain == "safety" && strings.HasPrefix(contract.Name, legacySafetyPrefix) {
t.Fatalf("legacy resource contract %s/%s must not be registered", contract.Domain, contract.Name)
if _, exists := removed[contract.Name]; exists || contract.Domain == "safety" {
t.Fatalf("removed safety resource %s/%s remains registered", contract.Domain, contract.Name)
}
}
}
@@ -258,17 +255,6 @@ func TestPrepareResourceValuesResolvesRequiredIdentityRelationsAndRejectsInvalid
}
func TestPrepareResourceValuesAcceptsArbitraryTextFields(t *testing.T) {
t.Run("safety rule", func(t *testing.T) {
ctx, _ := updateContext(http.MethodPost, "/safety/safe_rule", "", []byte(`{"rule_code":"pressure-limit","threshold":"{invalid}","action":"close-valve","gray_scope":"north region"}`))
values, err := prepareResourceValues(ctx, &models.SafeRule{}, []string{"rule_code", "threshold", "action", "gray_scope"}, nil)
if err != nil {
t.Fatal(err)
}
if values["threshold"] != `{invalid}` || values["gray_scope"] != `north region` {
t.Fatalf("text values were not preserved: %#v", values)
}
})
t.Run("order item", func(t *testing.T) {
_, mock := setupPlatformRoleDatabase(t)
mock.ExpectQuery(regexp.QuoteMeta(`SELECT "id" FROM "ec_order" WHERE identity = $1 ORDER BY "ec_order"."id" LIMIT $2`)).
@@ -292,12 +278,6 @@ func TestPrepareResourceValuesAcceptsArbitraryTextFields(t *testing.T) {
assertMockExpectations(t, mock)
})
t.Run("arbitrary text", func(t *testing.T) {
ctx, _ := updateContext(http.MethodPost, "/safety/safe_rule", "", []byte(`{"rule_code":"pressure-limit","threshold":"{invalid}","action":"close-valve"}`))
if _, err := prepareResourceValues(ctx, &models.SafeRule{}, []string{"rule_code", "threshold", "action"}, nil); err != nil {
t.Fatalf("arbitrary text was rejected: %v", err)
}
})
}
func TestCreateGasAccountResolvesGasBasicIdentityBeforePersisting(t *testing.T) {
@@ -350,7 +330,6 @@ func TestKeywordColumnsUseSafeTextAllowlist(t *testing.T) {
model any
want []string
}{
{"safety rule excludes arbitrary text fields", &models.SafeRule{}, []string{"rule_code", "action"}},
{"gas basic excludes sensitive fields", &models.GasBasic{}, []string{"code", "name"}},
{"user address has no searchable safe text", &models.UserAddress{}, []string{}},
}
@@ -655,26 +634,6 @@ func TestNonRootCannotAssignPlatformAccountRole(t *testing.T) {
}
}
func TestListSafetyEventDisposalsReturnsOnlyTheRequestedEventHistory(t *testing.T) {
_, mock := setupPlatformRoleDatabase(t)
mock.ExpectQuery(regexp.QuoteMeta(`SELECT count(*) FROM "safe_event_disposal" WHERE safe_event_identity = $1`)).
WithArgs("event-a").
WillReturnRows(sqlmock.NewRows([]string{"count"}).AddRow(1))
mock.ExpectQuery(regexp.QuoteMeta(`SELECT * FROM "safe_event_disposal" WHERE safe_event_identity = $1 ORDER BY created_at asc LIMIT $2`)).
WithArgs("event-a", 20).
WillReturnRows(sqlmock.NewRows([]string{"id", "identity", "created_at", "updated_at", "status", "version", "safe_event_identity", "action", "reason", "operator_identity"}).
AddRow(uint64(9), "disposal-a", nil, nil, "enabled", 1, "event-a", "close", "resolved", "operator-a"))
ctx, recorder := updateContext(http.MethodGet, "/safety/safe_event/event-a/disposals", "event-a", nil)
ListSafetyEventDisposals(ctx)
assertResponseCode(t, recorder, 0)
if !strings.Contains(recorder.Body.String(), `"safe_event_identity":"event-a"`) || strings.Contains(recorder.Body.String(), `"id":`) {
t.Fatalf("disposal history did not keep the event identity-only shape: %s", recorder.Body.String())
}
assertMockExpectations(t, mock)
}
func TestListGasAccountProjectsGasBasicIdentityAndNeverReturnsRelationID(t *testing.T) {
_, mock := setupPlatformRoleDatabase(t)
mock.ExpectQuery(regexp.QuoteMeta(`SELECT count(*) FROM "gas_account"`)).
@@ -820,33 +779,6 @@ func TestGetDeliveryTrackPointReturnsCoordinatesWithPreciseLocationScope(t *test
assertMockExpectations(t, mock)
}
func TestDisposeSafetyEventUpdatesEventAndAppendsOperatorActionTransactionally(t *testing.T) {
_, mock := setupPlatformRoleDatabase(t)
now := time.Now().UTC()
mock.ExpectBegin()
mock.ExpectQuery(regexp.QuoteMeta(`SELECT * FROM "safe_event" WHERE identity = $1 ORDER BY "safe_event"."id" LIMIT $2`)).
WithArgs("event-a", 1).
WillReturnRows(sqlmock.NewRows([]string{"id", "identity", "created_at", "updated_at", "status", "version", "event_code", "level", "title", "smart_cylinder_valve_identity", "sla_at"}).
AddRow(uint64(3), "event-a", now, now, "open", 1, "E-1", 2, "alarm", "valve-a", nil))
mock.ExpectExec(regexp.QuoteMeta(`UPDATE "safe_event" SET "status"=$1,"updated_at"=$2 WHERE identity = $3`)).
WithArgs("disposed", sqlmock.AnyArg(), "event-a").
WillReturnResult(sqlmock.NewResult(0, 1))
mock.ExpectQuery(regexp.QuoteMeta(`INSERT INTO "safe_event_disposal" ("identity","created_at","updated_at","status","version","safe_event_identity","action","reason","operator_identity") VALUES ($1,$2,$3,$4,$5,$6,$7,$8,$9) RETURNING "id"`)).
WithArgs(sqlmock.AnyArg(), sqlmock.AnyArg(), sqlmock.AnyArg(), "enabled", 1, "event-a", "close", "resolved", "operator-a").
WillReturnRows(sqlmock.NewRows([]string{"id"}).AddRow(uint64(1)))
mock.ExpectCommit()
ctx, recorder := updateContext(http.MethodPost, "/safety/safe_event/event-a/disposals", "event-a", []byte(`{"action":"close","reason":"resolved"}`))
ctx.Set("Auth", &types.JwtClaims{Identity: "operator-a"})
DisposeSafetyEvent(ctx)
assertResponseCode(t, recorder, 0)
if !strings.Contains(recorder.Body.String(), `"operator_identity":"operator-a"`) {
t.Fatalf("disposal omitted its operator: %s", recorder.Body.String())
}
assertMockExpectations(t, mock)
}
func TestReplacePlatformRoleMenusAllowsAnEmptySetToClearAssignmentsTransactionally(t *testing.T) {
_, mock := setupPlatformRoleDatabase(t)
mock.ExpectBegin()