# 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//`,內部分 `domain`(介面 + enum + errors) / `repository`(Mongo / Redis 實作) / `usecase`(原子業務邏輯) / `config`。 跨模組編排(例如「發 OTP → 寄信 → 驗碼 → 更新 profile」)一律放在 `internal/logic//`,**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//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//_logic.go` 的業務邏輯 5. `go build ./...` 確保編譯通過 6. `make lint` / `make test` 視改動範圍跑 ### 2. 新增 / 修改業務模組 - 領域介面與型別放 `internal/model//domain/` - Mongo / Redis 實作放 `internal/model//repository/` - 原子 usecase 放 `internal/model//usecase/`(**不可**互相呼叫) - 多步驟流程編排放 `internal/logic//` - 模組的對外裝配入口統一在 `internal/model//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` 加 ` rest.Middleware` 欄位,於 `NewServiceContext` 結尾 wire `sc. = middleware.NewMiddleware(...).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//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()` 裡呼叫 `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`。