All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 9m35s
117 lines
4.1 KiB
Go
117 lines
4.1 KiB
Go
// Package approval 定义业务用例依赖的渠道无关审批接缝。
|
||
package approval
|
||
|
||
import (
|
||
"context"
|
||
stderrors "errors"
|
||
"time"
|
||
|
||
"gorm.io/gorm"
|
||
)
|
||
|
||
// 审批恢复适配器方法见文件末尾。
|
||
|
||
// PrepareRequest 是业务写入前执行审批渠道可用性检查的请求。
|
||
type PrepareRequest struct {
|
||
BusinessType string
|
||
SubmitterAccountID uint
|
||
CorrelationID string
|
||
}
|
||
|
||
// Preparation 是渠道可用性检查返回的短期、不透明准备凭据。
|
||
type Preparation struct {
|
||
provider string
|
||
businessType string
|
||
submitterAccountID uint
|
||
correlationID string
|
||
expiresAt time.Time
|
||
issuer *CreationService
|
||
providerContext ProviderPreparation
|
||
}
|
||
|
||
// CreateRequest 是业务事务内创建通用审批实例的请求。
|
||
type CreateRequest struct {
|
||
Preparation Preparation
|
||
BusinessType string
|
||
BusinessID uint
|
||
SubmitterAccountID uint
|
||
SubmitterSnapshot []byte
|
||
RequestSnapshot []byte
|
||
CorrelationID string
|
||
}
|
||
|
||
// Reference 是业务表保存的通用审批实例引用。
|
||
type Reference struct {
|
||
InstanceID uint
|
||
Status int
|
||
}
|
||
|
||
// Port 是退款、线下充值等业务用例唯一依赖的审批创建接缝。
|
||
// Prepare 必须在业务事务前确认 Adapter、场景和发起身份可用;CreateInTx 必须复核准备凭据并使用调用方事务写入审批事实。
|
||
type Port interface {
|
||
Prepare(ctx context.Context, request PrepareRequest) (Preparation, error)
|
||
CreateInTx(ctx context.Context, tx *gorm.DB, request CreateRequest) (Reference, error)
|
||
}
|
||
|
||
// ProviderPreparation 是渠道 Adapter 在事务前完成场景和发起身份检查后返回的内部准备结果。
|
||
// ChannelContext 只能包含后续写入渠道专属表所需的安全快照,不得包含密钥或访问令牌。
|
||
type ProviderPreparation struct {
|
||
Provider string
|
||
ChannelContext []byte
|
||
}
|
||
|
||
// ProviderPort 定义具体审批渠道对通用创建用例提供的防腐接缝。
|
||
type ProviderPort interface {
|
||
Prepare(ctx context.Context, request PrepareRequest) (ProviderPreparation, error)
|
||
CreateContextInTx(ctx context.Context, tx *gorm.DB, preparation ProviderPreparation, instanceID uint) error
|
||
}
|
||
|
||
// SubmissionRequestedEvent 是渠道提交 Worker 接收的通用申请事件。
|
||
type SubmissionRequestedEvent struct {
|
||
EventID string `json:"event_id"`
|
||
InstanceID uint `json:"instance_id"`
|
||
BusinessType string `json:"business_type"`
|
||
BusinessID uint `json:"business_id"`
|
||
SubmitterAccountID uint `json:"submitter_account_id"`
|
||
Provider string `json:"provider"`
|
||
CorrelationID string `json:"correlation_id"`
|
||
OccurredAt time.Time `json:"occurred_at"`
|
||
}
|
||
|
||
// SubmissionEventWriter 在调用方业务事务中追加渠道提交 Outbox。
|
||
type SubmissionEventWriter interface {
|
||
Append(ctx context.Context, tx *gorm.DB, event SubmissionRequestedEvent) error
|
||
}
|
||
|
||
type RecoveryPort interface {
|
||
EnqueueSubmittedSync(ctx context.Context, tx *gorm.DB, instanceID uint) error
|
||
EnqueueUnknownConfirm(ctx context.Context, tx *gorm.DB, instanceID uint) error
|
||
RecoverSubmissionEvent(ctx context.Context, tx *gorm.DB, instanceID uint) (bool, error)
|
||
}
|
||
|
||
// RecoveryAdapter 将恢复动作委托给基础设施实现。
|
||
type RecoveryAdapter struct {
|
||
SyncFunc func(context.Context, *gorm.DB, uint) error
|
||
ConfirmFunc func(context.Context, *gorm.DB, uint) error
|
||
RecoverFunc func(context.Context, *gorm.DB, uint) (bool, error)
|
||
}
|
||
|
||
func (a RecoveryAdapter) SyncSubmitted(ctx context.Context, tx *gorm.DB, id uint) error {
|
||
if a.SyncFunc == nil {
|
||
return stderrors.New("审批原实例同步接缝未配置")
|
||
}
|
||
return a.SyncFunc(ctx, tx, id)
|
||
}
|
||
func (a RecoveryAdapter) ConfirmUnknown(ctx context.Context, tx *gorm.DB, id uint) error {
|
||
if a.ConfirmFunc == nil {
|
||
return stderrors.New("审批结果确认接缝未配置")
|
||
}
|
||
return a.ConfirmFunc(ctx, tx, id)
|
||
}
|
||
func (a RecoveryAdapter) RecoverSubmissionEvent(ctx context.Context, tx *gorm.DB, id uint) (bool, error) {
|
||
if a.RecoverFunc == nil {
|
||
return false, stderrors.New("审批提交事件恢复接缝未配置")
|
||
}
|
||
return a.RecoverFunc(ctx, tx, id)
|
||
}
|