All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 10m15s
- 新增单行配置表 tb_asset_auto_renewal_config 与尝试记录表 tb_asset_auto_renewal_attempt(迁移 000229/000230) - 每日按上海自然日扫描,窗口内以同一资产钱包可用余额续购当前主套餐,资金/订单/套餐/审计同一事务闭合 - 唯一键保证每资产每日至多一次尝试,占位中断由后续扫描收敛,当日不重试 - 四类失败原因向客户与店铺各投递每日至多一条站内通知,并注册通知类型与个人客户白名单 - 续费成功后按条件经 Outbox 可靠投递复机,新增恢复扫描只查询回填,不使用即发即弃调用 - 配置读写仅超级管理员与平台账号,保存记录操作者、前后值快照并登记统一审计 - tasks 7.1–7.15 全部验证通过(本机隔离 PostgreSQL/Redis,零外部渠道调用)
227 lines
10 KiB
Go
227 lines
10 KiB
Go
package bootstrap
|
|
|
|
import (
|
|
assetAutoRenewalApp "github.com/break/junhong_cmp_fiber/internal/application/assetautorenewal"
|
|
cardObservationApp "github.com/break/junhong_cmp_fiber/internal/application/cardobservation"
|
|
carrierThresholdApp "github.com/break/junhong_cmp_fiber/internal/application/carrierthreshold"
|
|
walletapp "github.com/break/junhong_cmp_fiber/internal/application/wallet"
|
|
assetAutoRenewalInfra "github.com/break/junhong_cmp_fiber/internal/infrastructure/assetautorenewal"
|
|
auditInfra "github.com/break/junhong_cmp_fiber/internal/infrastructure/audit"
|
|
cardObservationInfra "github.com/break/junhong_cmp_fiber/internal/infrastructure/cardobservation"
|
|
carrierThresholdInfra "github.com/break/junhong_cmp_fiber/internal/infrastructure/carrierthreshold"
|
|
"github.com/break/junhong_cmp_fiber/internal/infrastructure/integrationlog"
|
|
"github.com/break/junhong_cmp_fiber/internal/infrastructure/messaging/outbox"
|
|
prioritypollingInfra "github.com/break/junhong_cmp_fiber/internal/infrastructure/prioritypolling"
|
|
walletinfra "github.com/break/junhong_cmp_fiber/internal/infrastructure/wallet"
|
|
assetAutoRenewalQuery "github.com/break/junhong_cmp_fiber/internal/query/assetautorenewal"
|
|
"github.com/break/junhong_cmp_fiber/internal/service/commission_calculation"
|
|
"github.com/break/junhong_cmp_fiber/internal/service/commission_stats"
|
|
deviceSvc "github.com/break/junhong_cmp_fiber/internal/service/device"
|
|
iotCardSvc "github.com/break/junhong_cmp_fiber/internal/service/iot_card"
|
|
orderSvc "github.com/break/junhong_cmp_fiber/internal/service/order"
|
|
packagepkg "github.com/break/junhong_cmp_fiber/internal/service/package"
|
|
pollingSvc "github.com/break/junhong_cmp_fiber/internal/service/polling"
|
|
purchaseValidationSvc "github.com/break/junhong_cmp_fiber/internal/service/purchase_validation"
|
|
"github.com/break/junhong_cmp_fiber/pkg/queue"
|
|
)
|
|
|
|
type workerServices struct {
|
|
CommissionCalculation *commission_calculation.Service
|
|
CommissionStats *commission_stats.Service
|
|
UsageService *packagepkg.UsageService
|
|
ActivationService *packagepkg.ActivationService
|
|
ResetService *packagepkg.ResetService
|
|
AlertService *pollingSvc.AlertService
|
|
CleanupService *pollingSvc.CleanupService
|
|
}
|
|
|
|
func initWorkerServices(stores *queue.WorkerStores, deps *WorkerDependencies) *queue.WorkerServices {
|
|
auditWriter := auditInfra.NewWriter(auditInfra.NewRegistry(), nil)
|
|
commissionStatsService := commission_stats.New(stores.ShopSeriesCommissionStats)
|
|
|
|
commissionCalculationService := commission_calculation.New(
|
|
deps.DB,
|
|
stores.CommissionRecord,
|
|
stores.Shop,
|
|
stores.ShopPackageAllocation,
|
|
stores.ShopSeriesAllocation,
|
|
stores.PackageSeries,
|
|
stores.IotCard,
|
|
stores.Device,
|
|
stores.AgentWallet,
|
|
stores.AgentWalletTransaction,
|
|
stores.Order,
|
|
stores.OrderItem,
|
|
stores.Package,
|
|
stores.ShopSeriesCommissionStats,
|
|
commissionStatsService,
|
|
deps.Logger,
|
|
)
|
|
commissionCalculationService.SetAuditWriter(auditWriter)
|
|
|
|
usageService := packagepkg.NewUsageService(
|
|
deps.DB,
|
|
deps.Redis,
|
|
stores.PackageUsage,
|
|
stores.PackageUsageDailyRecord,
|
|
stores.DeviceSimBinding,
|
|
deps.Logger,
|
|
)
|
|
|
|
activationService := packagepkg.NewActivationService(
|
|
deps.DB,
|
|
deps.Redis,
|
|
stores.PackageUsage,
|
|
stores.Package,
|
|
stores.PackageUsageDailyRecord,
|
|
deps.Logger,
|
|
)
|
|
|
|
resetService := packagepkg.NewResetService(
|
|
deps.DB,
|
|
deps.Redis,
|
|
stores.PackageUsage,
|
|
deps.Logger,
|
|
)
|
|
activationService.SetLifecycleAudit(auditWriter)
|
|
usageService.SetLifecycleAudit(auditWriter)
|
|
resetService.SetLifecycleAudit(auditWriter)
|
|
|
|
alertService := pollingSvc.NewAlertService(
|
|
stores.PollingAlertRule,
|
|
stores.PollingAlertHistory,
|
|
deps.Redis,
|
|
deps.Logger,
|
|
)
|
|
|
|
cleanupService := pollingSvc.NewCleanupService(
|
|
stores.DataCleanupConfig,
|
|
stores.DataCleanupLog,
|
|
deps.Logger,
|
|
)
|
|
cardObservationOutbox := outbox.NewRepository()
|
|
observationSeriesEvents := cardObservationInfra.NewSeriesEventWriter(cardObservationOutbox)
|
|
priorityEvents := prioritypollingInfra.NewPriorityEventWriter(cardObservationOutbox)
|
|
// 运营商通道流量阈值用例:达量判定嵌入流量观测事务,持锁判定注入停复机入口。
|
|
carrierThresholdService := carrierThresholdApp.NewService(deps.DB, cardObservationOutbox).SetLogger(deps.Logger)
|
|
cardObservationService := cardObservationApp.NewService(
|
|
deps.DB,
|
|
cardObservationInfra.NewEventWriter(cardObservationOutbox),
|
|
cardObservationInfra.NewCacheInvalidator(deps.Redis, deps.Logger),
|
|
)
|
|
iotCardAuditService := iotCardSvc.New(
|
|
deps.DB, stores.IotCard, stores.Shop, stores.AssetAllocationRecord,
|
|
stores.ShopPackageAllocation, stores.ShopSeriesAllocation, stores.PackageSeries,
|
|
deps.GatewayClient, deps.Logger,
|
|
)
|
|
iotCardAuditService.SetAccessAudit(auditWriter)
|
|
iotCardAuditService.SetPhoneAssetAssociationStore(stores.PhoneAssetAssociation)
|
|
cardObservationService.SetStateAuditWriter(iotCardAuditService)
|
|
// 运营商通道流量阈值达量判定嵌入流量观测事务:与卡流量事实同事务写周期锁与停机事件。
|
|
cardObservationService.SetChannelThresholdEvaluator(carrierThresholdService)
|
|
cardObservationIntegration := integrationlog.NewRepository(deps.DB)
|
|
cardObservationSeriesCoordinator := cardObservationInfra.NewSeriesCoordinator(deps.Redis)
|
|
cardObservationSeriesService := cardObservationApp.NewSeriesAttemptService(
|
|
cardObservationSeriesCoordinator,
|
|
cardObservationInfra.NewSeriesRunner(deps.DB, deps.GatewayClient, cardObservationService, cardObservationIntegration, auditWriter),
|
|
cardObservationInfra.NewSeriesAttemptLogger(cardObservationIntegration),
|
|
)
|
|
|
|
// 初始化订单服务,供超时取消和批量订购共同复用现有订单规则。
|
|
purchaseValidation := purchaseValidationSvc.New(deps.DB, stores.IotCard, stores.Device, stores.Package, stores.ShopPackageAllocation)
|
|
orderService := orderSvc.New(
|
|
deps.DB,
|
|
deps.Redis,
|
|
stores.Order,
|
|
stores.OrderItem,
|
|
stores.AgentWallet,
|
|
stores.AssetWallet,
|
|
nil, // paymentStore: 超时取消不需要
|
|
purchaseValidation,
|
|
stores.ShopPackageAllocation,
|
|
stores.ShopSeriesAllocation,
|
|
stores.IotCard,
|
|
stores.Device,
|
|
stores.PackageSeries,
|
|
stores.PackageUsage,
|
|
stores.Package,
|
|
nil, // wechatConfigService: 超时取消不需要
|
|
nil, // wechatPayment: 超时取消不需要
|
|
nil, // paymentLoader: 超时取消不需要
|
|
deps.QueueClient,
|
|
deps.Logger,
|
|
stores.AssetIdentifier,
|
|
stores.PersonalCustomer,
|
|
stores.PersonalCustomerPhone,
|
|
)
|
|
orderService.SetLifecycleAudit(auditWriter)
|
|
orderService.SetPaymentIntegrationLog(integrationlog.NewRepository(deps.DB))
|
|
walletOutbox := outbox.NewRepository()
|
|
walletDebitEvents := walletinfra.NewDebitEventWriter(walletOutbox, auditWriter)
|
|
orderService.SetAgentWalletReservationService(walletapp.NewReservationService(walletinfra.NewReservationEventWriter(walletOutbox, auditWriter), walletDebitEvents, nil))
|
|
orderService.SetAgentWalletDebitService(walletapp.NewDebitService(walletDebitEvents, nil))
|
|
orderService.SetObservationSeriesEventWriter(observationSeriesEvents)
|
|
orderService.SetPriorityEventWriter(priorityEvents)
|
|
|
|
// 创建停复机服务并注入回调:流量耗尽自动停机、套餐激活/重置/支付后自动复机
|
|
stopResumeService := iotCardSvc.NewStopResumeService(
|
|
deps.Redis,
|
|
stores.IotCard,
|
|
stores.PackageUsage,
|
|
stores.DeviceSimBinding,
|
|
deps.GatewayClient,
|
|
deps.Logger,
|
|
)
|
|
stopResumeService.SetObservationSeriesEventWriter(deps.DB, observationSeriesEvents)
|
|
stopResumeService.SetPriorityEventWriter(priorityEvents)
|
|
stopResumeService.SetUnifiedAudit(auditWriter, integrationlog.NewRepository(deps.DB))
|
|
// 持通道阈值锁的卡在周期内拒绝一切复机(自动、手动、保护期强制、机卡分离)。
|
|
stopResumeService.SetChannelThresholdLockGuard(carrierThresholdService)
|
|
// 停复机执行端口复用既有停复机服务作为唯一事实源:消费者与两个计划任务共用同一用例实例。
|
|
carrierThresholdService.SetCommander(carrierThresholdInfra.NewCardCommander(stopResumeService))
|
|
// 资产钱包自动续费:复机执行同样复用既有停复机单一事实源,通知与复机都走公共 Outbox。
|
|
assetAutoRenewalService := assetAutoRenewalApp.NewService(assetAutoRenewalApp.Dependencies{
|
|
DB: deps.DB, Redis: deps.Redis, Logger: deps.Logger,
|
|
Outbox: cardObservationOutbox, AuditWriter: auditWriter,
|
|
PurchaseValidation: purchaseValidation,
|
|
Candidates: assetAutoRenewalQuery.NewQuery(deps.DB),
|
|
Resume: assetAutoRenewalInfra.NewCardCommander(stopResumeService),
|
|
ObservationEvents: observationSeriesEvents,
|
|
PriorityEvents: priorityEvents,
|
|
})
|
|
activationService.SetObservationSeriesEventWriter(observationSeriesEvents)
|
|
activationService.SetPriorityEventWriter(priorityEvents)
|
|
usageService.SetStopResumeCallback(stopResumeService)
|
|
activationService.SetResumeCallback(stopResumeService)
|
|
orderService.SetResumeCallback(stopResumeService)
|
|
resetService.SetResumeCallback(stopResumeService)
|
|
deviceBatchAllocator := deviceSvc.New(
|
|
deps.DB, deps.Redis, stores.Device, stores.DeviceSimBinding, stores.IotCard, stores.Shop,
|
|
stores.AssetAllocationRecord, stores.ShopPackageAllocation, stores.ShopSeriesAllocation,
|
|
stores.PackageSeries, deps.GatewayClient, stores.AssetIdentifier, nil, nil,
|
|
)
|
|
deviceBatchAllocator.SetPhoneAssetAssociationStore(stores.PhoneAssetAssociation)
|
|
|
|
return &queue.WorkerServices{
|
|
PaymentAudit: auditWriter,
|
|
RechargeAudit: auditWriter,
|
|
CardObservation: cardObservationService,
|
|
CardObservationSeries: cardObservationSeriesService,
|
|
ObservationSeriesEvents: observationSeriesEvents,
|
|
PriorityEvents: priorityEvents,
|
|
CommissionCalculation: commissionCalculationService,
|
|
CommissionStats: commissionStatsService,
|
|
UsageService: usageService,
|
|
ActivationService: activationService,
|
|
ResetService: resetService,
|
|
AlertService: alertService,
|
|
CleanupService: cleanupService,
|
|
StopResumeService: stopResumeService,
|
|
CarrierThreshold: carrierThresholdService,
|
|
AssetAutoRenewal: assetAutoRenewalService,
|
|
OrderExpirer: orderService,
|
|
AssetPackageOrderCreator: orderService,
|
|
DeviceBatchAllocator: deviceBatchAllocator,
|
|
}
|
|
}
|