Files
junhong_cmp_fiber/internal/service/polling/audit.go
break 5e552d99bc 收口审计治理与套餐任务进展
Constraint: 在线热修前必须保存当前迭代分支全部有效代码进展
Confidence: medium
Scope-risk: broad
Directive: 后续修改需保持审计事件与业务事务边界一致
Tested: git diff --cached --check
Not-tested: 未运行全量测试,提交用于切换分支前保存既有工作
2026-08-05 14:30:54 +08:00

122 lines
4.6 KiB
Go

package polling
import (
"context"
stderrors "errors"
"strconv"
"gorm.io/gorm"
auditinfra "github.com/break/junhong_cmp_fiber/internal/infrastructure/audit"
"github.com/break/junhong_cmp_fiber/internal/model"
"github.com/break/junhong_cmp_fiber/pkg/auditcontext"
"github.com/break/junhong_cmp_fiber/pkg/auditfailure"
"github.com/break/junhong_cmp_fiber/pkg/constants"
pkgerrors "github.com/break/junhong_cmp_fiber/pkg/errors"
)
func runPollingTransaction(ctx context.Context, db *gorm.DB, writer *auditinfra.Writer, fn func(*gorm.DB) error) error {
if db == nil || writer == nil {
return pkgerrors.New(pkgerrors.CodeInvalidStatus, "统一轮询审计接缝未配置")
}
return db.WithContext(ctx).Transaction(fn)
}
func writePollingAudit(ctx context.Context, tx *gorm.DB, writer *auditinfra.Writer, input auditinfra.PollingInput) error {
return writer.WritePolling(ctx, tx, input)
}
func recordPollingFailure(ctx context.Context, db *gorm.DB, writer *auditinfra.Writer, input auditinfra.PollingInput, originalErr error) {
if input.OperatorID == 0 || input.ResourceType == "" || input.ResourceKey == "" {
return
}
var appErr *pkgerrors.AppError
if !stderrors.As(originalErr, &appErr) {
appErr = pkgerrors.New(pkgerrors.CodeInternalError, "轮询操作失败")
}
if input.Result == "" {
input.Result = constants.AuditResultFailed
}
if input.ErrorCode == "" {
input.ErrorCode = strconv.Itoa(appErr.Code)
}
if input.ErrorSummary == "" {
input.ErrorSummary = appErr.Message
}
if db != nil && writer != nil {
if err := db.WithContext(ctx).Transaction(func(tx *gorm.DB) error {
return writePollingAudit(ctx, tx, writer, input)
}); err == nil {
return
} else {
originalErr = err
}
}
linkage := auditcontext.From(ctx)
auditfailure.RecordSecondaryWriteFailure(
input.ActionCode, input.ResourceKey, linkage.RequestID, linkage.CorrelationID, input.ErrorCode, originalErr,
)
}
func pollingConfigIdentity(config *model.PollingConfig) map[string]any {
return map[string]any{
"id": config.ID, "config_name": config.ConfigName, "card_condition": config.CardCondition,
"card_category": config.CardCategory, "carrier_id": config.CarrierID, "priority": config.Priority,
"status": config.Status,
}
}
func pollingConfigState(config *model.PollingConfig) map[string]any {
return map[string]any{
"config_name": config.ConfigName, "card_condition": config.CardCondition,
"card_category": config.CardCategory, "carrier_id": config.CarrierID, "priority": config.Priority,
"realname_check_interval": config.RealnameCheckInterval, "carddata_check_interval": config.CarddataCheckInterval,
"package_check_interval": config.PackageCheckInterval, "protect_check_interval": config.ProtectCheckInterval,
"card_status_check_interval": config.CardStatusCheckInterval, "status": config.Status,
"description": config.Description,
}
}
func pollingConcurrencyIdentity(config *model.PollingConcurrencyConfig) map[string]any {
return map[string]any{"id": config.ID, "task_type": config.TaskType, "max_concurrency": config.MaxConcurrency}
}
func pollingAlertRuleIdentity(rule *model.PollingAlertRule) map[string]any {
return map[string]any{
"id": rule.ID, "rule_name": rule.RuleName, "task_type": rule.TaskType,
"metric_type": rule.MetricType, "operator": rule.Operator, "threshold": rule.Threshold,
"alert_level": rule.AlertLevel, "status": rule.Status,
}
}
func pollingAlertRuleState(rule *model.PollingAlertRule) map[string]any {
return map[string]any{
"rule_name": rule.RuleName, "task_type": rule.TaskType, "metric_type": rule.MetricType,
"operator": rule.Operator, "threshold": rule.Threshold, "duration_minutes": rule.DurationMinutes,
"alert_level": rule.AlertLevel, "status": rule.Status, "cooldown_minutes": rule.CooldownMinutes,
"notification_channels_configured": rule.NotificationChannels != "", "description": rule.Description,
}
}
func pollingManualTriggerIdentity(log *model.PollingManualTriggerLog) map[string]any {
return map[string]any{
"id": log.ID, "task_type": log.TaskType, "trigger_type": log.TriggerType,
"total_count": log.TotalCount, "status": log.Status, "triggered_by": log.TriggeredBy,
}
}
func pollingManualTriggerKey(id uint) string {
return strconv.FormatUint(uint64(id), 10)
}
func pollingManualAttemptKey(taskType, triggerType string, operatorID uint) string {
return triggerType + ":" + taskType + ":" + strconv.FormatUint(uint64(operatorID), 10)
}
func pollingManualAttemptIdentity(taskType, triggerType string, totalCount int, operatorID uint) map[string]any {
return map[string]any{
"task_type": taskType, "trigger_type": triggerType,
"total_count": totalCount, "triggered_by": operatorID,
}
}