From 86e126c42b33fbe72030d6c62a3a2422fec226f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=AD=E5=B7=9E=E6=98=8E=E5=A9=B3=E7=A7=91=E6=8A=80?= Date: Sat, 4 Jul 2026 11:46:59 +0800 Subject: [PATCH] =?UTF-8?q?release:=20v1.2.0=20=E7=89=88=E6=9C=AC=E5=8F=B7?= =?UTF-8?q?=E6=8F=90=E5=8D=87=20+=20=E8=84=9A=E6=89=8B=E6=9E=B6=E5=AF=B9?= =?UTF-8?q?=E9=BD=90=20+=20=E6=96=87=E6=A1=A3=E6=A0=B8=E9=AA=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 版本号 1.1.1 → 1.2.0:app.go Version 常量;脚手架 GoMod 模板经 xlgo.Version 自动跟随;GUIDE 文档版本同步 - CHANGELOG/README 新增 v1.2.0 破坏性版本条目(包级全局 atomic.Pointer 治理、jwt.DefaultJWT 删除、FindWhereOrdered 签名变更、response 去 omitempty、cache.ErrRedisNotReady、config.Clone 深拷贝等) - 脚手架对齐:RepositoryMake 模板 FindByName 改用 FindOne(走 readConn 读写分离,避免 M-35 GetDB 不路由 footgun) - 文档核验修复(README/GUIDE 逐行对照源码 6595e94): - README DB 示例 users := ...Find(&users) 自引用声明编译错误 - GUIDE xlgo.StartServer(engine,8080) 不存在 → engine.Run(":8080") - GUIDE app.token_expire 死键(v1.1.0 已移除 AppConfig.TokenExpire) - GUIDE jwt.expire: 86400 类型错(time.Duration 需字符串 "24h") - GUIDE storage.Init(&cfg.Storage) 吞错误 → 显式 err 处理 - GUIDE 登录示例 token,_:=jwt.GenerateToken 吞错误 + time.Duration(cfg.JWT.Expire)*time.Second 双重转换 - GUIDE 验证规则表补 phone_strict / username - .gitignore 忽略 8 个评审报告文件(仅本地保留,不入库;已从未推送提交中 filter-branch 清除) Co-Authored-By: Claude Opus 4.8 (1M context) --- .gitignore | 8 ++++++++ CHANGELOG.md | 11 ++++++++--- GUIDE.md | 24 ++++++++++++++++-------- README.md | 19 ++++++++++++++++++- app.go | 2 +- cmd/xlgo/commands.go | 2 +- cmd/xlgo/templates.go | 13 ++++++------- 7 files changed, 58 insertions(+), 21 deletions(-) diff --git a/.gitignore b/.gitignore index 3613b7a..aab50ff 100644 --- a/.gitignore +++ b/.gitignore @@ -7,3 +7,11 @@ gitHub_release_*.md # 构建产物 *.exe bin/ +claude_check_report_framework.md +claude_check_report_module.md +cross_review_assessment.md +deepseek_check_report_framework.md +deepseek_check_report_module.md +glm_check_report_framework.md +glm_check_report_modelue.md +last_report.md diff --git a/CHANGELOG.md b/CHANGELOG.md index 869cc9d..c2a2aa4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,8 +16,12 @@ xlgo 框架更新日志。本文档遵循 [Keep a Changelog](https://keepachange ## [Unreleased] -> 框架整体评估后的结构性修复,包含 2 CRITICAL + 12 HIGH + 6 MEDIUM 问题的修复。 -> 项目处于初级阶段,无下游用户,放心引入破坏性变更。 +_暂无未发布变更。_ + +## [1.2.0] - 2026-07-04 + +> 框架整体评估后的结构性修复:4 轮对抗性评审(deepseek / GLM / Claude / 终审)收口的全部 CRITICAL/HIGH/MEDIUM 问题 + 主线A 包级可变全局并发治理统一。 +> 项目处于初级阶段,无下游用户,放心引入破坏性变更。`go vet` + `go build` + `go test -race ./...` 全绿。 ### Breaking ⚠️ @@ -964,7 +968,8 @@ v1.0.2 引入可插拔方言注册表后,`gorm.io/driver/postgres` 成为直 - 基础框架功能 - 完整示例代码 -[Unreleased]: https://github.com/EthanCodeCraft/xlgo-core/compare/v1.1.1...HEAD +[Unreleased]: https://github.com/EthanCodeCraft/xlgo-core/compare/v1.2.0...HEAD +[1.2.0]: https://github.com/EthanCodeCraft/xlgo-core/compare/v1.1.1...v1.2.0 [1.1.1]: https://github.com/EthanCodeCraft/xlgo-core/releases/tag/v1.1.1 [1.1.0]: https://github.com/EthanCodeCraft/xlgo-core/releases/tag/v1.1.0 [1.0.4]: https://github.com/EthanCodeCraft/xlgo-core/releases/tag/v1.0.4 diff --git a/GUIDE.md b/GUIDE.md index 3e6d75a..94c68a6 100644 --- a/GUIDE.md +++ b/GUIDE.md @@ -111,7 +111,6 @@ app: env: "dev" # dev/test/prod debug: true base_url: "http://localhost:8080" - token_expire: 86400 # Token过期时间(秒) server: port: 8080 @@ -134,7 +133,7 @@ redis: jwt: secret: your_jwt_secret_key - expire: 86400 + expire: "24h" # time.Duration,如 "24h"/"30m" log: dir: ./logs @@ -701,7 +700,9 @@ if !ok { | `max=20` | 最大长度 | | `email` | 邮箱格式 | | `phone` | 手机号格式 | +| `phone_strict` | 手机号严格校验(验证运营商号段) | | `password` | 密码强度(8-72 字节,需含大写+小写+数字) | +| `username` | 字母开头,3-20 位字母/数字/下划线 | | `url` | URL 格式 | | `ip` | IP 地址格式 | @@ -1070,7 +1071,8 @@ router.RegisterVersion(router.NewVersion("v1", "/api/v1")) // 应用路由 router.Apply() -xlgo.StartServer(engine, 8080) +// 启动服务(如需优雅关闭与生命周期管理,改用 app := xlgo.New(...); app.Run()) +engine.Run(":8080") ``` #### 8.4.7 默认路由 @@ -1199,7 +1201,9 @@ storage: import "github.com/EthanCodeCraft/xlgo-core/storage" // 初始化 -storage.Init(&cfg.Storage) +if err := storage.Init(&cfg.Storage); err != nil { + return err +} // 上传文件(从请求中获取) file, _ := c.FormFile("file") @@ -1799,13 +1803,17 @@ func Login(c *gin.Context) { } // 生成Token - token, _ := jwt.GenerateToken(user.ID, user.Username, "admin", "admin") + token, err := jwt.GenerateToken(user.ID, user.Username, "admin", "admin") + if err != nil { + response.FailWithError(c, response.ErrServerError) + return + } // 缓存用户信息 cache.GetCache().Set(c.Request.Context(), cache.KSession(token), user, - time.Duration(cfg.JWT.Expire)*time.Second) + cfg.JWT.Expire) response.Success(c, gin.H{ "token": token, @@ -1817,5 +1825,5 @@ func Login(c *gin.Context) { --- -_文档版本: v1.1.1_ -_最后更新: 2026-07-03_ +_文档版本: v1.2.0_ +_最后更新: 2026-07-04_ diff --git a/README.md b/README.md index e1757c6..dc6765a 100644 --- a/README.md +++ b/README.md @@ -246,7 +246,8 @@ database.InitDBWithReplicas(cfg, []string{ }) // 读操作自动路由到从库 -users := database.GetReadDB().Find(&users) +var users []model.User +database.GetReadDB().Find(&users) // 强制使用主库 ctx := database.UseMaster(context.Background()) @@ -819,6 +820,22 @@ docker run -d -p 8080:8080 xlgo-app:latest > 完整变更历史见 [CHANGELOG.md](./CHANGELOG.md)。 +### v1.2.0 (2026-07-04) + +> **破坏性版本**:4 轮对抗性评审(deepseek / GLM / Claude / 终审)收口的全部 CRITICAL/HIGH/MEDIUM 修复 + 主线A 包级可变全局并发治理统一。`go vet` + `go build` + `go test -race ./...` 全绿。完整变更见 [CHANGELOG.md](./CHANGELOG.md)。 + +主要破坏性变更(升级前必读): + +- **包级可变全局一律 `atomic.Pointer`**(主线A):`database.DefaultRedis`/`database.DefaultManager`/`storage.DefaultStorage`/`validation.Validator` 由裸指针改为 `atomic.Pointer[T]`。直接读字段调方法需改用 facade(`InitRedis`/`GetDB`/`ValidateStruct` 等)或 `.Load()`;`database.DefaultManager = x` 改 `database.SetDefaultManager(x)`。 +- **`jwt.DefaultJWT` 包级变量删除** → `GetDefaultJWT()` / `SetDefaultJWTManager()`。 +- **`repository.FindWhereOrdered`/`FindPageWhereOrdered` 签名**:`args []any` → `args ...any`,`order` 前置于 `query`。 +- **`response.Response` 的 `Data`/`RequestID` 去 `omitempty`**:两字段在所有响应中恒存在。 +- **`cache.IsLocked`/`GetLockTTL`/`ForceUnlock`** Redis 不可用改返 `ErrRedisNotReady`(锁操作正确性相关)。 +- **`config.Load()` 返回深拷贝**:新增 `(*Config).Clone()`;`Get()` 仍返只读指针(热路径零分配)。 +- **`handler.GetPage` 加 `page` 上限 10000**;`utils.EqualsIgnoreCase` 改 `strings.EqualFold`;`utils.ReadFile` 去 TOCTOU 前置检查(错误改 `errors.Is(err, os.ErrNotExist)`)。 + +升级:`go get github.com/EthanCodeCraft/xlgo-core@v1.2.0`(⚠️ 含破坏性变更,详见 CHANGELOG 迁移说明) + ### v1.1.1 (2026-06-23) > v1.1.0 的补丁发布:补 `ServerConfig.Host` 绑定地址、面向用户文案统一中文、修正 README 过时/错误描述(含会致启动失败的配置示例)。 diff --git a/app.go b/app.go index 61880e7..a19449d 100644 --- a/app.go +++ b/app.go @@ -28,7 +28,7 @@ import ( // Version 框架版本号。发版时只改这一处,避免版本字面量散落各处。 // CLI(xlgo version)、脚手架生成的 go.mod 等均引用此常量。 -const Version = "1.1.1" +const Version = "1.2.0" // HealthCheckFunc 健康检查函数 type HealthCheckFunc func(context.Context) error diff --git a/cmd/xlgo/commands.go b/cmd/xlgo/commands.go index df3b820..fbd91d8 100644 --- a/cmd/xlgo/commands.go +++ b/cmd/xlgo/commands.go @@ -281,7 +281,7 @@ func createRepository(name, nameTitle string) error { content := fmt.Sprintf(templates.RepositoryMake, nameTitle, name, nameTitle, nameTitle, nameTitle, name, nameTitle, nameTitle, nameTitle, nameTitle, - nameTitle, nameTitle, nameTitle, + nameTitle, nameTitle, ) content = replaceModuleImports(content) diff --git a/cmd/xlgo/templates.go b/cmd/xlgo/templates.go index 2cfe10e..77cc370 100644 --- a/cmd/xlgo/templates.go +++ b/cmd/xlgo/templates.go @@ -491,14 +491,13 @@ func New%sRepository() *%sRepository { } } -// FindByName 根据名称查询 +// FindByName 根据名称查询。 +// +// 走 BaseRepo.FindOne → readConn 读连接:默认路由到从库(读写分离,H6c), +// 需读主库用 database.UseMaster(ctx),事务内自动 join 外层事务。 +// 不要用 r.GetDB() 自行查询——它返回注入的主库且不参与路由(M-35 footgun)。 func (r *%sRepository) FindByName(ctx context.Context, name string) (*model.%s, error) { - var m model.%s - err := r.GetDB().WithContext(ctx).Where("name = ?", name).First(&m).Error - if err != nil { - return nil, err - } - return &m, nil + return r.FindOne(ctx, "name = ?", name) } `,