package audit import ( "context" "strconv" "gorm.io/gorm" "github.com/break/junhong_cmp_fiber/pkg/constants" pkgerrors "github.com/break/junhong_cmp_fiber/pkg/errors" "github.com/break/junhong_cmp_fiber/pkg/middleware" ) // AssetAutoRenewalConfigAudit 是资产钱包自动续费配置保存的审计事实。 // // 前后值快照由调用方在保存事务内组装:Before 为保存前的开关、范围、集合、天数与版本, // After 为保存后的对应值。审计写入与配置保存同事务,未注册时整体失败(fail-closed)。 type AssetAutoRenewalConfigAudit struct { OperatorID uint OperationType string Description string BeforeData map[string]any AfterData map[string]any Result string ErrorCode string ErrorSummary string RequestID string CorrelationID string } // WriteAssetAutoRenewalConfigChange 将自动续费配置变化转换为统一 Audit Event。 func (w *Writer) WriteAssetAutoRenewalConfigChange(ctx context.Context, tx *gorm.DB, change AssetAutoRenewalConfigAudit) error { operationType := change.OperationType if operationType != "" && operationType != constants.AuditOperationAssetAutoRenewalConfigUpdate { return pkgerrors.New(pkgerrors.CodeInvalidParam, "审计动作未注册") } action, ok := w.registry.ActionByOperation(constants.AuditOperationAssetAutoRenewalConfigUpdate) if !ok { return pkgerrors.New(pkgerrors.CodeInvalidParam, "审计动作未注册") } if change.OperatorID == 0 { return pkgerrors.New(pkgerrors.CodeInvalidParam, "自动续费配置审计操作者缺失") } result := change.Result if result == "" { result = constants.AuditResultSuccess } summary := change.Description if summary == "" { summary = "保存资产钱包自动续费配置" } configID := strconv.FormatUint(uint64(constants.AssetAutoRenewalConfigSingletonID), 10) return w.Append(ctx, tx, AppendInput{ ActionCode: action.Code, Summary: summary, Actor: ActorInput{ Kind: constants.AuditActorAccount, ID: strconv.FormatUint(uint64(change.OperatorID), 10), Name: middleware.GetUsernameFromContext(ctx), }, Source: action.Source, RequestPath: contextString(middleware.GetRequestPathFromContext(ctx)), RequestMethod: contextString(middleware.GetRequestMethodFromContext(ctx)), IPAddress: contextString(middleware.GetIPFromContext(ctx)), UserAgent: contextString(middleware.GetUserAgentFromContext(ctx)), ScopeType: constants.AuditScopePlatform, Result: result, ErrorCode: change.ErrorCode, ErrorSummary: change.ErrorSummary, RequestID: change.RequestID, CorrelationID: change.CorrelationID, Resources: []ResourceInput{{ Type: constants.AuditResourceAssetAutoRenewalConfig, ID: &configID, Key: configID, DisplayName: constants.AssetAutoRenewalConfigDisplayName, Relation: constants.AuditResourceRelationPrimary, Role: constants.AuditResourceRoleAssetAutoRenewalConfigTarget, BeforeData: change.BeforeData, AfterData: change.AfterData, SubjectVisibility: constants.AuditSubjectInternalOnly, }}, }) }