feat: add hook system, QR code login, and layered cache
All checks were successful
Build Backend / build (push) Successful in 5m54s
Build Backend / build-docker (push) Successful in 4m7s

- Implement extensible hook system for content moderation with
  builtin and AI-powered moderation hooks
- Add QR code login feature with SSE for real-time status updates
  and scan/confirm/cancel workflow
- Introduce layered cache with local LRU + Redis backend for
  improved read performance
- Refactor post and comment services to use hook-based moderation
  instead of direct AI service calls
- Add local cache configuration options (size, buckets, ttl)
This commit is contained in:
lafay
2026-03-20 12:23:28 +08:00
parent bdfcbdadea
commit 98f0c9f2b6
23 changed files with 2726 additions and 76 deletions

View File

@@ -8,7 +8,9 @@ import (
"carrot_bbs/internal/grpc/runner"
"carrot_bbs/internal/pkg/email"
"carrot_bbs/internal/pkg/gorse"
"carrot_bbs/internal/pkg/hook"
"carrot_bbs/internal/pkg/openai"
"carrot_bbs/internal/pkg/redis"
"carrot_bbs/internal/pkg/s3"
"carrot_bbs/internal/pkg/sse"
"carrot_bbs/internal/repository"
@@ -50,6 +52,7 @@ var ServiceSet = wire.NewSet(
ProvideAdminCommentService,
ProvideAdminGroupService,
ProvideAdminDashboardService,
ProvideQRCodeLoginService,
// 日志服务
ProvideAsyncLogManager,
@@ -100,7 +103,6 @@ func ProvideSystemMessageService(
return service.NewSystemMessageService(notifyRepo, pushService, userRepo, postRepo, cacheBackend)
}
// ProvidePostService 提供帖子服务
func ProvidePostService(
postRepo *repository.PostRepository,
systemMessageService service.SystemMessageService,
@@ -108,11 +110,11 @@ func ProvidePostService(
postAIService *service.PostAIService,
cacheBackend cache.Cache,
txManager repository.TransactionManager,
hookManager *hook.Manager,
) service.PostService {
return service.NewPostService(postRepo, systemMessageService, gorseClient, postAIService, cacheBackend, txManager)
return service.NewPostService(postRepo, systemMessageService, gorseClient, postAIService, cacheBackend, txManager, hookManager)
}
// ProvideCommentService 提供评论服务
func ProvideCommentService(
commentRepo *repository.CommentRepository,
postRepo *repository.PostRepository,
@@ -120,8 +122,9 @@ func ProvideCommentService(
gorseClient gorse.Client,
postAIService *service.PostAIService,
cacheBackend cache.Cache,
hookManager *hook.Manager,
) *service.CommentService {
return service.NewCommentService(commentRepo, postRepo, systemMessageService, gorseClient, postAIService, cacheBackend)
return service.NewCommentService(commentRepo, postRepo, systemMessageService, gorseClient, postAIService, cacheBackend, hookManager)
}
// ProvideMessageService 提供消息服务
@@ -343,6 +346,18 @@ func ProvideLogService(
return service.NewLogService(operationLogService, loginLogService, dataChangeLogService)
}
// ProvideQRCodeLoginService 提供二维码登录服务
func ProvideQRCodeLoginService(
redisClient *redis.Client,
sseHub *sse.Hub,
jwtService *service.JWTService,
userService service.UserService,
activityService service.UserActivityService,
logService *service.LogService,
) *service.QRCodeLoginService {
return service.NewQRCodeLoginService(redisClient, sseHub, jwtService, userService, activityService, logService)
}
// parseDuration 解析时长字符串
func parseDuration(s string) (time.Duration, error) {
return time.ParseDuration(s)