Files
backend/pkg/database/manager.go
lan f2b02682c2
Some checks failed
Build / build-docker (push) Has been cancelled
Build / build (push) Has been cancelled
feat(yggdrasil): 实现好友系统与 profiles 查询接口
按 MinecraftServices 文档实现好友系四组接口与 profiles 服务:

好友系统(/api/yggdrasil/minecraftservices/*)
- Friends(1.3):列表查询、ADD/REMOVE 操作(发请求/接受/拒绝/撤回/删除)
  - 状态枚举+单向记录模型,接受请求时合并两方向避免好友列表重复
- Player Attributes(1.2):friendsPreferences / 脏词过滤 / 聊天偏好读写
  - Upsert 用 map 显式写字段规避 gorm 对带 default 零值布尔字段的忽略
- Presence(1.1):Redis key+TTL 上报与好友在线状态批量查询
- Blocklist(1.6):屏蔽列表查询(含 120s Redis 缓存),Block/Unblock 内部方法

Profiles 服务
- getManyByName(2.1):POST /api/profiles/minecraft,返回 [{id,name}]
  - toLowerCase 规范化、去重、空名过滤、maxBatch=10 超限拒绝
- getByName(2.2):GET /api/users/profiles/minecraft/:name,返回 {id,name},未找到返回 404

路由与基础设施
- 路由按官方 host 前缀一一转发
  - api.mojang.com/* -> /api/yggdrasil/api/*
  - api.minecraftservices.com/* -> /api/yggdrasil/minecraftservices/*
- 新增 Friend/PlayerAttributes 模型与 AutoMigrate 注册
- 新增 FriendsService 与 Container 装配
- 抽 extractBearerToken helper,统一 MinecraftServices 错误响应

修复
- texture_service: ToggleFavorite 在 db 为 nil 时降级非事务执行
  修复 TestTextureServiceImpl_ToggleFavorite 空指针 panic
- texture_service_test: UploadTexture 用例改用真实 SHA-256 命中 mock
  修复 4 个子用例因文件大小/Hash 不匹配的失败
- profile_repository: GetByNames/FindByName 改 LOWER() 大小写不敏感
  与客户端 toLowerCase 规范化对齐

测试
- 好友模型、ADD/REMOVE/接受、属性、屏蔽、Bearer 解析单测全绿
- profiles 查询规范化、去重、超限、大小写不敏感单测全绿
- go build ./... && go test ./... 全部通过
2026-07-09 20:44:41 +08:00

64 lines
1.7 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package database
import (
"fmt"
"carrotskin/internal/model"
"go.uber.org/zap"
"gorm.io/gorm"
)
// 本文件原包含基于 sync.Once 的全局单例Init/GetDB/MustGetDB/GetDBWrapper
//
// 在 DI 迁移阶段4全局单例已被移除。数据库连接由 fx.Provide 构造
// (见 internal/app/infra_module.go 的 provideDatabase通过构造函数参数
// 注入 *database.DB 与 *gorm.DB 到各消费者。
//
// 数据库构造逻辑见 postgres.go 的 New()。
// AutoMigrateWithDB 使用指定的 *gorm.DB 执行表结构迁移(供 DI 使用)。
// 注意表的创建顺序:先创建被引用的表,再创建引用表。
func AutoMigrateWithDB(db *gorm.DB, logger *zap.Logger) error {
logger.Info("开始执行数据库迁移...")
tables := []interface{}{
// 用户相关表(先创建,因为其他表可能引用它)
&model.User{},
&model.UserPointLog{},
&model.UserLoginLog{},
// 档案相关表
&model.Profile{},
// 材质相关表
&model.Texture{},
&model.UserTextureFavorite{},
&model.TextureDownloadLog{},
// 认证相关表
&model.Client{}, // Client表用于管理Token版本
// Yggdrasil相关表在User之后创建因为它引用User
&model.Yggdrasil{},
// 好友系统相关表(好友关系、玩家偏好属性)
&model.Friend{},
&model.PlayerAttributes{},
// 审计日志表
&model.AuditLog{},
// Casbin权限规则表
&model.CasbinRule{},
}
if err := db.AutoMigrate(tables...); err != nil {
logger.Error("数据库迁移失败", zap.Error(err))
return fmt.Errorf("数据库迁移失败: %w", err)
}
logger.Info("数据库迁移完成")
return nil
}