refactor: rename safe and audit backend resources

This commit is contained in:
2026-07-27 14:28:23 +08:00
parent 068b4e0ed9
commit 4e1f8a13e3
17 changed files with 193 additions and 96 deletions

View File

@@ -48,7 +48,7 @@ func ApproveAudit(ctx *gin.Context) {
}
values := approvalValues(request.Status, request.Opinion, claims.Identity)
var approval models.AudApproval
var approval models.AuditApproval
err = impl.DBService.Transaction(func(transaction *gorm.DB) error {
if err := transaction.Where("identity = ?", ctx.Param("identity")).First(&approval).Error; err != nil {
return err
@@ -63,7 +63,7 @@ func ApproveAudit(ctx *gin.Context) {
if err != nil {
return err
}
if result := transaction.Model(&models.AudApproval{}).Where("identity = ? AND status = ?", approval.Identity, "pending").Updates(values); result.Error != nil {
if result := transaction.Model(&models.AuditApproval{}).Where("identity = ? AND status = ?", approval.Identity, "pending").Updates(values); result.Error != nil {
return result.Error
} else if result.RowsAffected == 0 {
return errApprovalNotProcessable
@@ -72,11 +72,11 @@ func ApproveAudit(ctx *gin.Context) {
if err != nil {
return err
}
return transaction.Create(&models.AudOperationLog{
return transaction.Create(&models.AuditOperationLog{
Entity: newEntity("enabled"),
OperatorIdentity: claims.Identity,
Action: "approve",
ObjectType: "aud_approval",
ObjectType: "audit_approval",
ObjectIdentity: approval.Identity,
BeforeData: string(before),
AfterData: string(after),

View File

@@ -32,19 +32,19 @@ func TestApproveAuditOnlyUpdatesApprovalFieldsAndAppendsOperationAudit(t *testin
_, mock := setupPlatformRoleDatabase(t)
now := time.Now().UTC()
mock.ExpectBegin()
mock.ExpectQuery(regexp.QuoteMeta(`SELECT * FROM "aud_approval" WHERE identity = $1 ORDER BY "aud_approval"."id" LIMIT $2`)).
mock.ExpectQuery(regexp.QuoteMeta(`SELECT * FROM "audit_approval" WHERE identity = $1 ORDER BY "audit_approval"."id" LIMIT $2`)).
WithArgs("approval-a", 1).
WillReturnRows(sqlmock.NewRows([]string{"id", "identity", "created_at", "updated_at", "status", "version", "business_type", "business_identity", "applicant_identity", "opinion", "handler_identity", "handled_at"}).
AddRow(uint64(1), "approval-a", now, now, "pending", 1, "refund", "payment-a", "applicant-a", "", "", nil))
mock.ExpectExec(regexp.QuoteMeta(`UPDATE "aud_approval" SET "handled_at"=$1,"handler_identity"=$2,"opinion"=$3,"status"=$4,"updated_at"=$5 WHERE identity = $6 AND status = $7`)).
mock.ExpectExec(regexp.QuoteMeta(`UPDATE "audit_approval" SET "handled_at"=$1,"handler_identity"=$2,"opinion"=$3,"status"=$4,"updated_at"=$5 WHERE identity = $6 AND status = $7`)).
WithArgs(sqlmock.AnyArg(), "operator-a", "accepted", "approved", sqlmock.AnyArg(), "approval-a", "pending").
WillReturnResult(sqlmock.NewResult(0, 1))
mock.ExpectQuery(regexp.QuoteMeta(`INSERT INTO "aud_operation_log" ("identity","created_at","updated_at","status","version","operator_identity","action","object_type","object_identity","before_data","after_data") VALUES ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11) RETURNING "id"`)).
WithArgs(sqlmock.AnyArg(), sqlmock.AnyArg(), sqlmock.AnyArg(), "enabled", 1, "operator-a", "approve", "aud_approval", "approval-a", jsonContaining(`"status":"pending"`), jsonContaining(`"handler_identity":"operator-a"`)).
mock.ExpectQuery(regexp.QuoteMeta(`INSERT INTO "audit_operation_log" ("identity","created_at","updated_at","status","version","operator_identity","action","object_type","object_identity","before_data","after_data") VALUES ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11) RETURNING "id"`)).
WithArgs(sqlmock.AnyArg(), sqlmock.AnyArg(), sqlmock.AnyArg(), "enabled", 1, "operator-a", "approve", "audit_approval", "approval-a", jsonContaining(`"status":"pending"`), jsonContaining(`"handler_identity":"operator-a"`)).
WillReturnRows(sqlmock.NewRows([]string{"id"}).AddRow(uint64(2)))
mock.ExpectCommit()
ctx, recorder := updateContext(http.MethodPost, "/audit/aud_approval/approval-a/approve", "approval-a", []byte(`{"status":"approved","opinion":"accepted","business_identity":"payment-b"}`))
ctx, recorder := updateContext(http.MethodPost, "/audit/audit_approval/approval-a/approve", "approval-a", []byte(`{"status":"approved","opinion":"accepted","business_identity":"payment-b"}`))
ctx.Set("Auth", &types.JwtClaims{Identity: "operator-a"})
ApproveAudit(ctx)
@@ -59,7 +59,7 @@ func TestApproveAuditRejectsStatusesOutsideApprovedAndRejected(t *testing.T) {
for _, decision := range []string{"pending", "archived"} {
t.Run(decision, func(t *testing.T) {
_, mock := setupPlatformRoleDatabase(t)
ctx, recorder := updateContext(http.MethodPost, "/audit/aud_approval/approval-a/approve", "approval-a", []byte(`{"status":"`+decision+`"}`))
ctx, recorder := updateContext(http.MethodPost, "/audit/audit_approval/approval-a/approve", "approval-a", []byte(`{"status":"`+decision+`"}`))
ctx.Set("Auth", &types.JwtClaims{Identity: "operator-a"})
ApproveAudit(ctx)
@@ -73,12 +73,12 @@ func TestApproveAuditRejectsStatusesOutsideApprovedAndRejected(t *testing.T) {
func TestApproveAuditRejectsAlreadyHandledApproval(t *testing.T) {
_, mock := setupPlatformRoleDatabase(t)
mock.ExpectBegin()
mock.ExpectQuery(regexp.QuoteMeta(`SELECT * FROM "aud_approval" WHERE identity = $1 ORDER BY "aud_approval"."id" LIMIT $2`)).
mock.ExpectQuery(regexp.QuoteMeta(`SELECT * FROM "audit_approval" WHERE identity = $1 ORDER BY "audit_approval"."id" LIMIT $2`)).
WithArgs("approval-a", 1).
WillReturnRows(approvalRows("approval-a", "approved", "applicant-a"))
mock.ExpectRollback()
ctx, recorder := updateContext(http.MethodPost, "/audit/aud_approval/approval-a/approve", "approval-a", []byte(`{"status":"approved"}`))
ctx, recorder := updateContext(http.MethodPost, "/audit/audit_approval/approval-a/approve", "approval-a", []byte(`{"status":"approved"}`))
ctx.Set("Auth", &types.JwtClaims{Identity: "operator-a"})
ApproveAudit(ctx)
@@ -89,12 +89,12 @@ func TestApproveAuditRejectsAlreadyHandledApproval(t *testing.T) {
func TestApproveAuditRejectsTheApplicant(t *testing.T) {
_, mock := setupPlatformRoleDatabase(t)
mock.ExpectBegin()
mock.ExpectQuery(regexp.QuoteMeta(`SELECT * FROM "aud_approval" WHERE identity = $1 ORDER BY "aud_approval"."id" LIMIT $2`)).
mock.ExpectQuery(regexp.QuoteMeta(`SELECT * FROM "audit_approval" WHERE identity = $1 ORDER BY "audit_approval"."id" LIMIT $2`)).
WithArgs("approval-a", 1).
WillReturnRows(approvalRows("approval-a", "pending", "operator-a"))
mock.ExpectRollback()
ctx, recorder := updateContext(http.MethodPost, "/audit/aud_approval/approval-a/approve", "approval-a", []byte(`{"status":"approved"}`))
ctx, recorder := updateContext(http.MethodPost, "/audit/audit_approval/approval-a/approve", "approval-a", []byte(`{"status":"approved"}`))
ctx.Set("Auth", &types.JwtClaims{Identity: "operator-a"})
ApproveAudit(ctx)
@@ -105,15 +105,15 @@ func TestApproveAuditRejectsTheApplicant(t *testing.T) {
func TestApproveAuditRejectsAConcurrentSecondDecision(t *testing.T) {
_, mock := setupPlatformRoleDatabase(t)
mock.ExpectBegin()
mock.ExpectQuery(regexp.QuoteMeta(`SELECT * FROM "aud_approval" WHERE identity = $1 ORDER BY "aud_approval"."id" LIMIT $2`)).
mock.ExpectQuery(regexp.QuoteMeta(`SELECT * FROM "audit_approval" WHERE identity = $1 ORDER BY "audit_approval"."id" LIMIT $2`)).
WithArgs("approval-a", 1).
WillReturnRows(approvalRows("approval-a", "pending", "applicant-a"))
mock.ExpectExec(regexp.QuoteMeta(`UPDATE "aud_approval" SET "handled_at"=$1,"handler_identity"=$2,"opinion"=$3,"status"=$4,"updated_at"=$5 WHERE identity = $6 AND status = $7`)).
mock.ExpectExec(regexp.QuoteMeta(`UPDATE "audit_approval" SET "handled_at"=$1,"handler_identity"=$2,"opinion"=$3,"status"=$4,"updated_at"=$5 WHERE identity = $6 AND status = $7`)).
WithArgs(sqlmock.AnyArg(), "operator-a", "", "approved", sqlmock.AnyArg(), "approval-a", "pending").
WillReturnResult(sqlmock.NewResult(0, 0))
mock.ExpectRollback()
ctx, recorder := updateContext(http.MethodPost, "/audit/aud_approval/approval-a/approve", "approval-a", []byte(`{"status":"approved"}`))
ctx, recorder := updateContext(http.MethodPost, "/audit/audit_approval/approval-a/approve", "approval-a", []byte(`{"status":"approved"}`))
ctx.Set("Auth", &types.JwtClaims{Identity: "operator-a"})
ApproveAudit(ctx)

View File

@@ -15,7 +15,7 @@ func TestDashboardOverviewReturnsZeroValuesForAnEmptyDatabase(t *testing.T) {
`SELECT count\(\*\) FROM "delivery_basic" WHERE status = \$1`,
`SELECT count\(\*\) FROM "staff_account" WHERE work_status = \$1`,
`SELECT count\(\*\) FROM "user_account" WHERE status = \$1`,
`SELECT count\(\*\) FROM "saf_event" WHERE status = \$1`,
`SELECT count\(\*\) FROM "safe_event" WHERE status = \$1`,
} {
mock.ExpectQuery(regexp.MustCompile(query).String()).WithArgs(sqlmock.AnyArg()).WillReturnRows(sqlmock.NewRows([]string{"count"}).AddRow(0))
}

View File

@@ -75,7 +75,7 @@ func ExpectedResources() []ResourceContract {
resourceContract("staff", "staff_account", Writable, "list"), resourceContract("staff", "staff_credential", Writable, "list"),
resourceContract("user", "user_account", Writable, "list"), resourceContract("user", "user_address", Writable, "list"), resourceContract("user", "user_service_relation", Writable, "list"),
resourceContract("device", "dev_smart_cylinder_valve", Writable, "list"), resourceContract("device", "dev_device_binding", Writable, "list"), resourceContract("device", "dev_telemetry", ReadOnly, "list"),
resourceContract("safety", "saf_rule", Writable, "list"), resourceContract("safety", "saf_event", Writable, "list"), resourceContract("safety", "saf_inspection", Writable, "list"), resourceContract("safety", "saf_event_disposal", AppendOnly, "list"),
resourceContract("safety", "safe_rule", Writable, "list"), resourceContract("safety", "safe_event", Writable, "list"), resourceContract("safety", "safe_inspection", Writable, "list"), resourceContract("safety", "safe_event_disposal", AppendOnly, "list"),
resourceContract("ec", "ec_category", Writable, "list"), resourceContract("ec", "ec_product", Writable, "list"), resourceContract("ec", "ec_product_attribute", Writable, "list"), resourceContract("ec", "ec_product_image", Writable, "list"), resourceContract("ec", "ec_cart", Writable, "list"), resourceContract("ec", "ec_order", Writable, "list"), resourceContract("ec", "ec_order_item", Writable, "list"), resourceContract("ec", "ec_review", Writable, "list"),
resourceContract("delivery", "delivery_task", Writable, "list"), resourceContract("delivery", "delivery_track", Writable, "list"), resourceContract("delivery", "delivery_track_point", ReadOnly, "list"),
resourceContract("finance", "fin_payment", Writable, "list"), resourceContract("finance", "fin_settlement", Writable, "list"), resourceContract("finance", "fin_reconciliation", Writable, "list"),
@@ -83,7 +83,7 @@ func ExpectedResources() []ResourceContract {
resourceContract("platform", "platfrom_account", Writable, "list"), resourceContract("platform", "platform_role", Writable, "list"), resourceContract("platform", "platform_menu", Writable, "tree"),
resourceContract("wallet", "wallet", ReadOnly, "list"), resourceContract("wallet", "wallet_ledger", ReadOnly, "list"), resourceContract("wallet", "wallet_recharge", ReadOnly, "list"), resourceContract("wallet", "wallet_withdrawal", ReadOnly, "list"),
resourceContract("report", "report", ReadOnly, "list"), resourceContract("report", "report_item", ReadOnly, "list"), resourceContract("report", "report_metric_snapshot", ReadOnly, "list"),
resourceContract("audit", "aud_operation_log", ReadOnly, "list"), resourceContract("audit", "aud_export_log", ReadOnly, "list"), resourceContract("audit", "aud_approval", ReadOnly, "list"),
resourceContract("audit", "audit_operation_log", ReadOnly, "list"), resourceContract("audit", "audit_export_log", ReadOnly, "list"), resourceContract("audit", "audit_approval", ReadOnly, "list"),
}
}
@@ -103,8 +103,8 @@ func resourcePath(domain, name string) string {
return "/user/address"
case "user_service_relation":
return "/user/service_relation"
case "saf_event_disposal":
return "/safety/saf_event/:identity/disposals"
case "safe_event_disposal":
return "/safety/safe_event/:identity/disposals"
default:
return "/" + domain + "/" + name
}

View File

@@ -250,8 +250,8 @@ func TestPrepareResourceValuesResolvesRequiredIdentityRelationsAndRejectsInvalid
func TestPrepareResourceValuesNormalizesStringJSONBFields(t *testing.T) {
t.Run("safety rule", func(t *testing.T) {
ctx, _ := updateContext(http.MethodPost, "/safety/saf_rule", "", []byte(`{"rule_code":"pressure-limit","threshold":{"max":10},"action":"close-valve","gray_scope":["north"]}`))
values, err := prepareResourceValues(ctx, &models.SafRule{}, []string{"rule_code", "threshold", "action", "gray_scope"}, nil)
ctx, _ := updateContext(http.MethodPost, "/safety/safe_rule", "", []byte(`{"rule_code":"pressure-limit","threshold":{"max":10},"action":"close-valve","gray_scope":["north"]}`))
values, err := prepareResourceValues(ctx, &models.SafeRule{}, []string{"rule_code", "threshold", "action", "gray_scope"}, nil)
if err != nil {
t.Fatal(err)
}
@@ -284,8 +284,8 @@ func TestPrepareResourceValuesNormalizesStringJSONBFields(t *testing.T) {
})
t.Run("invalid json string", func(t *testing.T) {
ctx, _ := updateContext(http.MethodPost, "/safety/saf_rule", "", []byte(`{"rule_code":"pressure-limit","threshold":"{invalid}","action":"close-valve"}`))
if _, err := prepareResourceValues(ctx, &models.SafRule{}, []string{"rule_code", "threshold", "action"}, nil); err == nil {
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.Fatal("invalid JSON string was accepted for a string/jsonb field")
}
})
@@ -341,7 +341,7 @@ func TestKeywordColumnsUseSafeTextAllowlist(t *testing.T) {
model any
want []string
}{
{"safety rule excludes jsonb", &models.SafRule{}, []string{"rule_code", "action"}},
{"safety rule excludes jsonb", &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{}},
}
@@ -648,19 +648,19 @@ func TestNonRootCannotAssignPlatformAccountRole(t *testing.T) {
func TestListSafetyEventDisposalsReturnsOnlyTheRequestedEventHistory(t *testing.T) {
_, mock := setupPlatformRoleDatabase(t)
mock.ExpectQuery(regexp.QuoteMeta(`SELECT count(*) FROM "saf_event_disposal" WHERE saf_event_identity = $1`)).
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 "saf_event_disposal" WHERE saf_event_identity = $1 ORDER BY created_at asc LIMIT $2`)).
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", "saf_event_identity", "action", "reason", "operator_identity"}).
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/saf_event/event-a/disposals", "event-a", nil)
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(), `"saf_event_identity":"event-a"`) || strings.Contains(recorder.Body.String(), `"id":`) {
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)
@@ -815,19 +815,19 @@ func TestDisposeSafetyEventUpdatesEventAndAppendsOperatorActionTransactionally(t
_, mock := setupPlatformRoleDatabase(t)
now := time.Now().UTC()
mock.ExpectBegin()
mock.ExpectQuery(regexp.QuoteMeta(`SELECT * FROM "saf_event" WHERE identity = $1 ORDER BY "saf_event"."id" LIMIT $2`)).
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 "saf_event" SET "status"=$1,"updated_at"=$2 WHERE identity = $3`)).
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 "saf_event_disposal" ("identity","created_at","updated_at","status","version","saf_event_identity","action","reason","operator_identity") VALUES ($1,$2,$3,$4,$5,$6,$7,$8,$9) RETURNING "id"`)).
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/saf_event/event-a/disposals", "event-a", []byte(`{"action":"close","reason":"resolved"}`))
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)

View File

@@ -565,8 +565,8 @@ func stripInternalIDs(value any) any {
// action record. Disposal records deliberately have no update or delete route.
func ListSafetyEventDisposals(ctx *gin.Context) {
page, size := pageSize(ctx)
var list []models.SafEventDisposal
query := impl.DBService.Model(&models.SafEventDisposal{}).Where("saf_event_identity = ?", ctx.Param("identity"))
var list []models.SafeEventDisposal
query := impl.DBService.Model(&models.SafeEventDisposal{}).Where("safe_event_identity = ?", ctx.Param("identity"))
var total int64
if err := query.Count(&total).Error; err != nil {
infra.Response.Error(ctx, err)
@@ -597,23 +597,23 @@ func DisposeSafetyEvent(ctx *gin.Context) {
if request.Status == "" {
request.Status = "disposed"
}
var disposal models.SafEventDisposal
var disposal models.SafeEventDisposal
err = impl.DBService.Transaction(func(transaction *gorm.DB) error {
var event models.SafEvent
var event models.SafeEvent
if err := transaction.Where("identity = ?", ctx.Param("identity")).First(&event).Error; err != nil {
return err
}
if result := transaction.Model(&models.SafEvent{}).Where("identity = ?", event.Identity).Update("status", request.Status); result.Error != nil {
if result := transaction.Model(&models.SafeEvent{}).Where("identity = ?", event.Identity).Update("status", request.Status); result.Error != nil {
return result.Error
} else if result.RowsAffected == 0 {
return gorm.ErrRecordNotFound
}
disposal = models.SafEventDisposal{
Entity: newEntity("enabled"),
SafEventIdentity: event.Identity,
Action: request.Action,
Reason: request.Reason,
OperatorIdentity: claims.Identity,
disposal = models.SafeEventDisposal{
Entity: newEntity("enabled"),
SafeEventIdentity: event.Identity,
Action: request.Action,
Reason: request.Reason,
OperatorIdentity: claims.Identity,
}
return transaction.Create(&disposal).Error
})

View File

@@ -6,8 +6,8 @@ import (
"git.apinb.com/bsm-sdk/core/database"
)
// AudApproval 对应 aud_approval保存审批流与复核意见。
type AudApproval struct {
// AuditApproval 对应 audit_approval保存审批流与复核意见。
type AuditApproval struct {
Entity // 公共实体字段
BusinessType string `gorm:"column:business_type;type:varchar(64);not null" json:"business_type"` // business_type 业务字段
BusinessIdentity string `gorm:"column:business_identity;type:varchar(36);not null;index" json:"business_identity"` // business_identity 业务字段
@@ -17,5 +17,5 @@ type AudApproval struct {
HandledAt *time.Time `gorm:"column:handled_at;type:timestamptz" json:"handled_at"` // handled_at 业务字段
}
func init() { database.AppendMigrate(&AudApproval{}) }
func (table *AudApproval) TableName() string { return "aud_approval" }
func init() { database.AppendMigrate(&AuditApproval{}) }
func (table *AuditApproval) TableName() string { return "audit_approval" }

View File

@@ -5,8 +5,8 @@ import (
"time"
)
// AudExportLog 对应 aud_export_log保存敏感导出审计。
type AudExportLog struct {
// AuditExportLog 对应 audit_export_log保存敏感导出审计。
type AuditExportLog struct {
Entity // 公共实体字段
ApplicantIdentity string `gorm:"column:applicant_identity;type:varchar(36);not null;index" json:"applicant_identity"` // applicant_identity 业务字段
Purpose string `gorm:"column:purpose;type:varchar(255);not null" json:"purpose"` // purpose 业务字段
@@ -15,5 +15,5 @@ type AudExportLog struct {
FileURI string `gorm:"column:file_uri;type:varchar(512);not null;default:''" json:"file_uri"` // file_uri 业务字段
}
func init() { database.AppendMigrate(&AudExportLog{}) }
func (table *AudExportLog) TableName() string { return "aud_export_log" }
func init() { database.AppendMigrate(&AuditExportLog{}) }
func (table *AuditExportLog) TableName() string { return "audit_export_log" }

View File

@@ -2,8 +2,8 @@ package models
import "git.apinb.com/bsm-sdk/core/database"
// AudOperationLog 对应 aud_operation_log保存不可变操作审计。
type AudOperationLog struct {
// AuditOperationLog 对应 audit_operation_log保存不可变操作审计。
type AuditOperationLog struct {
Entity // 公共实体字段
OperatorIdentity string `gorm:"column:operator_identity;type:varchar(36);not null;index" json:"operator_identity"` // operator_identity 业务字段
Action string `gorm:"column:action;type:varchar(64);not null" json:"action"` // action 业务字段
@@ -13,5 +13,5 @@ type AudOperationLog struct {
AfterData string `gorm:"column:after_data;type:jsonb;not null;default:'{}'" json:"after_data"` // after_data 业务字段
}
func init() { database.AppendMigrate(&AudOperationLog{}) }
func (table *AudOperationLog) TableName() string { return "aud_operation_log" }
func init() { database.AppendMigrate(&AuditOperationLog{}) }
func (table *AuditOperationLog) TableName() string { return "audit_operation_log" }

View File

@@ -26,7 +26,7 @@ func GetDashboardOverview() (DashboardOverview, error) {
if err := impl.DBService.Model(&UserAccount{}).Where("status = ?", "enabled").Count(&overview.UserCount).Error; err != nil {
return DashboardOverview{}, err
}
if err := impl.DBService.Model(&SafEvent{}).Where("status = ?", "pending").Count(&overview.PendingSafetyCount).Error; err != nil {
if err := impl.DBService.Model(&SafeEvent{}).Where("status = ?", "pending").Count(&overview.PendingSafetyCount).Error; err != nil {
return DashboardOverview{}, err
}
return overview, nil

View File

@@ -1,15 +0,0 @@
package models
import "git.apinb.com/bsm-sdk/core/database"
// SafEventDisposal 对应 saf_event_disposal保存安全处置记录。
type SafEventDisposal struct {
Entity // 公共实体字段
SafEventIdentity string `gorm:"column:saf_event_identity;type:varchar(36);not null;index" json:"saf_event_identity"` // saf_event_identity 业务字段
Action string `gorm:"column:action;type:varchar(64);not null" json:"action"` // action 业务字段
Reason string `gorm:"column:reason;type:text;not null;default:''" json:"reason"` // reason 业务字段
OperatorIdentity string `gorm:"column:operator_identity;type:varchar(36);not null;default:''" json:"operator_identity"` // operator_identity 业务字段
}
func init() { database.AppendMigrate(&SafEventDisposal{}) }
func (table *SafEventDisposal) TableName() string { return "saf_event_disposal" }

View File

@@ -5,8 +5,8 @@ import (
"time"
)
// SafEvent 对应 saf_event保存安全事件统一入口。
type SafEvent struct {
// SafeEvent 对应 safe_event保存安全事件统一入口。
type SafeEvent struct {
Entity // 公共实体字段
EventCode string `gorm:"column:event_code;type:varchar(64);not null;uniqueIndex" json:"event_code"` // event_code 业务字段
Level int `gorm:"column:level;not null;default:3" json:"level"` // level 业务字段
@@ -15,5 +15,5 @@ type SafEvent struct {
SLAAt *time.Time `gorm:"column:sla_at;type:timestamptz" json:"sla_at"` // sla_at 业务字段
}
func init() { database.AppendMigrate(&SafEvent{}) }
func (table *SafEvent) TableName() string { return "saf_event" }
func init() { database.AppendMigrate(&SafeEvent{}) }
func (table *SafeEvent) TableName() string { return "safe_event" }

View File

@@ -0,0 +1,15 @@
package models
import "git.apinb.com/bsm-sdk/core/database"
// SafeEventDisposal 对应 safe_event_disposal保存安全处置记录。
type SafeEventDisposal struct {
Entity // 公共实体字段
SafeEventIdentity string `gorm:"column:safe_event_identity;type:varchar(36);not null;index" json:"safe_event_identity"` // safe_event_identity 业务字段
Action string `gorm:"column:action;type:varchar(64);not null" json:"action"` // action 业务字段
Reason string `gorm:"column:reason;type:text;not null;default:''" json:"reason"` // reason 业务字段
OperatorIdentity string `gorm:"column:operator_identity;type:varchar(36);not null;default:''" json:"operator_identity"` // operator_identity 业务字段
}
func init() { database.AppendMigrate(&SafeEventDisposal{}) }
func (table *SafeEventDisposal) TableName() string { return "safe_event_disposal" }

View File

@@ -2,8 +2,8 @@ package models
import "git.apinb.com/bsm-sdk/core/database"
// SafInspection 对应 saf_inspection保存安检与复检记录。
type SafInspection struct {
// SafeInspection 对应 safe_inspection保存安检与复检记录。
type SafeInspection struct {
Entity // 公共实体字段
UserAccountID uint64 `gorm:"column:user_account_id;not null;index" json:"user_account_id"` // user_account_id 业务字段
StaffAccountID uint64 `gorm:"column:staff_account_id;not null;index" json:"staff_account_id"` // staff_account_id 业务字段
@@ -11,5 +11,5 @@ type SafInspection struct {
EvidenceURI string `gorm:"column:evidence_uri;type:varchar(512);not null;default:''" json:"evidence_uri"` // evidence_uri 业务字段
}
func init() { database.AppendMigrate(&SafInspection{}) }
func (table *SafInspection) TableName() string { return "saf_inspection" }
func init() { database.AppendMigrate(&SafeInspection{}) }
func (table *SafeInspection) TableName() string { return "safe_inspection" }

View File

@@ -2,8 +2,8 @@ package models
import "git.apinb.com/bsm-sdk/core/database"
// SafRule 对应 saf_rule保存安全规则。
type SafRule struct {
// SafeRule 对应 safe_rule保存安全规则。
type SafeRule struct {
Entity // 公共实体字段
RuleCode string `gorm:"column:rule_code;type:varchar(64);not null;uniqueIndex" json:"rule_code"` // rule_code 业务字段
VersionNo int `gorm:"column:version_no;not null;default:1" json:"version_no"` // version_no 业务字段
@@ -12,5 +12,5 @@ type SafRule struct {
GrayScope string `gorm:"column:gray_scope;type:jsonb;not null;default:'{}'" json:"gray_scope"` // gray_scope 业务字段
}
func init() { database.AppendMigrate(&SafRule{}) }
func (table *SafRule) TableName() string { return "saf_rule" }
func init() { database.AppendMigrate(&SafeRule{}) }
func (table *SafeRule) TableName() string { return "safe_rule" }

View File

@@ -62,11 +62,11 @@ func registerDeviceRoute(group *gin.RouterGroup) {
}
func registerSafetyRoute(group *gin.RouterGroup) {
registerRestrictedWritableResource(group, "/safety/saf_rule", &models.SafRule{}, []string{"rule_code", "version_no", "threshold", "action", "gray_scope"})
registerRestrictedWritableResource(group, "/safety/saf_event", &models.SafEvent{}, []string{"event_code", "level", "title", "smart_cylinder_valve_identity", "sla_at"})
registerRestrictedWritableResource(group, "/safety/saf_inspection", &models.SafInspection{}, []string{"result", "evidence_uri"}, requiredRelation("user_account_identity", "user_account_id", &models.UserAccount{}), requiredRelation("staff_account_identity", "staff_account_id", &models.StaffAccount{}))
group.GET("/safety/saf_event/:identity/disposals", platform.ListSafetyEventDisposals)
group.POST("/safety/saf_event/:identity/disposals", platform.DisposeSafetyEvent)
registerRestrictedWritableResource(group, "/safety/safe_rule", &models.SafeRule{}, []string{"rule_code", "version_no", "threshold", "action", "gray_scope"})
registerRestrictedWritableResource(group, "/safety/safe_event", &models.SafeEvent{}, []string{"event_code", "level", "title", "smart_cylinder_valve_identity", "sla_at"})
registerRestrictedWritableResource(group, "/safety/safe_inspection", &models.SafeInspection{}, []string{"result", "evidence_uri"}, requiredRelation("user_account_identity", "user_account_id", &models.UserAccount{}), requiredRelation("staff_account_identity", "staff_account_id", &models.StaffAccount{}))
group.GET("/safety/safe_event/:identity/disposals", platform.ListSafetyEventDisposals)
group.POST("/safety/safe_event/:identity/disposals", platform.DisposeSafetyEvent)
}
func registerCommerceRoute(group *gin.RouterGroup) {
@@ -138,10 +138,10 @@ func registerContentRoute(group *gin.RouterGroup) {
}
func registerAuditRoute(group *gin.RouterGroup) {
registerReadOnlyResource(group, "/audit/aud_operation_log", &models.AudOperationLog{})
registerReadOnlyResource(group, "/audit/aud_export_log", &models.AudExportLog{})
registerReadOnlyResource(group, "/audit/aud_approval", &models.AudApproval{})
group.POST("/audit/aud_approval/:identity/approve", platform.ApproveAudit)
registerReadOnlyResource(group, "/audit/audit_operation_log", &models.AuditOperationLog{})
registerReadOnlyResource(group, "/audit/audit_export_log", &models.AuditExportLog{})
registerReadOnlyResource(group, "/audit/audit_approval", &models.AuditApproval{})
group.POST("/audit/audit_approval/:identity/approve", platform.ApproveAudit)
}
func registerWritableResource(group *gin.RouterGroup, path string, list, create, get, update gin.HandlerFunc, model any) {