fix(channel-monitor-v2): 修复 CI golangci-lint 与 admin settings 契约测试

处理 rows.Close errcheck、gofmt、空 recover 分支 staticcheck,并同步
GET /api/v1/admin/settings 契约期望中的 mode 与 hide_throughput 字段。
This commit is contained in:
IanShaw027
2026-08-07 11:21:13 +08:00
parent 242f2b78c2
commit 4245cb41f4
6 changed files with 28 additions and 26 deletions
@@ -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
@@ -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
@@ -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))
}
@@ -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,
+3 -2
View File
@@ -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)
+1 -2
View File
@@ -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()