Files
junhong_cmp_fiber/internal/task/polling_integration_log.go
2026-09-02 16:14:27 +08:00

59 lines
2.5 KiB
Go

package task
import (
"context"
"strconv"
"time"
"github.com/google/uuid"
"github.com/break/junhong_cmp_fiber/internal/infrastructure/integrationlog"
"github.com/break/junhong_cmp_fiber/internal/model"
"github.com/break/junhong_cmp_fiber/pkg/constants"
"github.com/break/junhong_cmp_fiber/pkg/errors"
)
// newGatewayAttempt 只在内存中准备稳定关联标识;成功无变化的轮询不落库。
func newGatewayAttempt(cardID uint, operation, scene string) integrationlog.Attempt {
resourceID := strconv.FormatUint(uint64(cardID), 10)
integrationID := uuid.NewString()
triggerSource := constants.CardObservationSourcePolling
triggerScene := scene
return integrationlog.Attempt{IntegrationID: integrationID,
Provider: constants.IntegrationProviderGateway, Direction: constants.IntegrationDirectionOutbound,
Operation: operation, ResourceType: constants.AssetTypeIotCard, ResourceID: &resourceID,
TriggerSource: &triggerSource, TriggerScene: &triggerScene, TriggerSeries: &integrationID,
CorrelationID: &integrationID, RequestSummary: map[string]any{"card_id": cardID},
Metadata: map[string]any{"scene": scene}}
}
// recordGatewayAttempt 在结果明确后才写入外部交互日志。
func recordGatewayAttempt(ctx context.Context, repository *integrationlog.Repository, attempt integrationlog.Attempt, result string, changed bool, summary string) error {
if repository == nil {
return errors.New(errors.CodeInternalError, "Gateway Integration Log 未配置")
}
attempt.InitialResult = result
attempt.StateChanged = changed
attempt.Metadata = map[string]any{"scene": attempt.TriggerScene, "summary": summary}
_, err := repository.Start(ctx, attempt)
return err
}
// completeGatewayAttempt 记录 Gateway 查询成功或明确失败,不把响应正文写入日志。
func completeGatewayAttempt(ctx context.Context, repository *integrationlog.Repository, attempt *model.IntegrationLog, success bool, startedAt time.Time) error {
if repository == nil || attempt == nil {
return errors.New(errors.CodeInternalError, "Gateway Integration Log 尝试不存在")
}
completionCtx, cancel := context.WithTimeout(context.WithoutCancel(ctx), 5*time.Second)
defer cancel()
result := constants.IntegrationResultFailed
if success {
result = constants.IntegrationResultSuccess
}
_, err := repository.Complete(completionCtx, attempt.IntegrationID, integrationlog.Completion{
Result: result, DurationMS: time.Since(startedAt).Milliseconds(), StateChanged: false,
ResponseSummary: map[string]any{"success": success},
})
return err
}