98 lines
5.0 KiB
Markdown
98 lines
5.0 KiB
Markdown
|
|
# AGENTS.md
|
|||
|
|
|
|||
|
|
給 AI coding agent(Claude / Cursor / Codex / 其他)的專案工作準則。請在開始任務前讀過一遍,並在需要時翻閱對應子文件。
|
|||
|
|
|
|||
|
|
## 專案簡介
|
|||
|
|
|
|||
|
|
`template-monorepo` 是基於 [go-zero](https://github.com/zeromicro/go-zero) 的 API Gateway,採用「**模組化 Clean Architecture**」:每個業務模組(auth / member / notification / permission ...)放在 `internal/model/<module>/`,內部分 `domain`(介面 + enum + errors) / `repository`(Mongo / Redis 實作) / `usecase`(原子業務邏輯) / `config`。
|
|||
|
|
|
|||
|
|
跨模組編排(例如「發 OTP → 寄信 → 驗碼 → 更新 profile」)一律放在 `internal/logic/<module>/`,**usecase 不可呼叫其他 usecase**。
|
|||
|
|
|
|||
|
|
## 必讀文件
|
|||
|
|
|
|||
|
|
| 文件 | 何時讀 |
|
|||
|
|
|---|---|
|
|||
|
|
| [`generate/api/README.md`](../generate/api/README.md) | 新增 / 修改 API 端點、type、文件分組、欄位描述、enum 列舉前 |
|
|||
|
|
| [`generate/doc-generate/README.md`](../generate/doc-generate/README.md) | 需要查 go-doc 支援的 tag / `@respdoc` 寫法時 |
|
|||
|
|
| `internal/model/<module>/README.md` | 動到該模組的領域邏輯時 |
|
|||
|
|
| `docs/model.md`(若存在) | 全局架構規範 |
|
|||
|
|
|
|||
|
|
## 標準工作流程
|
|||
|
|
|
|||
|
|
### 1. 修改 API(`.api` → handler / types / docs)
|
|||
|
|
|
|||
|
|
1. 編輯 `generate/api/*.api`(遵守 `generate/api/README.md` 的三條規則:tags 分組 / backtick 行末 `//` 中文 description / `options=A|B|C` enum)
|
|||
|
|
2. `make gen-api` — 重新產生 `internal/handler/`、`internal/logic/`(已存在則不覆蓋)、`internal/types/types.go`
|
|||
|
|
3. `make gen-doc` — 重新產生 `docs/openapi/gateway.yaml`(gitignore,本地驗證用)
|
|||
|
|
4. 實作 / 修改 `internal/logic/<module>/<handler>_logic.go` 的業務邏輯
|
|||
|
|
5. `go build ./...` 確保編譯通過
|
|||
|
|
6. `make lint` / `make test` 視改動範圍跑
|
|||
|
|
|
|||
|
|
### 2. 新增 / 修改業務模組
|
|||
|
|
|
|||
|
|
- 領域介面與型別放 `internal/model/<module>/domain/`
|
|||
|
|
- Mongo / Redis 實作放 `internal/model/<module>/repository/`
|
|||
|
|
- 原子 usecase 放 `internal/model/<module>/usecase/`(**不可**互相呼叫)
|
|||
|
|
- 多步驟流程編排放 `internal/logic/<module>/`
|
|||
|
|
- 模組的對外裝配入口統一在 `internal/model/<module>/usecase/module.go`,並從 `internal/svc/service_context.go` 注入
|
|||
|
|
|
|||
|
|
### 3. 錯誤碼
|
|||
|
|
|
|||
|
|
- 業務碼格式 `SSCCCDDD`(scope * 1_000_000 + category * 1_000 + detail)
|
|||
|
|
- Scope 註冊在 `internal/library/errors/code/types.go`(Facade=10, Auth=28, Member=29, Notification=30, Permission=31)
|
|||
|
|
- 新增 scope 時:同步更新 `gateway.api` 的 `bizCodeEnumDescription`
|
|||
|
|
|
|||
|
|
### 4. Middleware(go-zero 正規手段)
|
|||
|
|
|
|||
|
|
**禁止**在 `gateway.go` 用 `server.Use(...)` 全域掛 middleware,**所有** middleware 都透過 `.api` 的 `middleware:` 宣告:
|
|||
|
|
|
|||
|
|
```go
|
|||
|
|
@server (
|
|||
|
|
group: auth
|
|||
|
|
prefix: /api/v1/auth
|
|||
|
|
middleware: AuthJWT // 一個
|
|||
|
|
// middleware: AuthJWT,CasbinRBAC // 多個用逗號
|
|||
|
|
)
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
跑 `make gen-api` 後 `routes.go` 會自動 `rest.WithMiddlewares([]rest.Middleware{serverCtx.AuthJWT}, ...)`。
|
|||
|
|
|
|||
|
|
撰寫新 middleware 時:
|
|||
|
|
- 用 **struct + `Handle()` method** 模式(不是 factory function)
|
|||
|
|
- 檔名 = goctl stringx 規則(例 `AuthJWT` → `authjwt_middleware.go`、`CasbinRBAC` → `casbinrbac_middleware.go`)
|
|||
|
|
- 在 `ServiceContext` 加 `<Name> rest.Middleware` 欄位,於 `NewServiceContext` 結尾 wire `sc.<Name> = middleware.New<Name>Middleware(...).Handle`
|
|||
|
|
- Actor context 一律用 `internal/library/actor`(`WithActor` / `ActorFromContext`),禁止各 package 自定 `actorKey struct{}`(會造成 context value 進不來)
|
|||
|
|
|
|||
|
|
詳細範例與分組原則見 [`generate/api/README.md`](../generate/api/README.md) "Middleware" 章節。
|
|||
|
|
|
|||
|
|
### 4. Redis / Mongo / 設定
|
|||
|
|
|
|||
|
|
- 每個模組的設定型別放 `internal/model/<module>/config/config.go`,再合入 `internal/config/config.go` 的 `Config` struct
|
|||
|
|
- Redis client 共用 `internal/library/redis/`,需 Pub/Sub 用 `client.PubSubClient()`
|
|||
|
|
- Mongo index 註冊到 `cmd/mongo-index/main.go`(在 `run()` 裡呼叫 `<module>repo.EnsureMongoIndexes`)
|
|||
|
|
|
|||
|
|
## 通用準則
|
|||
|
|
|
|||
|
|
- **回應 traditional Chinese**(繁體中文)
|
|||
|
|
- 程式碼註解只寫「為什麼」、邊界條件、trade-off,**不寫**「import the module / increment counter」這類顯而易見的描述
|
|||
|
|
- 不主動建立 `*.md` 文件,除非使用者明確要求
|
|||
|
|
- 改 git config / 強制 push / `rm -rf` 等破壞性操作 **必須**先取得使用者同意
|
|||
|
|
- 不要在沒被要求時直接 commit;commit 前先 `git status` / `git diff` 確認
|
|||
|
|
- commit message 用繁中描述「為什麼」改,不是「改了什麼」
|
|||
|
|
|
|||
|
|
## 指令速查
|
|||
|
|
|
|||
|
|
| 指令 | 用途 |
|
|||
|
|
|---|---|
|
|||
|
|
| `make gen-api` | `.api` → handler / logic(skip exists)/ types |
|
|||
|
|
| `make gen-doc` | `.api` → `docs/openapi/gateway.yaml` |
|
|||
|
|
| `make gen-mock` | 模組 mock(gomock) |
|
|||
|
|
| `make tools` | 安裝 goctl / goimports / golangci-lint |
|
|||
|
|
| `make fix` | gofmt + goimports + lint --fix + lint |
|
|||
|
|
| `make check` | fix + test(提交前) |
|
|||
|
|
| `make run-dev` | 本機啟動(需 `make deps-up`) |
|
|||
|
|
| `make deps-up` | docker compose Mongo + Redis |
|
|||
|
|
| `make mongo-index` | 建立 / 更新 Mongo 索引 |
|
|||
|
|
|
|||
|
|
完整列表跑 `make help`。
|