service.xpcool.com/AGENTS.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

6.5 KiB
Raw Blame History

AGENTS.md — 项目智能体说明书

本文件是给所有 AI 编程助手CodeBuddy / WorkBuddy / Claude Code / Codex / Cursor 等)看的项目级上下文。 任何账号 clone 本仓库后,助手都应先读本文件与 docs/change-log/ 下最近的记录,即可无缝衔接。 请保持本文件长期稳定:只写「架构、规范、约定」,不要写一次性事项。

项目简介

service.xpcool.com个人多客户端mini / h5 / app后端服务GoFrame v2 单体应用。 核心业务用户认证JWT、内容、收藏、站内消息后台管理RBAC + 操作审计)。

技术栈

语言 Go 1.23.0
框架 github.com/gogf/gf/v2 v2.10.2
数据库 MySQLORM 由 gf 生成 dao/do/entity
认证 JWTinternal/library/jwtadmin 另有 X-Permission 校验

目录结构

service.xpcool.com/
├── api/            # HTTP 契约与 Swagger 元数据
│   ├── user/v1/        # /api/v1       用户端 API登录公开其余走 UserAuth
│   ├── admin/v1/       # /admin/v1     管理端 APIAdminAuth + X-Permission
│   └── open/v1/        # /api/open/v1  开放接口(给前端调用,公开无鉴权)
│       └── tools/      #   工具子功能契约每子功能一目录tools/<name>/<name>.go
├── common/         # 公共可复用模块(不依赖 internal可独立抽取成库
│   └── tools/      #   工具模块,按子功能分包(见下文)
├── internal/
│   ├── cmd/            # 启动引导(路由分组注册在此)
│   ├── consts/         # 错误码与常量
│   ├── controller/     # API→service 适配层(不写业务;含 open/ 开放接口实现)
│   ├── service/        # 领域用例(业务逻辑直接写这里,不用 logic/
│   ├── dao/            # gf gen dao 生成,禁止手改
│   ├── model/          # entity/ do/ dto/ vo/entity、do 生成,禁止手改)
│   ├── middleware/     # 路由中间件
│   ├── library/        # jwt / page / response 等内部基础件
│   └── table/          # 表列名常量
├── manifest/       # config.dev/test/prod.yaml、sql 迁移
├── docs/change-log/ # 每次请求与变更的记录(重要!见「上下文记忆」)
└── utility/        # (预留)跨切面辅助

开放接口api/open/v1前端调用与命名规则

  • 命名决策:公共接口前缀用 open(不用 common。理由common 语义偏"内部公共代码"open 是开放接口业界惯例(支付宝 /open/api 等),更能表达"对外暴露、无鉴权"。同属"公开"语义的备选还有 public
  • 路由前缀 /api/open/v1公开、无鉴权,实现于 internal/controller/open
  • tools 子功能目录规则api/open/v1/tools/<子功能名>/<子功能名>.go 定义该子功能的 Req/Res 契约(目录名=包名=文件名三一致);控制器 internal/controller/open/<子功能名>.go 放对应方法controller 统一 package open)。子功能变大后按端点/子领域在目录内加文件(如 ocr 目录下 ocr.goocr.go + idcard.go + invoice.go),不要堆在一个文件里。
  • 当前端点:GET/POST /tools/*uuid、md5、random、time、ip底层复用 common/tools Go 包。
  • 新增子功能三步:① api/open/v1/tools/<name>/<name>.go 写 Req/Resg.Meta 带 path/methodinternal/controller/open/<name>.go 加方法;③ 路由自动绑定,无需改 cmd.go。

公共工具模块 common/tools

  • 规则:不依赖 internal/,只薄封装 GoFrame 内置组件新工具优先复用内置gmd5/gaes/gdes/guid/grand/gtime/gconv/gstr/gfile...),避免重复造轮子。
  • 子功能:md5cryptox(AES/DES)、uuidrandomtimexconvertxstrxslicexipfilex
  • 新增子功能:在 common/tools/ 下建子包,更新 common/tools/doc.go 的布局清单。

分层与调用规范(必须遵守)

  1. 调用链:controller → service → dao → model(do)controller 不碰 dao。
  2. DTO/VO 边界:跨层出入参走 internal/model/dtointernal/model/voAPI 类型与 entity 不得越界。
  3. 数据库操作必须用 DO 对象internal/model/do),禁止 g.Map;未赋值字段保持 nil 自动忽略:
    dao.Users.Ctx(ctx).Where(cols.Id, id).Data(do.User{Uid: uid}).Update()
    
  4. 时间字段自动维护created_at/updated_at/deleted_at 由 ORM 自动处理,禁止手动赋值;软删除用 Delete(),禁止手写 WhereNull(cols.DeletedAt)
  5. 错误处理一律用 gerror(保留堆栈);响应统一走 internal/library/response
  6. 生成代码dao/do/entity禁止手改,改表后跑 gf gen dao 重新生成。
  7. 声明 ≥3 个相关变量时,用 var (...) 块对齐。

常用命令

# 运行dev
GF_GCFG_FILE=config.dev.yaml DB_DSN="user:pass@tcp(127.0.0.1:3306)/db?loc=Local" JWT_SECRET=xxx go run main.go
# 数据库模型生成(唯一来源)
gf gen dao -p internal -g default -gt -c
# 构建 / 测试
go build ./...
go test ./...

上下文记忆(重要)

三层配合,保证「换个账号/换台机器也能无缝衔接」:

  1. 本文件AGENTS.md:长期稳定的架构与规范。
  2. docs/change-log/YYYY-MM-DD.md:每次对话的「请求 + 变更 + 决策」记录,随 git 提交。
    • 每次完成任务后,若 docs/change-log/ 已有当日文件则追加,否则新建;
    • 格式固定:## 请求 / ## 变更(含文件清单)/ ## 决策与理由 / ## 待办与风险
    • 助手开工前先读最近 1-2 篇,快速恢复上下文。
  3. .workbuddy/memory/WorkBuddy 桌面端本机记忆(每日日志 + MEMORY.md已加入 .gitignore不入库,仅本机增强。

注意事项

  • ⚠️ gtime v2.10.2 格式化Time.Format("Y-m-d H:i:s") 是 PHP 风格;传 Go layout2006-01-02)要用 Time.Layout(...)。工具包 common/tools/timex 已统一封装。
  • ⚠️ gf v2.10.2 包名与旧版不同AES/DES 在 crypto/gaescrypto/gdes(无 gcryptoUUID 在 util/guid(无 guuid无 gslicer用标准库 slices
  • 配置文件按 GF_GCFG_FILE 切换;manifest/config/config.yaml 不入库。
  • 生产环境强密码:JWT_SECRET、数据库口令。
  • 变更涉及 API 时同步更新 api/ 下的 Swagger 元数据注释。