From 4245cb41f4d6a78c99ed363c9bad0ee488d1bc5d Mon Sep 17 00:00:00 2001 From: IanShaw027 Date: Fri, 7 Aug 2026 11:21:13 +0800 Subject: [PATCH] =?UTF-8?q?fix(channel-monitor-v2):=20=E4=BF=AE=E5=A4=8D?= =?UTF-8?q?=20CI=20golangci-lint=20=E4=B8=8E=20admin=20settings=20?= =?UTF-8?q?=E5=A5=91=E7=BA=A6=E6=B5=8B=E8=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 处理 rows.Close errcheck、gofmt、空 recover 分支 staticcheck,并同步 GET /api/v1/admin/settings 契约期望中的 mode 与 hide_throughput 字段。 --- .../channel_monitor_v2_aggregation.go | 18 +++++++-------- .../repository/channel_monitor_v2_repo.go | 22 +++++++++---------- .../channel_monitor_v2_repo_test.go | 2 -- backend/internal/server/api_contract_test.go | 4 ++++ backend/internal/server/routes/admin.go | 5 +++-- backend/internal/service/setting_service.go | 3 +-- 6 files changed, 28 insertions(+), 26 deletions(-) diff --git a/backend/internal/repository/channel_monitor_v2_aggregation.go b/backend/internal/repository/channel_monitor_v2_aggregation.go index 766382a8dd..e7cd34dad7 100644 --- a/backend/internal/repository/channel_monitor_v2_aggregation.go +++ b/backend/internal/repository/channel_monitor_v2_aggregation.go @@ -19,15 +19,15 @@ const channelMonitorV2ModelSQL = `COALESCE(NULLIF(TRIM(ul.requested_model), ''), // Backfill may still write short-lived 1m rows for old windows so rollups can be // built; prune at end of each recompute drops them past their TTL while rollups remain. const ( - channelMonitorV2RetentionUser1m = 3 * 24 * time.Hour - channelMonitorV2RetentionMetrics1m = 7 * 24 * time.Hour - channelMonitorV2RetentionError1m = 7 * 24 * time.Hour - channelMonitorV2RetentionHistogram1m = 7 * 24 * time.Hour - channelMonitorV2RetentionRollup5m = 7 * 24 * time.Hour // bucket_seconds=300 - channelMonitorV2RetentionRollup1h = 30 * 24 * time.Hour // 3600 - channelMonitorV2RetentionRollup12h = 45 * 24 * time.Hour // 43200 - channelMonitorV2RetentionRollup1d = 90 * 24 * time.Hour // 86400 - channelMonitorV2RetentionMax = channelMonitorV2RetentionRollup1d + channelMonitorV2RetentionUser1m = 3 * 24 * time.Hour + channelMonitorV2RetentionMetrics1m = 7 * 24 * time.Hour + channelMonitorV2RetentionError1m = 7 * 24 * time.Hour + channelMonitorV2RetentionHistogram1m = 7 * 24 * time.Hour + channelMonitorV2RetentionRollup5m = 7 * 24 * time.Hour // bucket_seconds=300 + channelMonitorV2RetentionRollup1h = 30 * 24 * time.Hour // 3600 + channelMonitorV2RetentionRollup12h = 45 * 24 * time.Hour // 43200 + channelMonitorV2RetentionRollup1d = 90 * 24 * time.Hour // 86400 + channelMonitorV2RetentionMax = channelMonitorV2RetentionRollup1d ) // channelMonitorV2MaxRetention is the longest stored window (1d rollup). Used to diff --git a/backend/internal/repository/channel_monitor_v2_repo.go b/backend/internal/repository/channel_monitor_v2_repo.go index 5e9d5b5cd8..0f13f1a35c 100644 --- a/backend/internal/repository/channel_monitor_v2_repo.go +++ b/backend/internal/repository/channel_monitor_v2_repo.go @@ -134,7 +134,7 @@ func (r *channelMonitorV2Repository) GetDimensions(ctx context.Context, filter s if err != nil { return nil, err } - defer rows.Close() + defer func() { _ = rows.Close() }() platformCounts := map[string]int64{} type modelValue struct { platform string @@ -602,7 +602,7 @@ func (r *channelMonitorV2Repository) listActiveGroupIDs(ctx context.Context) ([] if err != nil { return nil, err } - defer rows.Close() + defer func() { _ = rows.Close() }() ids := []int64{} for rows.Next() { var id int64 @@ -623,7 +623,7 @@ func (r *channelMonitorV2Repository) loadChannelMonitorV2GroupInfo(ctx context.C if err != nil { return nil, err } - defer rows.Close() + defer func() { _ = rows.Close() }() for rows.Next() { var id int64 var name, platform string @@ -646,7 +646,7 @@ func (r *channelMonitorV2Repository) GetErrors(ctx context.Context, filter servi if err != nil { return nil, err } - defer rows.Close() + defer func() { _ = rows.Close() }() counts := map[string]int64{} var total int64 ignoredSet := service.ChannelMonitorV2IgnoredCategorySet(cfg) @@ -760,7 +760,7 @@ func (r *channelMonitorV2Repository) loadErrorDetails(ctx context.Context, filte if err != nil { return nil, err } - defer rows.Close() + defer func() { _ = rows.Close() }() out := map[string][]service.ChannelMonitorV2ErrorDetail{} for rows.Next() { var platform, model, errorType, owner, source, message string @@ -830,7 +830,7 @@ func (r *channelMonitorV2Repository) GetUsers(ctx context.Context, filter servic if err != nil { return nil, err } - defer rows.Close() + defer func() { _ = rows.Close() }() type userMeta struct{ email, username string } meta := map[int64]userMeta{} accs := map[int64]*metricAccumulator{} @@ -923,7 +923,7 @@ func (r *channelMonitorV2Repository) loadFacts(ctx context.Context, filter servi if err != nil { return nil, err } - defer rows.Close() + defer func() { _ = rows.Close() }() facts := []channelMonitorV2Fact{} for rows.Next() { var bucket time.Time @@ -964,7 +964,7 @@ func (r *channelMonitorV2Repository) loadHistograms(ctx context.Context, filter if err != nil { return nil, err } - defer rows.Close() + defer func() { _ = rows.Close() }() out := []channelMonitorV2Histogram{} for rows.Next() { var bucket time.Time @@ -1379,7 +1379,7 @@ func (r *channelMonitorV2Repository) loadIgnoredErrorCounts( if err != nil { return byBucket, 0, err } - defer rows.Close() + defer func() { _ = rows.Close() }() for rows.Next() { var bucket time.Time var platform, model string @@ -1422,7 +1422,7 @@ func (r *channelMonitorV2Repository) loadIgnoredErrorCountsByPlatformModel( if err != nil { return byPM, 0, err } - defer rows.Close() + defer func() { _ = rows.Close() }() for rows.Next() { var platform, model string var count int64 @@ -1475,7 +1475,7 @@ func (r *channelMonitorV2Repository) loadIgnoredErrorCountsByMatrixKey( if err != nil { return byDimBucket, byDim, err } - defer rows.Close() + defer func() { _ = rows.Close() }() for rows.Next() { var bucket time.Time var platform, model string diff --git a/backend/internal/repository/channel_monitor_v2_repo_test.go b/backend/internal/repository/channel_monitor_v2_repo_test.go index 32523f527e..81e2e90fb2 100644 --- a/backend/internal/repository/channel_monitor_v2_repo_test.go +++ b/backend/internal/repository/channel_monitor_v2_repo_test.go @@ -261,5 +261,3 @@ func TestChannelMonitorV2CatalogFilterClearsMultiSelectDimensions(t *testing.T) require.Equal(t, []int64{3, 4}, configuredChannelMonitorV2GroupIDs(catalog, cfg)) require.Equal(t, []int64{3}, configuredChannelMonitorV2GroupIDs(filter, cfg)) } - - diff --git a/backend/internal/server/api_contract_test.go b/backend/internal/server/api_contract_test.go index 9a017f5620..243e8b2418 100644 --- a/backend/internal/server/api_contract_test.go +++ b/backend/internal/server/api_contract_test.go @@ -976,6 +976,8 @@ func TestAPIContracts(t *testing.T) { "balance_low_notify_recharge_url": "", "account_quota_notify_emails": [], "channel_monitor_enabled": true, + "channel_monitor_mode": "v2", + "channel_monitor_hide_throughput": false, "channel_monitor_default_interval_seconds": 60, "available_channels_enabled": false, "model_plaza_enabled": false, @@ -1279,6 +1281,8 @@ func TestAPIContracts(t *testing.T) { "balance_low_notify_recharge_url": "", "account_quota_notify_emails": [], "channel_monitor_enabled": true, + "channel_monitor_mode": "v2", + "channel_monitor_hide_throughput": false, "channel_monitor_default_interval_seconds": 60, "available_channels_enabled": false, "model_plaza_enabled": false, diff --git a/backend/internal/server/routes/admin.go b/backend/internal/server/routes/admin.go index b174abbf1f..4afd4c3032 100644 --- a/backend/internal/server/routes/admin.go +++ b/backend/internal/server/routes/admin.go @@ -1,10 +1,11 @@ // Package routes provides HTTP route registration and handlers. package routes + import ( "github.com/Wei-Shaw/sub2api/internal/handler" + "github.com/Wei-Shaw/sub2api/internal/pkg/response" "github.com/Wei-Shaw/sub2api/internal/server/middleware" "github.com/Wei-Shaw/sub2api/internal/service" - "github.com/Wei-Shaw/sub2api/internal/pkg/response" "github.com/gin-gonic/gin" ) @@ -107,7 +108,7 @@ func RegisterAdminRoutes( // 渠道监控 registerChannelMonitorRoutes(admin, h, settingService) - registerChannelMonitorV2Routes(admin, h, settingService) + registerChannelMonitorV2Routes(admin, h, settingService) // 风控中心 registerContentModerationRoutes(admin, h) diff --git a/backend/internal/service/setting_service.go b/backend/internal/service/setting_service.go index 9319972717..5d8baf4c10 100644 --- a/backend/internal/service/setting_service.go +++ b/backend/internal/service/setting_service.go @@ -306,7 +306,6 @@ func (s *SettingService) SetOnUpdateCallback(callback func()) { s.onUpdate = callback } - // SubscribeChannelMonitorRuntime registers a listener that is invoked after // settings are successfully persisted (and process caches refreshed). // Used by ChannelMonitorRunner / ChannelMonitorV2Aggregator for immediate @@ -345,7 +344,7 @@ func (s *SettingService) notifyChannelMonitorRuntimeListeners() { func(fn func()) { defer func() { if recovered := recover(); recovered != nil { - // keep settings path healthy + _ = recovered // keep settings path healthy } }() fn()