service.xpcool.com/docs/change-log/2026-08-24.md
夏犀麟 5cd8f0f551 refactor(api): 契约文件 index.go 重命名为 <功能名>.go
- tools/{uuid,md5,random,time,ip}/index.go → 对应 <功能名>.go(git mv 保留历史)
- 目录名=包名=文件名三一致,扩展时目录内按功能加文件(ocr.go → + idcard.go + invoice.go)
- doc.go / AGENTS.md / PROJECT_STRUCTURE.md 同步规则说明
- 冒烟测试 5 端点全部通过
2026-08-24 18:07:33 +08:00

156 lines
9.8 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.

# Change Log 2026-08-24
## 请求
1. 新增一个公共模块模块下存放 `tools` 功能模块`tools` 下再分各种子功能
2. 建立项目上下文记忆体系记录每次请求与更改方案对比后落地要求后续使用其他 CodeBuddy 账号也能无缝衔接
## 变更
新增文件
- `common/doc.go` 公共模块说明不依赖 internal可独立抽取
- `common/tools/doc.go` tools 模块布局清单与封装规则
- `common/tools/md5/md5.go` MD5 摘要Md5Hex / Md5Bytes / Md5File
- `common/tools/cryptox/cryptox.go` AES-128-CBC / DES-ECB 加解密base64 输出密钥任意长度自动规范化
- `common/tools/uuid/uuid.go` 唯一 IDNew 32 / Short 短随机码
- `common/tools/random/random.go` 随机数/随机串Int / String / Digits / Letters
- `common/tools/timex/timex.go` 时间工具Format / Timestamp / StartOfDay / EndOfDay
- `common/tools/convertx/convertx.go` 类型转换带默认值ToInt / ToInt64 / ToFloat64 / ToString / ToBool
- `common/tools/strx/strx.go` 字符串工具命名转换 SnakeCase/CamelCase + 脱敏 MaskPhone/MaskIDCard/MaskName
- `common/tools/slicex/slicex.go` 泛型切片工具Contains / Unique / Chunk / Map / Filter
- `common/tools/ip/ip.go` IP 工具IsValid / LocalIP / IsInternal / ToLong / ToString
- `common/tools/filex/filex.go` 文件工具Exists / IsDir / ReadString / WriteString
- `AGENTS.md` 项目智能体说明书架构规范命令记忆体系索引
- `docs/change-log/2026-08-24.md` 本文档
修改文件
- `.gitignore` 追加 `.workbuddy/`本机记忆不入库
- `PROJECT_STRUCTURE.md` 目录树补充 `common/` `docs/change-log/`见后续提交
验证`go build ./...` `go vet ./common/...` 全部通过
## 决策与理由
- **公共模块放顶层 `common/` 而非 `internal/common/`**Go internal 包无法被外部模块引用放顶层便于未来抽取为独立库/被同仓库其他服务复用
- **tools 一律薄封装 GoFrame 内置组件**v2.10.2 AES/DES 已拆为 `crypto/gaes``crypto/gdes`UUID `util/guid` `gslicer`用标准库 `slices` 替代避免重复造轮子保持与框架一致
- **记忆体系三层方案**对比见下
1. `AGENTS.md`根目录 长期稳定规范跨工具标准Claude Code/CodeBuddy/Codex 等均识别 git
2. `docs/change-log/YYYY-MM-DD.md` 每次请求变更的结构化记录 git **这是跨账号衔接的关键**
3. `.workbuddy/memory/` WorkBuddy 本机增强不入库
- 对比过 `CLAUDE.md`Claude Code 专属已建议统一为 AGENTS.md`.cursor/rules`Cursor 专属`.codebuddy/` CodeBuddy 读取它们都不是最大公约数故不采用
## 待办与风险
- 后续每次任务完成后更新 `docs/change-log/`当日文件追加+ 提交 git确保其他账号 clone 即恢复上下文
- `convertx` 依赖 gconv "转换失败返回零值"行为无法区分"0"与非法输入需要严格转换的场景应在 service 层先校验
- 本次变更尚未 git 提交建议尽快 commit
---
## 追加17:30方向纠正 公共模块实为公共接口
### 请求
用户澄清要新增的是**给前端调用的公共 HTTP 接口**此前误建成 Go 工具包确认应规划到 `api/` 契约层
### 变更
新增文件
- `api/common/v1/tools.go` 公共接口契约`UUIDReq/Res``MD5Req/Res``RandomReq/Res``TimeReq/Res``IPReq/Res`g.Meta 路由元数据
- `internal/controller/common/tools.go` 控制器实现薄适配层复用 `common/tools/*` Go
修改文件
- `internal/cmd/cmd.go` 新增公开分组 `s.Group("/api/common/v1", ...)`Recover+CORS+HandlerResponse**无鉴权**
- `common/tools/timex/timex.go` 修复`Format` 内部改用 `Layout()` 方法见决策
- `internal/controller/common/tools.go` `Time` `now.Layout(...)`
- `AGENTS.md` 目录树与新增公共接口小节注意事项补 gtime 与包名差异
- `PROJECT_STRUCTURE.md` 目录树补充 `api/common/v1`
验证`go build ./...``go vet` 通过**实际启动服务冒烟测试** 5 个端点全部返回正确含修复后 time 格式化
### 决策与理由
- **路由前缀 `/api/common/v1`** `/api/v1`(user)`/admin/v1`(admin) 平级的独立公开前缀天然不套登录鉴权前端三个端mini/h5/app通用
- **契约层放 `api/common/v1`实现放 `internal/controller/common`** user/admin 完全同构公共接口不需要 service 纯工具计算controller 直接复用 `common/tools` 避免过度分层
- **🐛 gtime v2.10.2 大坑已修复**`Time.Format()` 参数是 **PHP 风格**`"Y-m-d H:i:s"` Go layout`"2006-01-02 15:04:05"`会原样输出Go layout 必须用 `Time.Layout()``common/tools/timex` 已统一封装为 `Layout` 语义调用方直接 `timex.Format(t, layout...)` 即可
- **冒烟测试教训**`go run` spawn 子进程`kill %1` 只杀包装进程残留的 `main.exe` 会继续占用 8000 端口导致后续测试打到旧代码杀进程需 `netstat -ano | grep :8000` PID `Stop-Process`
### 待办与风险
- 本次追加变更同样未提交 git与上文合并为一次 commit
- 公共接口已开放无鉴权能力md5/random/uuid 后续新增接口时需评审是否应限流/加签名避免被滥用
---
## 追加18:05开放接口命名决策 + API 目录重构
### 请求
1. 变更 API 目录设计契约层改为 `tools/<子功能>/index.go` 结构示例 `/api/common/v1/tools/ocr/index.go`
2. 同步修改所有涉及处控制器路由
3. 把命名规则记入项目记忆
4. 咨询公共接口一般用 common 命名吗有没有更好的
### 变更
新增文件契约层按子功能拆目录
- `api/open/v1/tools/doc.go` tools 目录结构规则说明
- `api/open/v1/tools/uuid/index.go``md5/index.go``random/index.go``time/index.go``ip/index.go` 每子功能一个目录index.go `package <子功能名>`g.Meta tags `Open/Tools`
- `internal/controller/open/controller.go` Controller 结构 + New()
- `internal/controller/open/uuid.go``md5.go``random.go``time.go``ip.go` 按子功能拆文件import 对应契约子包
删除文件
- `api/common/v1/tools.go``api/common/` 目录
- `internal/controller/common/tools.go``internal/controller/common/` 目录
修改文件
- `internal/cmd/cmd.go` import `commonctl``openctl`路由 `/api/common/v1``/api/open/v1`注释改 Open tools API
- `AGENTS.md` 目录树更新公共接口小节改为开放接口api/open/v1与命名规则记录 open 命名决策与 tools 子功能目录规则
- `PROJECT_STRUCTURE.md` 目录树同步
验证`go build ./...``go vet` 通过冒烟测试旧路由 `/api/common/v1/tools/time` 返回 404新路由 `/api/open/v1/tools/*` 5 端点全部正确
### 决策与理由
- **命名 common open**用户询问"公共接口一般用 common 吗"对比后选 **open**业界开放接口惯例如支付宝 /open/api语义强调对外暴露无鉴权`public` 为并列备选更强调"公开"`common` 偏内部通用语义弃用命名规则已记入 AGENTS.md开放接口小节
- **契约层目录规则**`api/open/v1/tools/<子功能名>/index.go` 每子功能一目录 GoFrame 惯例api 下按功能分包一致用户示例 ocr 即为后续子功能如未来加 OCR 识别接口即建 `tools/ocr/index.go`控制器 `internal/controller/open/<子功能名>.go` 对应拆文件 package open
- **路由绑定不受目录重构影响**GoFrame 通过 controller 方法参数反射定位 g.Meta契约包拆成多个子包uuid/md5/random/time/ip不影响 `group.Bind(openctl.New())` 自动注册cmd.go 只需改前缀
- 包名 `time`api/open/v1/tools/time与标准库 time 潜在同名controller 中统一用 import 别名 `timeapi` 规避
### 待办与风险
- 前端若已联调旧 `/api/common/v1` 路径需同步改 `/api/open/v1`当前无线上前端风险低
- 新增子功能记得更新 `api/open/v1/tools/doc.go` 的示例清单
---
## 追加18:08契约文件 index.go <功能名>.go
### 请求
用户咨询"子功能目录内用 index.go 还是 <功能名>.go 更易扩展维护"确认推荐后执行改动
### 变更
- `git mv` 重命名 5 个契约文件`tools/{uuid,md5,random,time,ip}/index.go` `tools/{uuid,md5,random,time,ip}/{uuid,md5,random,time,ip}.go`包内容不变
- `api/open/v1/tools/doc.go` 规则说明改为目录名=包名=文件名三一致补充"功能变大后目录内加文件"的扩展指引
- `AGENTS.md` / `PROJECT_STRUCTURE.md` 同步 index.go 引用为 <name>.go
验证`go build ./...``go vet` 通过冒烟测试 5 端点全部正常
### 决策与理由
- ** <功能名>.go 而非 index.go** 目录名=包名=文件名三一致导航直观 index.go "入口"语义功能膨胀后出现 `index.go + idcard.go` 混排会失去入口意义 `<name>.go + idcard.go` 自然 符合 Go 生态主流strings/strings.go GoFrame 官方模板api/user/v1/user.go
- **扩展路径已定型**子功能从 1 个端点到多个端点只需在目录内加文件 ocr 目录 `ocr.go → + idcard.go + invoice.go`无需重构文件名
### 待办与风险
- 无新增风险后续新增子功能统一按 `tools/<name>/<name>.go` 建文件