feat(lyra)!: 接入分类查询并集中组装依赖
- 使用 Squirrel 与 sqlx 实现分类查询 - 集中组装依赖并向 handler 注入 model 接口 - 显式转换分类响应 DTO,统一空列表输出 - 补充路由与 handler 测试,同步架构文档 BREAKING CHANGE: 将 GET /hello 替换为 GET /test,响应由问候字符串改为分类列表
This commit is contained in:
@@ -0,0 +1,42 @@
|
||||
# 架构审查与提交前收尾
|
||||
|
||||
日期:2026-10-17
|
||||
|
||||
状态:审查及已批准修正完成,父会话已复查代码与文档;等待更新暂存区及确认提交信息。
|
||||
|
||||
## 当前结论
|
||||
|
||||
- 当前实际调用链为 main → buildDependencies → buildHandlers → router 的 GET /test → TestHandler.Hello → CategoryModel.FindAll → PostgreSQL。
|
||||
- 显式注入、入口容器边界、model 接口和路由依赖方向成立;当前单条只读查询不需要额外 service 或事务框架。
|
||||
- 审查发现的 DTO 边界与当前状态文档问题已修正:handler 显式转换为 api.CategoryResponse,README 与架构文档已同步。
|
||||
- 超时、DSN 编码、优雅关闭和查询语义命名列为后续增强,不扩入本轮修正。
|
||||
|
||||
## 已批准的最小方案
|
||||
|
||||
1. 增加分类响应 DTO,以明确 JSON 字段,由现有 TestHandler 显式转换;空列表保持 [],不改变 SQL。
|
||||
2. 用假的 CategoryModel 补 handler 测试,覆盖成功、空列表、失败和 context 传递,不连接数据库。
|
||||
3. 更新 README.md 和 docs/architecture.md 的当前实现说明,历史计划保留为历史。
|
||||
4. 最终执行格式检查、go test ./... -count=1、go build ./...、go vet ./...,父会话审阅最终差异。
|
||||
5. 依 git-commit 流程确认暂存范围;任何重新暂存后重新检查全部索引文件的完整内容,再展示提交信息并等待明确确认。
|
||||
|
||||
## 实施分工与范围
|
||||
|
||||
- 代码 lane(复用 fixer):仅写 internal/api/category.go、internal/handler/test.go、internal/handler/test_test.go,负责 DTO 转换与成功/空结果/失败/context 测试及 Go 验证。
|
||||
- 文档 lane(独立 fixer):仅写 README.md、docs/architecture.md,按当前磁盘源代码更新现状;不得声称真实数据库查询已验证。
|
||||
- 父会话维护本计划、整合终态并检查实际差异;不修改 SQL、路由名称、连接逻辑、依赖版本或其他历史计划。
|
||||
- 两个写入范围互不重叠;全部终态后确认验证证据仍适用,再进入重新暂存与完整索引安全检查。
|
||||
|
||||
## 已有验证及边界
|
||||
|
||||
- 当前未修正版本的 go test ./... -count=1、go build ./...、go vet ./...、gofmt -l . 全部通过。
|
||||
- 当前路由测试不连接数据库,仅验证路由分发;真实 handler 与 SQL 查询尚未验证。
|
||||
- 当前暂存的十个非删除文件完整内容已检查,未发现新增疑似真实敏感值或意外生成物;未暂存新的修正内容。
|
||||
- 审查所有者:oracle 静态审查、fixer 独立验证、父会话负责取舍及提交安全检查。
|
||||
|
||||
## 修正后的证据
|
||||
|
||||
- 新增分类响应 DTO 和 handler 替身测试;成功映射、空切片与 nil 结果输出 []、失败返回通用 500、请求 context 透传均已验证。
|
||||
- 代码 lane 在最终 Go 代码上执行 go test ./internal/handler -v -count=1、go test ./... -count=1、go build ./...、go vet ./... 均通过,新增及修改 Go 文件的格式检查通过。
|
||||
- 文档 lane 仅修改 README.md 与 docs/architecture.md;父会话已读取 DTO、handler、测试与两份文档并复查,未发现新的阻断问题。
|
||||
- 不重复运行未发生变化的 Go 代码验证;真实 SQL 与数据库端到端路径仍未验证。
|
||||
- 更新暂存区后必须重新检查全部暂存文件的完整版本,之前索引安全检查不自动适用于新内容。
|
||||
@@ -0,0 +1,19 @@
|
||||
# 重写当前路由回归测试
|
||||
|
||||
日期:2026-10-17
|
||||
|
||||
## 已批准范围
|
||||
|
||||
用户要求重写 router_test。当前路由为 GET /test,注册入口接收 router.Handlers,其中 TestHandler 为 gin.HandlerFunc。
|
||||
|
||||
- 仅新增或重写 internal/router/router_test.go,不修改生产代码、依赖或用户已调整的模型字段。
|
||||
- 测试使用 package router_test、gin.New、httptest 和注入的替身 handler,不启动端口、不访问数据库。
|
||||
- 覆盖 GET /test 调用注入处理器,并保留处理器自定义的状态码和响应体。
|
||||
- 覆盖未知路径和不支持的方法均不调用处理器;使用 gin.New 默认设置,两者预期 404。
|
||||
- 每个用例创建独立引擎;不使用 t.Parallel,避免 Gin 全局模式设置竞争。
|
||||
|
||||
## 验证所有者与证据
|
||||
|
||||
- fixer:只写测试文件,gofmt,执行 go test ./internal/router -v -count=1 与 go test ./...。
|
||||
- 父会话:检查最终差异、替身调用次数断言、当前路由名以及无数据库依赖。
|
||||
- 本轮证据仅覆盖路由注册与分发,不覆盖真实 TestHandler 或数据库查询。
|
||||
@@ -0,0 +1,66 @@
|
||||
# Squirrel + sqlx 最小查询练习
|
||||
|
||||
日期:2026-10-17
|
||||
|
||||
## 范围与状态
|
||||
|
||||
- 前期由用户自行实现;2026-10-17 用户明确批准代改依赖组装示例。本轮仍不启动服务、不连接数据库。
|
||||
- 使用隔离的本地 PostgreSQL 测试库,不复用真实或共享环境。
|
||||
- 当前范围调整:用户先在已有 /hello handler 中手动验证查询;下方 categories 集成测试步骤保留为后续练习。
|
||||
- 临时在 handler 中只读查询 current_database(),不依赖业务表;正式业务查询再迁至 model。
|
||||
|
||||
## 当前 Hello 实验
|
||||
|
||||
### 本轮已批准实施:集中依赖组装
|
||||
|
||||
- 以用户现有代码为准:Hello 已通过 CategoryModel.FindAll 查询分类,保留该 SQL、过滤条件和结果映射,不改成系统信息查询。
|
||||
- 新增 cmd/lyra/dependencies.go,buildHandlers(db) 返回 router.Handlers,当前只装配 Hello(db)。
|
||||
- router.go 定义仅包含 Hello gin.HandlerFunc 的 Handlers,RegisterRoutes 接收它,不再导入 handler 或 sqlx。
|
||||
- main.go 仅把路由注册改为先 buildHandlers(db),再 RegisterRoutes;保留配置、连接和其他用户改动。
|
||||
- Hello 保持 Hello(db) 闭包接口,在返回闭包前创建 CategoryModel,避免每个请求重新构造;修复先返回问候再返回列表的重复响应,错误分支返回 HTTP 500 后立即 return。
|
||||
- 路由测试注入固定响应的替身 handler,验证 /hello 确实调用传入的处理器并维持现有响应契约,不触碰数据库。
|
||||
- 写入范围:cmd/lyra/main.go、cmd/lyra/dependencies.go、internal/router/router.go、internal/router/router_test.go、internal/handler/hello.go;不改 model、依赖文件或敏感配置。
|
||||
- fixer 负责首次编辑前确认缩进与换行、gofmt、go test ./... 和 go build ./...;父会话负责审阅最终差异、依赖方向和用户改动保留情况。
|
||||
- 验证边界:httptest 证明路由注入生效,构建证明组装链编译通过;不宣称真实数据库查询已验证。
|
||||
|
||||
实施结果:上述五个 Go 文件已完成调整。fixer 执行 gofmt、go test ./...、go build ./...、go vet ./... 均通过;父会话已审阅实际差异与新增 dependencies.go,git diff --check 通过。未启动服务或连接数据库,真实查询及 Hello 成功/失败分支尚无运行时验证。用户已有 model/category.go 和依赖文件改动保持不变。
|
||||
|
||||
### 历史练习建议(由上方现状覆盖)
|
||||
|
||||
1. 沿用闭包:Hello(db *sqlx.DB) gin.HandlerFunc,捕获 main 已创建的连接池。
|
||||
2. router.RegisterRoutes 接收 gin.HandlerFunc,不依赖数据库;main 调用 handler.Hello(db) 完成组装。
|
||||
3. 每个请求从 Request.Context 派生五秒超时,使用 Squirrel 构造 SELECT current_database(),sqlx.GetContext 执行并映射字符串。
|
||||
4. 失败使用现有 httpx.Fail 与通用错误码,不返回数据库原始错误;成功使用 httpx.OK 返回当前数据库名。
|
||||
5. 路由测试注入返回固定响应的替身 handler,不连接数据库;保留现有路径、状态码和响应体断言。该测试不覆盖真实 Hello 查询逻辑。
|
||||
6. 用户在隔离本地环境运行服务并请求 /hello 验证真实查询;实验不要对外暴露数据库信息。
|
||||
|
||||
## 后续 categories 练习顺序
|
||||
|
||||
### 依赖组装组织建议(讨论记录,未代改代码)
|
||||
|
||||
- 继续使用显式构造函数注入,不引入 Wire、全局连接或通用依赖容器。
|
||||
- 组装代码可以放在 cmd/lyra/dependencies.go,仍属于 package main;main 只调用 buildHandlers(db) 并注册路由。
|
||||
- router 可定义只包含 gin.HandlerFunc 的 Handlers 结构,RegisterRoutes 接收该结构,避免路由增加导致参数列表不断增长。
|
||||
- 当前只需要 Hello 字段,其他路由随实际实现添加,不提前创建 model/service 等占位代码。
|
||||
- 后续组装顺序为 db → model → 按需 service → handler;每层只接收实际需要的依赖,不传递整个应用容器。
|
||||
- 该方式减少 main 的杂乱,但不消除新增组件时必须更新组装关系的工作;对象在启动时构造,请求复用连接池。
|
||||
- Dependencies 位置建议:当前若确需该结构,直接定义在 cmd/lyra/dependencies.go,不为单个类型新建包。以后多个入口确实需要复用组装逻辑时,再迁移到 internal/app;该包作为组装上层可引用 model/service/handler/router,业务包不得反向引用 app。当前不创建新目录或依赖容器。
|
||||
|
||||
1. 在 module 根目录引入 github.com/Masterminds/squirrel。
|
||||
2. 准备已执行现有迁移的隔离测试库;如需数据,用户单独准备至少一个分类,测试本身不写数据。
|
||||
3. 测试从 LYRA_TEST_DATABASE_URL 读取连接串;缺失时跳过,不回退到开发配置。
|
||||
4. 注册 pgx stdlib 驱动,创建五秒超时 Context,以 sqlx.ConnectContext 连接并清理连接。
|
||||
5. 定义带 db 标签的局部结果结构,使用 Squirrel 显式声明列、可选 sort 条件、sort/id 排序、有限条数和 Dollar 占位符。
|
||||
6. 调用 ToSql 获取 SQL 和 args,通过 db.SelectContext 执行并映射切片。
|
||||
7. 先验证 SQL/args,再验证真实查询;通过后再提取正式 model 方法。
|
||||
|
||||
## 验证与注意事项
|
||||
|
||||
- Go 命令在 go/projects/lyra 执行。
|
||||
- 查询构造测试应验证使用 $1 而非 ?,过滤值位于 args 中而非拼入 SQL。
|
||||
- 集成测试验证目标库身份、查询无错误、字段映射、过滤与排序。
|
||||
- 空表返回空切片属于成功,但不能证明非空数据映射和排序正确;需要已知数据才能完成这些验收。
|
||||
- 环境变量缺失导致 SKIP 不算数据库查询已通过。
|
||||
- 不记录 DSN、密码或可能包含凭据的连接错误原文。
|
||||
- 完成后执行 go test ./internal/model -run TestCategoryQuery -v -count=1。
|
||||
- 正式复用时使用 sqlx.SelectContext(ctx, executor, ...) 支持 *sqlx.DB 和 *sqlx.Tx;sqlx.ExtContext 接口本身没有 SelectContext 方法。
|
||||
Reference in New Issue
Block a user