From 464b23c6bfa7c16b1f7412deafb935f94bed96fe Mon Sep 17 00:00:00 2001 From: Delicious233 <101502465+DeliciousBuding@users.noreply.github.com> Date: Wed, 19 Aug 2026 03:45:38 +0800 Subject: [PATCH 1/2] =?UTF-8?q?refactor(hub):=20service=20public=5Fstats?= =?UTF-8?q?=20=E5=BD=92=E7=BB=84=E5=AD=90=E5=8C=85=EF=BC=88#1761=20?= =?UTF-8?q?=E9=A6=96=E4=B8=AA=E5=A2=9E=E9=87=8F=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 将 internal/service/public_stats.go 提取为 internal/service/publicstats/ 子包, 沿用 agentevent/、deliveryoutbox/ 等既有子包模式(doc.go + 原文件改 package 子句)。 选择 public_stats 的原因:耦合分析显示它与扁平 service 包的双向依赖均为 0 —— 不引用任何兄弟文件符号,也未被任何兄弟文件引用;外部消费者仅 3 处 (app/wiring.go、handler/public.go、handler/public_test.go),无生命周期钩子、 无接口注入、router 层零引用,是最安全的首个增量。 类型与方法签名保持不变(PublicStatsService.GetStats),纯归组无行为变更。 验证:go build ./... && go vet ./... && go test ./internal/service/... -short 全绿。 Co-authored-by: Cursor --- hub-server/internal/app/wiring.go | 3 ++- hub-server/internal/handler/public.go | 6 +++--- hub-server/internal/handler/public_test.go | 4 ++-- hub-server/internal/service/publicstats/doc.go | 9 +++++++++ .../internal/service/{ => publicstats}/public_stats.go | 2 +- 5 files changed, 17 insertions(+), 7 deletions(-) create mode 100644 hub-server/internal/service/publicstats/doc.go rename hub-server/internal/service/{ => publicstats}/public_stats.go (98%) diff --git a/hub-server/internal/app/wiring.go b/hub-server/internal/app/wiring.go index d415e362e..abb26b2c7 100644 --- a/hub-server/internal/app/wiring.go +++ b/hub-server/internal/app/wiring.go @@ -26,6 +26,7 @@ import ( "github.com/agenthub/hub-server/internal/service/message" "github.com/agenthub/hub-server/internal/service/messagereaction" "github.com/agenthub/hub-server/internal/service/oidc" + "github.com/agenthub/hub-server/internal/service/publicstats" "github.com/agenthub/hub-server/internal/service/session" "github.com/agenthub/hub-server/internal/service/workspace" ) @@ -244,7 +245,7 @@ func (a *App) initHandlers(_ context.Context) error { a.AttachmentHandler = handler.NewAttachmentHandler(a.AttachmentService) a.NotificationHandler = handler.NewNotificationHandler(a.NotificationService) a.HealthHandler = handler.NewHealthHandler(a.DB, a.CacheClient, &a.Config.DB, a.startTime, a.Version) - pubStatsSvc := service.NewPublicStatsService(a.DB) + pubStatsSvc := publicstats.NewPublicStatsService(a.DB) a.PublicHandler = handler.NewPublicHandler(pubStatsSvc, a.startTime) return nil diff --git a/hub-server/internal/handler/public.go b/hub-server/internal/handler/public.go index 9947a3def..67efeb003 100644 --- a/hub-server/internal/handler/public.go +++ b/hub-server/internal/handler/public.go @@ -6,7 +6,7 @@ import ( "github.com/gin-gonic/gin" - "github.com/agenthub/hub-server/internal/service" + "github.com/agenthub/hub-server/internal/service/publicstats" ) // PublicStats is the response body for GET /api/public/stats. @@ -20,13 +20,13 @@ type PublicStats struct { // PublicHandler serves unauthenticated public endpoints for the website. type PublicHandler struct { - statsSvc *service.PublicStatsService + statsSvc *publicstats.PublicStatsService startTime time.Time } // NewPublicHandler creates a PublicHandler. // startTime should be the moment App.Run was called. -func NewPublicHandler(statsSvc *service.PublicStatsService, startTime time.Time) *PublicHandler { +func NewPublicHandler(statsSvc *publicstats.PublicStatsService, startTime time.Time) *PublicHandler { return &PublicHandler{statsSvc: statsSvc, startTime: startTime} } diff --git a/hub-server/internal/handler/public_test.go b/hub-server/internal/handler/public_test.go index 08a012dfe..2300db2c3 100644 --- a/hub-server/internal/handler/public_test.go +++ b/hub-server/internal/handler/public_test.go @@ -16,7 +16,7 @@ import ( "github.com/agenthub/hub-server/internal/handler" "github.com/agenthub/hub-server/internal/model" - "github.com/agenthub/hub-server/internal/service" + "github.com/agenthub/hub-server/internal/service/publicstats" ) func TestPublicStatsBucketsCountsAndUptime(t *testing.T) { @@ -43,7 +43,7 @@ func TestPublicStatsBucketsCountsAndUptime(t *testing.T) { w := httptest.NewRecorder() c, _ := gin.CreateTestContext(w) c.Request = httptest.NewRequest(http.MethodGet, "/api/public/stats", nil) - statsSvc := service.NewPublicStatsService(db) + statsSvc := publicstats.NewPublicStatsService(db) h := handler.NewPublicHandler(statsSvc, time.Now().Add(-25*time.Hour-13*time.Minute)) h.Stats(c) diff --git a/hub-server/internal/service/publicstats/doc.go b/hub-server/internal/service/publicstats/doc.go new file mode 100644 index 000000000..3b00cf63b --- /dev/null +++ b/hub-server/internal/service/publicstats/doc.go @@ -0,0 +1,9 @@ +// Package publicstats holds the public-facing statistics service for Hub. +// +// PublicStatsService serves aggregate counts (users, agents, online agents, +// messages) to the public stats endpoint. It neither uses nor is used by any +// sibling of the flat service package, so it is the first low-coupling domain +// grouped into a subpackage. +// +// See #1761. +package publicstats diff --git a/hub-server/internal/service/public_stats.go b/hub-server/internal/service/publicstats/public_stats.go similarity index 98% rename from hub-server/internal/service/public_stats.go rename to hub-server/internal/service/publicstats/public_stats.go index dfbd26ba2..236485e97 100644 --- a/hub-server/internal/service/public_stats.go +++ b/hub-server/internal/service/publicstats/public_stats.go @@ -1,4 +1,4 @@ -package service +package publicstats import ( "gorm.io/gorm" From 71e19e2be9a55e1a44c924d21514285744448278 Mon Sep 17 00:00:00 2001 From: Delicious233 <101502465+DeliciousBuding@users.noreply.github.com> Date: Wed, 19 Aug 2026 04:17:16 +0800 Subject: [PATCH 2/2] =?UTF-8?q?fix(hub):=20integration=20setup=20=E8=A1=A5?= =?UTF-8?q?=20publicstats=20=E5=AD=90=E5=8C=85=E5=BC=95=E7=94=A8=EF=BC=88?= =?UTF-8?q?=E4=BF=AE=E5=A4=8D=20#1768=20=E9=9B=86=E6=88=90=E7=BC=96?= =?UTF-8?q?=E8=AF=91=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit public_stats 归组为 service/publicstats 子包后,tests/integration/setup_test.go 仍引用旧的 service.NewPublicStatsService,导致 Backend integration 编译失败。 更新为 publicstats.NewPublicStatsService 并按字母序补 import。 验证:go test -c -tags integration 编译通过;go build/vet ./... 全绿; go test ./internal/service/... -short 全绿。 Co-authored-by: Cursor --- hub-server/tests/integration/setup_test.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/hub-server/tests/integration/setup_test.go b/hub-server/tests/integration/setup_test.go index 7bd93baf5..8bf380ed4 100644 --- a/hub-server/tests/integration/setup_test.go +++ b/hub-server/tests/integration/setup_test.go @@ -39,6 +39,7 @@ import ( "github.com/agenthub/hub-server/internal/service/message" "github.com/agenthub/hub-server/internal/service/messagereaction" "github.com/agenthub/hub-server/internal/service/oidc" + "github.com/agenthub/hub-server/internal/service/publicstats" "github.com/agenthub/hub-server/internal/service/session" "github.com/agenthub/hub-server/internal/testkit" "github.com/agenthub/hub-server/internal/ws" @@ -144,7 +145,7 @@ func TestMain(m *testing.M) { notificationService := service.NewNotificationService(db, mgr) notificationHandler := handler.NewNotificationHandler(notificationService) healthHandler := handler.NewHealthHandler(db, cacheClient, &cfg.DB, time.Now(), "test") - publicHandler := handler.NewPublicHandler(service.NewPublicStatsService(db), time.Now()) + publicHandler := handler.NewPublicHandler(publicstats.NewPublicStatsService(db), time.Now()) // Phase 1-7 handlers // config.yaml ships production-empty TokenDance ID values (client_id "",