feat: add platform resource audit baseline
This commit is contained in:
69
backend/api/internal/logic/platform/resource.go
Normal file
69
backend/api/internal/logic/platform/resource.go
Normal file
@@ -0,0 +1,69 @@
|
||||
package platform
|
||||
|
||||
// ResourceMode describes the operations a platform-admin resource supports.
|
||||
type ResourceMode string
|
||||
|
||||
const (
|
||||
Writable ResourceMode = "writable"
|
||||
ReadOnly ResourceMode = "readonly"
|
||||
AppendOnly ResourceMode = "append_only"
|
||||
)
|
||||
|
||||
// ResourceContract is the expected cross-layer representation of one resource.
|
||||
type ResourceContract struct {
|
||||
Domain string
|
||||
Name string
|
||||
PageKind string
|
||||
Mode ResourceMode
|
||||
}
|
||||
|
||||
// ExpectedResources returns the complete platform-admin resource catalogue.
|
||||
func ExpectedResources() []ResourceContract {
|
||||
return []ResourceContract{
|
||||
{Domain: "gas", Name: "gas_basic", Mode: Writable, PageKind: "list"},
|
||||
{Domain: "gas", Name: "gas_account", Mode: Writable, PageKind: "list"},
|
||||
{Domain: "delivery", Name: "delivery_basic", Mode: Writable, PageKind: "list"},
|
||||
{Domain: "delivery", Name: "delivery_account", Mode: Writable, PageKind: "list"},
|
||||
{Domain: "staff", Name: "staff_account", Mode: Writable, PageKind: "list"},
|
||||
{Domain: "staff", Name: "staff_credential", Mode: Writable, PageKind: "list"},
|
||||
{Domain: "user", Name: "user_account", Mode: Writable, PageKind: "list"},
|
||||
{Domain: "user", Name: "user_address", Mode: Writable, PageKind: "list"},
|
||||
{Domain: "user", Name: "user_service_relation", Mode: Writable, PageKind: "list"},
|
||||
{Domain: "device", Name: "dev_smart_cylinder_valve", Mode: Writable, PageKind: "list"},
|
||||
{Domain: "device", Name: "dev_device_binding", Mode: Writable, PageKind: "list"},
|
||||
{Domain: "device", Name: "saf_rule", Mode: Writable, PageKind: "list"},
|
||||
{Domain: "device", Name: "saf_event", Mode: Writable, PageKind: "list"},
|
||||
{Domain: "device", Name: "saf_inspection", Mode: Writable, PageKind: "list"},
|
||||
{Domain: "commerce", Name: "ec_category", Mode: Writable, PageKind: "list"},
|
||||
{Domain: "commerce", Name: "ec_product", Mode: Writable, PageKind: "list"},
|
||||
{Domain: "commerce", Name: "ec_product_attribute", Mode: Writable, PageKind: "list"},
|
||||
{Domain: "commerce", Name: "ec_product_image", Mode: Writable, PageKind: "list"},
|
||||
{Domain: "commerce", Name: "ec_cart", Mode: Writable, PageKind: "list"},
|
||||
{Domain: "commerce", Name: "ec_order", Mode: Writable, PageKind: "list"},
|
||||
{Domain: "commerce", Name: "ec_review", Mode: Writable, PageKind: "list"},
|
||||
{Domain: "delivery", Name: "delivery_task", Mode: Writable, PageKind: "list"},
|
||||
{Domain: "delivery", Name: "delivery_track", Mode: Writable, PageKind: "list"},
|
||||
{Domain: "delivery", Name: "delivery_track_point", Mode: Writable, PageKind: "list"},
|
||||
{Domain: "finance", Name: "fin_payment", Mode: Writable, PageKind: "list"},
|
||||
{Domain: "finance", Name: "fin_settlement", Mode: Writable, PageKind: "list"},
|
||||
{Domain: "finance", Name: "fin_reconciliation", Mode: Writable, PageKind: "list"},
|
||||
{Domain: "content", Name: "cnt_content", Mode: Writable, PageKind: "list"},
|
||||
{Domain: "notification", Name: "ntf_template", Mode: Writable, PageKind: "list"},
|
||||
{Domain: "customer_service", Name: "cs_ticket", Mode: Writable, PageKind: "list"},
|
||||
{Domain: "platform", Name: "platfrom_account", Mode: Writable, PageKind: "list"},
|
||||
{Domain: "platform", Name: "platform_role", Mode: Writable, PageKind: "list"},
|
||||
{Domain: "platform", Name: "platform_menu", Mode: Writable, PageKind: "tree"},
|
||||
{Domain: "device", Name: "dev_telemetry", Mode: ReadOnly, PageKind: "list"},
|
||||
{Domain: "wallet", Name: "wallet", Mode: ReadOnly, PageKind: "list"},
|
||||
{Domain: "wallet", Name: "wallet_ledger", Mode: ReadOnly, PageKind: "list"},
|
||||
{Domain: "wallet", Name: "wallet_recharge", Mode: ReadOnly, PageKind: "list"},
|
||||
{Domain: "wallet", Name: "wallet_withdrawal", Mode: ReadOnly, PageKind: "list"},
|
||||
{Domain: "report", Name: "report", Mode: ReadOnly, PageKind: "list"},
|
||||
{Domain: "report", Name: "report_item", Mode: ReadOnly, PageKind: "list"},
|
||||
{Domain: "report", Name: "report_metric_snapshot", Mode: ReadOnly, PageKind: "list"},
|
||||
{Domain: "audit", Name: "aud_operation_log", Mode: ReadOnly, PageKind: "list"},
|
||||
{Domain: "audit", Name: "aud_export_log", Mode: ReadOnly, PageKind: "list"},
|
||||
{Domain: "audit", Name: "aud_approval", Mode: ReadOnly, PageKind: "list"},
|
||||
{Domain: "device", Name: "saf_event_disposal", Mode: AppendOnly, PageKind: "list"},
|
||||
}
|
||||
}
|
||||
19
backend/api/internal/logic/platform/resource_test.go
Normal file
19
backend/api/internal/logic/platform/resource_test.go
Normal file
@@ -0,0 +1,19 @@
|
||||
package platform
|
||||
|
||||
import "testing"
|
||||
|
||||
func TestExpectedResources(t *testing.T) {
|
||||
assertContract(t, ExpectedResources(), "gas", "gas_basic", Writable, "list")
|
||||
assertContract(t, ExpectedResources(), "device", "saf_event", Writable, "list")
|
||||
assertContract(t, ExpectedResources(), "wallet", "wallet_ledger", ReadOnly, "list")
|
||||
}
|
||||
|
||||
func assertContract(t *testing.T, contracts []ResourceContract, domain, name string, mode ResourceMode, pageKind string) {
|
||||
t.Helper()
|
||||
for _, contract := range contracts {
|
||||
if contract.Domain == domain && contract.Name == name && contract.Mode == mode && contract.PageKind == pageKind {
|
||||
return
|
||||
}
|
||||
}
|
||||
t.Fatalf("missing resource contract %s/%s with mode %q and page kind %q", domain, name, mode, pageKind)
|
||||
}
|
||||
22
backend/api/internal/routers/platform_test.go
Normal file
22
backend/api/internal/routers/platform_test.go
Normal file
@@ -0,0 +1,22 @@
|
||||
package routers
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
func TestPlatformGasRouteUsesGasBasic(t *testing.T) {
|
||||
engine := gin.New()
|
||||
RegisterPlatform("heqi", engine)
|
||||
|
||||
for _, route := range engine.Routes() {
|
||||
if route.Path == "/heqi/platform/v1/gas/gas_station" {
|
||||
t.Fatal("gas station route must use gas_basic as its resource name")
|
||||
}
|
||||
if route.Method == "GET" && route.Path == "/heqi/platform/v1/gas/gas_basic" {
|
||||
return
|
||||
}
|
||||
}
|
||||
t.Fatal("gas_basic list route is not registered")
|
||||
}
|
||||
Reference in New Issue
Block a user