add AGENTS

This commit is contained in:
王性驊 2026-04-09 07:53:15 +08:00
parent b4b28eecd4
commit 7dfba5e237
62 changed files with 7689 additions and 0 deletions

109
agents/backend-agent.md Normal file
View File

@ -0,0 +1,109 @@
# Backend Agent (Golang Backend Engineer)
## Role Positioning
**Golang Backend Engineer** - Responsible for API design, server-side implementation, and ensuring high-quality, testable Golang code following Domain-Driven + go-zero style architecture.
## Core Responsibilities
1. **API Specification** - Design RESTful APIs based on the PRD, producing OpenAPI 3.0 specifications
2. **Domain Modeling** - Define domain entities, value objects, and business rules aligned with PRD and DB schema
3. **Core Implementation** - Build server-side logic following Domain-Driven architecture (pkg/domain definitions → pkg/usecase implementation → internal/logic handler → pkg/repository infrastructure)
4. **Quality Assurance (TDD)** - Implement features using Test-Driven Development to ensure high coverage and reliability
5. **Cross-Team Collaboration** - Sync with DBA Agent for schema design, UX Agent for API integration, and QA Agent for testability
## Skills Used
| Stage | Skill | Auxiliary | Input | Output |
|-------|-------|-----------|-------|--------|
| 4: API Design | `be-api-design` | `design-an-interface` | PRD | `docs/api/{date}-{feature}.yaml` |
| 5: DB Schema | Collaborate with DBA Agent | - | API spec + domain model | Alignment confirmation |
| 8: Task Breakdown | Review Orchestrator's plan | - | `./plans/{feature}.md` | Feasibility confirmation |
| 9: Implementation | `go-backend-dev` | `tdd` | Plan + API spec + DB schema | Production-ready Go code |
| 10: QA Support | Bug fix support | - | QA report | Bug fixes + regression tests |
| 11: Code Review | Respond to PR feedback | - | Review comments | Code changes |
## Working Principles
1. **API-First Design** - Define the API contract (OpenAPI) before writing implementation code
2. **Domain-Driven Architecture** - `pkg/domain/` contains pure abstractions (entities, value objects, interfaces), `pkg/usecase/` and `pkg/repository/` contain implementations, `internal/logic/` and `internal/svc/` handle wiring
3. **Test-Driven Development** - Write tests first (Red), then implement (Green), then refactor
4. **Vertical Slices** - Implement end-to-end features one slice at a time, not layer by layer
5. **Error Transparency** - Every error is checked immediately; use `fmt.Errorf` with `%w` for wrapping
6. **Interface Segregation** - Keep interfaces small (1-3 methods); define them where they are consumed
## Rollback Mechanism
```
Design Review Rejects API Spec (Stage 7)
→ Revise OpenAPI spec (skill: be-api-design + design-an-interface)
→ Coordinate with DBA Agent if schema changes needed
QA Failed (Stage 10)
→ Rollback to Stage 8 (Task Breakdown)
→ Fix bugs + add regression tests
→ Re-enter Stage 10
Code Review Failed (Stage 11)
→ Address PR feedback
→ Re-enter Stage 10 for verification
DBA/UX Conflict
→ Coordinate with DBA Agent: adjust domain model or API
→ Coordinate with UX Agent: adjust API responses or request formats
```
## Collaboration with Other Agents
```
Backend Agent ← PM Agent: Receive PRD and non-functional requirements
Backend Agent ←→ DBA Agent: Align API resources with Database Schema (Stage 5)
Backend Agent ←→ UX Agent: Ensure API responses match prototype needs (Stage 6)
Backend Agent ← Design Reviewer: Receive design feedback, revise API spec (Stage 7)
Backend Agent ← Orchestrator: Receive implementation plan (Stage 8)
Backend Agent → QA Agent: Provide testable code and API docs (Stage 10)
Backend Agent ← Code Reviewer: Implement feedback from PR reviews (Stage 11)
```
## Decision Authority
- Define the internal technical structure of the backend (packages, layers)
- Choose specific Go libraries within the approved tech stack
- Determine the granularity of API endpoints and resource modeling
- Set the internal testing strategy (unit, integration, E2E boundaries)
- Decide on error handling patterns and response formats
## Deliverables Checklist
### Stage 4: API Design
- [ ] OpenAPI 3.0 specification saved to `docs/api/`
- [ ] All functional requirements from PRD mapped to endpoints
- [ ] `design-an-interface` alternatives documented
### Stage 5: DB Collaboration
- [ ] Domain model aligns with DB schema
- [ ] Repository interfaces feasible with proposed schema
### Stage 9: Implementation
- [ ] Domain-Driven architecture structure complete (pkg/domain, pkg/usecase, internal/logic, pkg/repository)
- [ ] All layers implemented
- [ ] Unit tests >= 80%, business logic >= 90%
- [ ] Integration tests passing for critical paths
### Stage 10-11: QA & Code Review
- [ ] All QA-reported bugs fixed with regression tests
- [ ] PR review feedback addressed
## Common Issues Handling
**Q: PRD requirements are technically infeasible?**
A: Document the constraint in the API spec, propose alternatives, escalate to PM Agent for scope adjustment.
**Q: API design conflicts with DB schema?**
A: Coordinate with DBA Agent. Prefer changing the mapping layer over altering the DB schema.
**Q: Performance bottleneck detected?**
A: Add caching (Redis), optimize queries with DBA Agent, consider async for long-running operations.
**Q: Test coverage below 80%?**
A: Prioritize usecase layer tests, use table-driven tests for edge cases, add integration tests for critical flows.

View File

@ -0,0 +1,322 @@
# 實施檢查清單
本文件提供 Vibe-Kanban 工作流程的實施檢查清單,確保所有組件都已正確實作。
---
## 檢查清單總覽
- [ ] Phase 1: 核心框架
- [ ] Phase 2: 設計階段技能
- [ ] Phase 3: 整合測試
- [ ] Phase 4: 優化
---
## Phase 1: 核心框架
### 1.1 主控技能 - vibe-kanban
```
skills/vibe-kanban/
├── SKILL.md # 主技能定義
├── references/
│ └── workflow-diagram.md # 工作流程圖
└── templates/
└── state-template.yaml # 狀態模板
```
#### SKILL.md 必須包含
- [ ] 階段定義
- [ ] 狀態機邏輯
- [ ] 階段轉換條件
- [ ] 退回機制
- [ ] 狀態持久化邏輯
- [ ] 進度報告格式
- [ ] 命令列表
- [ ] `/vibe-kanban start`
- [ ] `/vibe-kanban status`
- [ ] `/vibe-kanban next`
- [ ] `/vibe-kanban back`
- [ ] `/vibe-kanban skip`
#### 狀態模板 state-template.yaml
- [ ] 專案名稱欄位
- [ ] 當前階段欄位
- [ ] 歷史記錄欄位
- [ ] 產出文件欄位
- [ ] 阻塞原因欄位
- [ ] 下一步動作欄位
### 1.2 PRD 技能 - pm-prd
```
skills/pm-prd/
├── SKILL.md
└── templates/
└── prd-template.md
```
#### SKILL.md 必須包含
- [ ] 輸入格式定義
- [ ] 輸出格式定義
- [ ] 功能性需求模板
- [ ] 非功能性需求模板
- [ ] 驗收標準模板
- [ ] 優先級排序邏輯
- [ ] 人類審核流程
#### PRD 模板 prd-template.md
- [ ] Metadata 區塊
- [ ] 背景區塊
- [ ] 功能性需求區塊 (FR-001, FR-002, ...)
- [ ] 非功能性需求區塊 (NFR-001, NFR-002, ...)
- [ ] 驗收標準區塊 (AC-001, AC-002, ...)
- [ ] 排期建議區塊
- [ ] 依賴區塊
- [ ] 風險評估區塊
---
## Phase 2: 設計階段技能
### 2.1 API 設計技能 - be-api-design
```
skills/be-api-design/
├── SKILL.md
└── templates/
└── openapi-template.yaml
```
#### SKILL.md 必須包含
- [ ] RESTful API 設計原則
- [ ] OpenAPI 3.0 規格產出
- [ ] 請求/回應 Schema 定義
- [ ] 錯誤處理設計
- [ ] 安全性考量清單
- [ ] 效能考量清單
- [ ] 人類審核流程
#### OpenAPI 模板 openapi-template.yaml
- [ ] info 區塊 (標題、版本、描述)
- [ ] paths 區塊 (端點定義)
- [ ] components/schemas 區塊 (資料模型)
- [ ] responses 區塊 (回應格式)
- [ ] securitySchemes 區塊 (安全機制)
### 2.2 資料庫設計技能- dba-schema
```
skills/dba-schema/
├── SKILL.md
└── templates/
└── schema-template.sql
```
#### SKILL.md 必須包含
- [ ] 資料正規化原則
- [ ] 索引策略
- [ ] 外鍵關聯設計
- [ ] 遷移計畫格式
- [ ] 效能優化建議
- [ ] 人類審核流程
#### Schema 模板 schema-template.sql
- [ ] Migration 標頭
- [ ] Table 定義
- [ ] Index 定義
- [ ] Constraint 定義
- [ ] Trigger 定義
- [ ] Comment 定義
### 2.3 UX 原型技能 - ux-prototype
```
skills/ux-prototype/
├── SKILL.md
└── templates/
├── user-flow-template.md
└── component-mapping-template.md
```
#### SKILL.md 必須包含
- [ ] 使用者流程圖產出
- [ ] 線框圖描述格式
- [ ] 元件與 API 對應邏輯
- [ ] 原型工具建議
- [ ] 人類審核流程
#### 使用者流程模板 user-flow-template.md
- [ ] Mermaid 流程圖
- [ ] 頁面清單表格
- [ ] 頁面 URL 對應
#### 元件對應模板 component-mapping-template.md
- [ ] 頁面元件列表
- [ ] 元件資料來源
- [ ] API 端點對應
- [ ] 快取策略建議
---
## Phase 3: 整合測試
### 3.1 端到端流程測試
- [ ] 測試案例 1: 完整流程從頭到尾
- [Brainstorming → CEO Review → PRD → ... → Deploy]
- [ ] 測試案例 2: CEO 審核退回
- [Brainstorming → CEO Review (失敗) → Brainstorming]
- [ ] 測試案例 3: QA 失敗退回
- [所有階段 → QA (失敗) → Task Breakdown]
- [ ] 測試案例 4: PR 審核失敗退回
- [所有階段 → PR Review (失敗) → Task Breakdown]
### 3.2 狀態持久化測試
- [ ] 測試狀態檔案建立
- [ ] 測試狀態檔案更新
- [ ] 測試狀態檔案恢復
- [ ] 測試狀態檔案損壞處理
### 3.3 退回機制測試
- [ ] 測試退回到上一階段
- [ ] 測試退回到特定階段
- [ ] 測試退回後的產出清理
- [ ] 測試退回後重新執行
### 3.4 併發測試
- [ ] 測試多專案併發執行
- [ ] 測試鎖機制
- [ ] 測試資源競爭
---
## Phase 4: 優化
### 4.1 效能優化
- [ ] 階段轉換時間優化
- [ ] 檔案讀寫優化
- [ ] 快取機制實作
### 4.2 錯誤處理優化
- [ ] 友善錯誤訊息
- [ ] 錯誤恢復機制
- [ ] 錯誤日誌記錄
### 4.3 使用者體驗優化
- [ ] 進度視覺化
- [ ] 預估時間顯示
- [ ] 歷史記錄瀏覽
### 4.4 文件完善
- [ ] 使用者指南
- [ ] 開發者文件
- [ ] API 文件
- [ ] 最佳實踐指南
---
## 測試矩陣
### 功能測試
| 功能 | 測試案例 | 預期結果 | 實際結果 | 狀態 |
|------|---------|---------|---------|------|
| 開始新專案 | 輸入專案名稱 | 建立狀態檔案 | | [ ] |
| 查看狀態 | 執行status | 顯示當前階段 | | [ ] |
| 前往下一階段 | 執行 next | 狀態更新 | | [ ] |
| 退回上一階段 | 執行 back | 狀態回滾 | | [ ] |
| 跳過階段 | 執行 skip | 狀態跳過 | | [ ] |
### 整合測試
| 整合點 | 測試案例 | 預期結果 | 實際結果 | 狀態 |
|--------|---------|---------|---------|------|
| PM → CEO | PRD 審核通過 | 進入 API 設計 | | [ ] |
| CEO 失敗 | PRD 審核失敗 | 退回Brainstorming | | [ ] |
| QA 失敗 | 測試不通過 | 退回 Task Breakdown | | [ ] |
| Deploy | 部署成功 | 專案完成 | | [ ] |
### 效能測試
| 指標 | 目標 | 實際 | 狀態 |
|------|------|------|------|
| 階段轉換時間 | < 5 | | [ ] |
| 狀態載入時間 | < 1 | | [ ] |
|檔案寫入時間 | < 2 | | [ ] |
---
## 部署檢查清單
### 部署前
- [ ] 所有測試通過
- [ ] 文件完整
- [ ] 版本號更新
- [ ] CHANGELOG 更新
### 部署中
- [ ] 備份現有版本
- [ ] 部署新版本
- [ ] 驗證部署成功
### 部署後
- [ ] 監控錯誤日誌
- [ ] 驗證功能正常
- [ ] 更新使用文件
---
## 維護檢查清單
### 每週
- [ ] 檢查錯誤日誌
- [ ] 檢查效能指標
- [ ] 檢查使用者反饋
### 每月
- [ ] 更新技能版本
- [ ] 審核技術債
- [ ] 優化流程
### 每季
- [ ] 全面測試回歸
- [ ] 安全性審核
- [ ] 架構審核
---
## 簽核記錄
| 階段 | 審核人 | 日期 | 簽核 |
|------|-------|------|------|
| Phase 1 | | | [ ] |
| Phase 2 | | | [ ] |
| Phase 3 | | | [ ] |
| Phase 4 | | | [ ] |
| 最終審核 | | | [ ] |

View File

@ -0,0 +1,197 @@
# Vibe-Kanban 快速開始指南
本指南幫助您快速理解如何使用 Vibe-Kanban 工作流程。
---
## 核心概念
### 什麼是 Vibe-Kanban
Vibe-Kanban 是一個由 AI 代理協作的軟體開發工作流程系統。每個開發階段都由特定的 AI 代理負責,從需求探索到部署全自動化。
### 核心角色
| 角色 | 負責階段 | AI 技能 |
|------|---------|---------|
| PM (產品經理) | 需求探索、PRD 撰寫 | brainstorming,pm-prd |
| CEO (商業決策) | 商業價值審核 | plan-ceo-review |
| Backend Engineer | API 設計 | be-api-design |
| DBA | 資料庫規劃 | dba-schema |
| UX Designer | 原型設計 | ux-prototype |
| Design Reviewer | 設計審核 | design-review |
| QA Engineer | 測試驗收 | qa |
| OPS (運維) | 部署 | land-and-deploy |
---
## 使用方式
### 1. 開始新專案
```bash
/vibe-kanban start "使用者認證功能"
```
系統會自動:
1. 建立專案狀態檔案
2. 觸發 PM 進行需求探索
3. 進入 Brainstorming 階段
### 2. 查看當前狀態
```bash
/vibe-kanban status
```
輸出範例:
```
╔══════════════════════════════════════════════════════════════╗
║ VIBE-KANBAN 狀態 ║
╠══════════════════════════════════════════════════════════════╣
║ 專案: feature-user-auth ║
║ 當前階段: CEO_REVIEW (CEO 商業價值審核) ║
║ 狀態: IN_PROGRESS ║
║ ║
║ 下一步: 等待 CEO 審核通過 ║
╚══════════════════════════════════════════════════════════════╝
```
### 3. 前往下一階段
```bash
/vibe-kanban next
```
### 4. 退回修改
```bash
/vibe-kanban back "設計與需求不符,需要重新定義"
```
---
## 工作流程總覽
```
┌─────────┐ ┌──────────┐ ┌─────────┐ ┌───────────┐
│Brainstorm│ ──▶│CEO Review│ ──▶│ PRD │ ──▶│ API Design │
└─────────┘ └──────────┘ └─────────┘ └───────────┘
┌─────────┐ ┌──────────┐ ┌──────────┐ ┌───────────┐
│ Deploy │ ◀──│PR Review │◀───│ QA │◀───│DB Schema │
└─────────┘ └──────────┘ └──────────┘ └───────────┘
```
---
## 各階段產出
### 階段 1-2: 需求探索
- **產出**: `docs/brainstorm/{date}-{feature}.md`
- **內容**: 需求分析、使用者故事、技術方案
### 階段 3: PRD 撰寫
- **產出**: `docs/prd/{date}-{feature}.md`
- **內容**: 功能性需求、非功能性需求、驗收標準
### 階段 4: API 設計
- **產出**: `docs/api/{date}-{feature}.yaml`
- **內容**: OpenAPI 3.0 規格文件
### 階段 5: 資料庫規劃
- **產出**: `docs/db/{date}-{feature}.sql`
- **內容**: 資料表定義、索引、遷移計畫
### 階段 6: UX 原型
- **產出**: `docs/design/{date}-{feature}/`
- **內容**: 使用者流程、線框圖、原型連結
### 階段 7: 設計審核
- **產出**: `docs/design/{date}-{feature}/review-report.md`
- **內容**: 審核報告、修改建議
### 階段 8: 任務拆分
- **產出**: `.gstack/kanban/{project}/tasks.md`
- **內容**: 前後端任務分配
### 階段 9: 實作
- **產出**: 程式碼
- **內容**: 功能實作、單元測試
### 階段 10: QA 測試
- **產出**: `.gstack/qa-reports/qa-report-{date}.md`
- **內容**: 測試報告、Bug 列表
### 階段 11: PR 審核
- **產出**: PR 描述、審核報告
- **內容**: 代碼變更說明
### 階段 12: 部署
- **產出**: `.gstack/deploy-reports/deploy-report-{date}.md`
- **內容**: 部署日誌、驗證結果
---
常見問題
### Q: 如果某個階段的產出不滿意怎麼辦?
A: 使用 `/vibe-kanban back "原因"` 退回到上一階段重新處理。
### Q: 可以跳過某些階段嗎?
A: 使用 `/vibe-kanban skip`,但需要確認跳過的原因和風險。
### Q: 如何查看歷史記錄?
A: 查看 `.gstack/kanban/{project}/` 目錄下的 `state.yaml` 檔案。
### Q: 多人協作時如何同步狀態?
A: 將 `.gstack/kanban/` 目錄加入版本控制,團隊成員可以共享狀態。
---
## 最佳實踐
1. **每個階段都應該產出文件** - 確保可追溯性
2. **及時退回修改** - 發現問題立即退回,不要累積技術債
3. **QA 前確保驗收標準完整** - 測試案例來自驗收標準
4. **部署前確認所有測試通過** - 自動化測試是門檻
5. **保存所有產出文件** - 方便日後參考和審計
---
## 故障排除
### 問題: 狀態檔案損壞
```bash
# 重置狀態檔案
rm .gstack/kanban/{project}/state.yaml
/vibe-kanban start "{project-name}"
```
### 問題: 階段卡住無法前進
```bash
# 強制前往下一階段
/vibe-kanban next --force
```
### 問題: 需要回到特定階段
```bash
# 跳轉到特定階段
/vibe-kanban goto PRD
```
---
## 下一步
1. 查看 [VIBE_KANBAN_PLAN.md](VIBE_KANBAN_PLAN.md) 了解詳細設計
2. 查看 [IMPLEMENTATION_CHECKLIST.md](IMPLEMENTATION_CHECKLIST.md) 了解實施步驟
3. 開始使用 `/vibe-kanban start "您的功能名稱"`

View File

@ -0,0 +1,500 @@
# 技能依賴圖
本文件描述 Vibe-Kanban 工作流程中各技能之間的依賴關係。
---
## 依賴圖總覽
```
┌─────────────────────────────────────────────────────────────────────────┐
│ 技能依賴關係圖 │
└─────────────────────────────────────────────────────────────────────────┘
┌──────────────┐
│ 使用者 │
│ 輸入想法 │
└──────┬───────┘
┌────────────────────────────────┐
│ │
│ vibe-kanban (主控) │
│ │
└────────────────┬───────────────┘
┌───────────────────────────┼───────────────────────────┐
│ │ │
▼ ▼ ▼
┌─────────────────┐ ┌─────────────────────────┐ ┌─────────────────┐
│ brainstorming │ │ plan-ceo-review │ │ pm-prd │
│ │ │ (現有技能) │ │ (新建技能) │
│ (現有技能) │ │ │ │ │
└────────┬────────┘ └────────────┬────────────┘ └────────┬────────┘
│ │ │
└─────────────┬─────────────┘ │
│ │
▼ │
┌─────────────────┐ │
│ ceo-review │◀──────────────────────────────┘
│ output │
└────────┬────────┘│
┌────────────────────────────┐
│ │
│be-api-design (新建技能) │
│ │
└─────────────┬──────────────┘│
┌────────────────────────────┐
│ │
│ dba-schema (新建技能) │
│ │
└─────────────┬──────────────┘
┌────────────────────────────┐
│ │
│ ux-prototype (新建技能) │
│ │
└─────────────┬──────────────┘
┌────────────────────────────┐
│ │
│ design-review (現有技能) │
│ │
└─────────────┬──────────────┘
│ 失敗退回 PRD
┌─────────────────────────────────────────┐
│ │
│ dispatching-parallel-agents (現有技能) │
│ │
└────────────────┬────────────────────────┘│
┌──────────────┐
│ │
│ 前端實作 │
│ │
└──────┬───────┘
│ ┌──────────────┐
│ │ │
└───────▶│ 後端實作 │
│ │
└──────┬───────┘
┌────────────────────────────────┐
│ │
│ qa (現有技能) │
│ │
└─────────────┬──────────────────┘
│ 失敗退回 Task Breakdown
┌────────────────────────────────┐
│ │
│ review (現有技能) │
│ │
└─────────────┬──────────────────┘
│ 失敗退回 Task Breakdown
┌────────────────────────────────┐
│ │
│ land-and-deploy (現有技能) │
│ │
└────────────────┬───────────────┘
┌──────────┐
│ │
│ 完成 │
│ │
└──────────┘
```
---
## 技能分類
### 現有技能 (可直接使用)
| 技能名稱 | 位置 | 用途 |
|---------|------|------|
| `brainstorming` | skills/ | PM 需求探索 |
| `plan-ceo-review` | gstack/| CEO 商業價值審核 |
| `design-review` | gstack/| 設計審核 |
| `dispatching-parallel-agents` | skills/ | 任務平行拆分 |
| `qa` | gstack/ | QA 測試驗收 |
| `review` | gstack/ | PR 代碼審核 |
| `land-and-deploy` | gstack/ | 部署流程 |
### 新建技能 (需要實作)
| 技能名稱 | 位置 | 用途 |
|---------|------|------|
| `vibe-kanban`| skills/ | 主控協調器 |
| `pm-prd` | skills/ | PRD 撰寫 |
| `be-api-design` | skills/ | API 設計 |
| `dba-schema` | skills/ | 資料庫規劃 |
| `ux-prototype` | skills/ | UX 原型 |
---
## 詳細依賴關係
### Stage 1: Brainstorming
```yaml
技能: brainstorming
類型: 現有
輸入:
- 使用者輸入的想法
- 專案上下文 (CLAUDE.md, README.md 等)
輸出:
- docs/brainstorm/{date}-{feature}.md
依賴: 無
觸發: vibe-kanban (主控)
```
### Stage 2: CEO Review
```yaml
技能: plan-ceo-review
類型: 現有
輸入:
- docs/brainstorm/{date}-{feature}.md
輸出:
- docs/ceo-review/{date}-{feature}.md
- 審核報告
依賴:
- brainstorming (必須完成)
觸發: vibe-kanban (主控)
退回: 可退回 brainstorming
```
### Stage 3: PRD
```yaml
技能: pm-prd
類型: 新建
輸入:
- docs/brainstorm/{date}-{feature}.md
- docs/ceo-review/{date}-{feature}.md
輸出:
- docs/prd/{date}-{feature}.md
依賴:
- brainstorming (必須完成)
- plan-ceo-review (必須通過)
觸發: vibe-kanban (主控)
退回: 可退回 ceo-review
```
### Stage 4: API Design
```yaml
技能: be-api-design
類型: 新建
輸入:
- docs/prd/{date}-{feature}.md
輸出:
- docs/api/{date}-{feature}.yaml
依賴:
- pm-prd (必須完成)
觸發: vibe-kanban (主控)
退回: 可退回 pm-prd
```
### Stage 5: DB Schema
```yaml
技能: dba-schema
類型: 新建
輸入:
- docs/api/{date}-{feature}.yaml
- docs/prd/{date}-{feature}.md
輸出:
- docs/db/{date}-{feature}.sql
- docs/db/migrations/{version}-{description}.sql
依賴:
- be-api-design (必須完成)
觸發: vibe-kanban (主控)
退回: 可退回 be-api-design
```
### Stage 6: UX Prototype
```yaml
技能: ux-prototype
類型: 新建
輸入:
- docs/prd/{date}-{feature}.md
- docs/api/{date}-{feature}.yaml
- docs/db/{date}-{feature}.sql
輸出:
- docs/design/{date}-{feature}/user-flow.md
- docs/design/{date}-{feature}/wireframes/
- docs/design/{date}-{feature}/prototype-link.md
依賴:
- dba-schema (必須完成)
觸發: vibe-kanban (主控)
退回: 可退回 dba-schema
```
### Stage 7: Design Review
```yaml
技能: design-review
類型: 現有
輸入:
- docs/design/{date}-{feature}/
輸出:
- docs/design/{date}-{feature}/review-report.md
依賴:
- ux-prototype (必須完成)
觸發: vibe-kanban (主控)
退回: 可退回 pm-prd (設計與需求不符)
```
### Stage 8: Task Breakdown
```yaml
技能: dispatching-parallel-agents-doc
類型: 現有
輸入:
- docs/prd/{date}-{feature}.md
- docs/api/{date}-{feature}.yaml
- docs/design/{date}-{feature}/
輸出:
- .gstack/kanban/{project}/tasks.md
- 任務分配
依賴:
- design-review (必須通過)
觸發: vibe-kanban (主控)
退回: 無
```
### Stage 9: Implementation
```yaml
技能: 無 (手動或使用 writing-plans)
類型: 手動
輸入:
- .gstack/kanban/{project}/tasks.md
輸出:
- 程式碼
- 單元測試
依賴:
- dispatching-parallel-agents-doc (必須完成)
觸發: 開發者手動
退回: 無
```
### Stage 10: QA
```yaml
技能: qa
類型: 現有
輸入:
- 程式碼
- docs/prd/{date}-{feature}.md (驗收標準)
輸出:
- .gstack/qa-reports/qa-report-{date}.md
依賴:
-實作 (必須完成)
觸發: vibe-kanban (主控)
退回: 可退回 dispatching-parallel-agents-doc (步驟四)
```
### Stage 11: PR Review
```yaml
技能: review
類型: 現有
輸入:
- PR (程式碼變更)
輸出:
-PR 審核報告
依賴:
- qa (必須通過)
觸發: vibe-kanban (主控)
退回: 可退回 dispatching-parallel-agents-doc (步驟四)
```
### Stage 12: Deploy
```yaml
技能: land-and-deploy
類型: 現有
輸入:
- 已核准的 PR
輸出:
- .gstack/deploy-reports/deploy-report-{date}.md
依賴:
- review (必須通過)
觸發: vibe-kanban (主控)
退回: 無 (部署失敗可重新部署)
```
---
## 退回路徑總覽
```yaml
退回路徑:
- from: CEO_REVIEW
to: BRAINSTORM
reason: "商業價值不足或需求不清"
- from: PRD
to: CEO_REVIEW
reason: "PRD 與 CEO 審核不符"
- from: API_DESIGN
to: PRD
reason: "API 設計與需求不符"
- from: DB_SCHEMA
to: API_DESIGN
reason: "資料結構與 API 衝突"
- from: UX_PROTOTYPE
to: DB_SCHEMA
reason: "原型與資料結構不符"
- from: DESIGN_REVIEW
to: PRD
reason: "設計與需求不符"
- from: QA
to: TASK_BREAKDOWN
reason: "測試不通過"
- from: PR_REVIEW
to: TASK_BREAKDOWN
reason: "代碼審核不通過"
- from: DEPLOY
to: IMPLEMENTATION
reason: "部署失敗"
```
---
## 檔案流向圖
```
使用者輸入
docs/brainstorm/{date}-{feature}.md
docs/ceo-review/{date}-{feature}.md
docs/prd/{date}-{feature}.md
├──▶ docs/api/{date}-{feature}.yaml
│ │
│ └──▶ docs/db/{date}-{feature}.sql
│ │
│ └──▶ docs/design/{date}-{feature}/
│ │
│ └──▶ docs/design/{date}-{feature}/review-report.md
└──▶ .gstack/kanban/{project}/tasks.md
└──▶ 程式碼
├──▶ .gstack/qa-reports/qa-report-{date}.md
├──▶ PR (代碼變更)
└──▶ .gstack/deploy-reports/deploy-report-{date}.md
```
---
## 版本控制建議
### 應納入版本控制的檔案
```
.gstack/kanban/{project}/state.yaml # 工作流狀態
docs/brainstorm/ # 需求探索文件
docs/prd/ # PRD 文件
docs/api/ # API 規格
docs/db/ # 資料庫設計
docs/design/ # 設計文件
.gstack/qa-reports/ # QA 報告
.gstack/deploy-reports/ # 部署報告
```
### 不應納入版本控制的檔案
```
.gstack/tmp/ # 暫存檔案
node_modules/ # 依賴
*.log # 日誌檔案
```
---
## 授權和稽核
### 每個階段的授權需求
| 階段 | 需要授權 | 授權者 |
|------|---------|--------|
| BRAINSTORM | 否 | - |
| CEO_REVIEW | 是 | CEO/決策者 |
| PRD | 是 | PM |
| API_DESIGN | 是 | 後端負責人 |
| DB_SCHEMA | 是 | DBA |
| UX_PROTOTYPE | 是 | UX 設計師 |
| DESIGN_REVIEW | 是 | 設計審核者 |
| TASK_BREAKDOWN | 否 | - |
| IMPLEMENTATION | 否 | - |
| QA | 否 | - |
| PR_REVIEW | 是 | 代碼審核者 |
| DEPLOY | 否 | - |
---
## 效能考量
### 平行執行機會
```yaml
可平行執行:
- API_DESIGN + DB_SCHEMA (可同時進行)
- 前端實作 + 後端實作 (可同時進行)
不可平行執行:
- BRAINSTORM → CEO_REVIEW (必須順序)
- PRD → API_DESIGN (必須順序)
- QA → PR_REVIEW → DEPLOY (必須順序)
```
### 快取策略
```yaml
可快取:
- 專案上下文 (CLAUDE.md, README.md)
- 現有 API 規格
- 現有資料庫 Schema
不可快取:
- 當前階段的輸出
- 狀態檔案
```

View File

@ -0,0 +1,440 @@
# Vibe-Kanban 工作流程 - 技能整合規劃
**版本**: 3.0
**日期**: 2025-01-15
**狀態**: 實施階段
---
## 執行摘要
本規劃整合多個現有技能,建立完整的軟體開發工作流程。
**總計**: 11 個現有技能 + 5 個新建技能
**Agent**: 8 個核心 Agent + 1 個主控協調器
**階段**: 12 個工作流程階段
---
## 現有技能整合清單
### 核心技能(直接使用)
| Skill | 來源 | 用途 | 整合階段 |
|-------|------|------|---------|
| `brainstorming` | skills | PM 需求探索 | Stage 1 |
| `plan-ceo-review` | gstack | CEO 商業價值審核 | Stage 2 |
| `write-a-prd` | skills | PRD 撰寫(含訪談) | Stage 3 |
| `grill-me` | skills | **深度驗證閘門** | Stage 3.5 |
| `prd-to-plan` | skills | 實作計畫產出 | Stage 8 |
| `design-an-interface` | skills | API 介面設計 | Stage 4 |
| `tdd` | skills | 測試驅動開發 | Stage 9 |
| `qa` | skills | QA 測試驗收 | Stage 10 |
| `review` | gstack | PR 代碼審核 | Stage 11 |
| `land-and-deploy` | gstack | 部署流程 | Stage 12 |
| `cso` | gstack | 安全審核 | Stage 7/11 |
| `codex` | gstack | 多 AI 代碼審核 | Stage 11 |
### 新增技能(需實作)
| Skill | 用途 | 優先級 |
|-------|------|--------|
| `vibe-kanban` | **主控協調器** | P0 |
| `be-api-design` | OpenAPI 規格產出 | P1 |
| `go-backend-dev` | **Golang 後端實作** | P1 |
| `dba-schema` | 資料庫 Schema 設計 | P1 |
| `ux-prototype` | UX 原型設計 | P2 |
---
## Agent 角色定義
| # | Agent | 角色 | 主要技能 |
|---|-------|------|---------|
| 1 | **Orchestrator** | 主控協調器 | `vibe-kanban` |
| 2 | **PM Agent** | 產品經理 | `brainstorming`, `write-a-prd` |
| 3 | **CEO Reviewer** | 商業決策者 | `plan-ceo-review` |
| 4 | **Backend Agent** | Golang 後端工程師 | `be-api-design`, `go-backend-dev`, `design-an-interface`, `tdd` |
| 5 | **DBA Agent** | 資料庫工程師 | `dba-schema` |
| 6 | **UX Agent** | 使用者體驗設計師 | `ux-prototype` |
| 7 | **QA Agent** | 品質保證工程師 | `qa` |
| 8 | **DevOps Agent** | 運維工程師 | `land-and-deploy` |
| 9 | **Design Reviewer** | 設計審核者 | `design-review` |
| 10 | **Security Reviewer** | 安全審核者 | `cso` |
| 11 | **Code Reviewer** | 代碼審核者 | `review`, `codex` |
---
## 完整工作流程(含 Grill-Me 整合)
```
┌─────────────────────────────────────────────────────────────────────────────┐
│ VIBE-KANBAN + GRILL-ME 工作流程 │
└─────────────────────────────────────────────────────────────────────────────┘
Stage 1: Brainstorming (PM Agent)
├── Skill: brainstorming
├── 輸入: 使用者想法
├── 輸出: docs/brainstorm/{date}-{feature}.md
└── 下一步: CEO Review
Stage 2: CEO Review (CEO Reviewer)
├── Skill: plan-ceo-review
├── 輸入: Brainstorm 文件
├── 輸出: docs/ceo-review/{date}-{feature}.md
└── 下一步: PRD 撰寫
Stage 3: PRD 撰寫 (PM Agent)
├── Skill: write-a-prd
├── 輸入: CEO Review 結果
├── 輸出: docs/prd/{date}-{feature}.md (初版)
└── 下一步: 深度驗證 (可選)
Stage 3.5: 深度驗證 ⭐ GRILL-ME 整合點
├── Skill: grill-me
├── 觸發條件: 使用者選擇 "進行深度驗證"
├── 輸入: PRD 初版
├── 驗證項目:
│ ├── 每個功能性需求的完整性
│ ├── 使用者故事的邊界情況
│ ├── 非功能性需求的遺漏
│ ├── 驗收標準的可測試性
│ └── 潛在風險和依賴
├── 輸出: 強化後的 PRD
└── 下一步: API Design
Stage 4: API Design (Backend Agent)
├── Skill: be-api-design + design-an-interface
├── 輸入: PRD
├── 輸出: docs/api/{date}-{feature}.yaml
└── 下一步: DB Schema (平行)
Stage 5: DB Schema (DBA Agent)
├── Skill: dba-schema
├── 輸入: API 規格
├── 輸出: docs/db/{date}-{feature}.sql
└── 下一步: UX Prototype (平行)
Stage 6: UX Prototype (UX Agent)
├── Skill: ux-prototype
├── 輸入: PRD + API + DB
├── 輸出: docs/design/{date}-{feature}/
└── 下一步: Design Review
Stage 7: Design Review (Design Reviewer)
├── Skill: design-review
├── 輸入: 所有設計文件
├── 輸出: docs/design/review-report.md
├── 決策點:
│ ├── ✅ 通過 → Task Breakdown
│ └── ❌ 退回 → PRD 修改
└── 下一步: Task Breakdown
Stage 8: Task Breakdown (Orchestrator)
├── Skill: prd-to-plan
├── 輸入: 所有設計文件
├── 輸出: ./plans/{feature}.md
└── 下一步: 實作 (平行)
Stage 9: Implementation (Backend + Frontend Agents)
├── Backend Skill: go-backend-dev + tdd
├── Frontend Skill: (現有技能或手動)
├── 輸入: 實作計畫
├── 輸出: 程式碼
└── 下一步: QA
Stage 10: QA (QA Agent)
├── Skill: qa
├── 輸入: 程式碼 + 驗收標準
├── 輸出: .gstack/qa-reports/qa-report.md
├── 決策點:
│ ├── ✅ 通過 → PR Review
│ └── ❌ 失敗 → 退回 Task Breakdown
└── 下一步: PR Review
Stage 11: PR Review (Code Reviewer)
├── Skill: review + codex
├── 輸入: PR
├── 輸出: PR 審核報告
├── 決策點:
│ ├── ✅ 通過 → Deploy
│ └── ❌ 失敗 → 退回 Task Breakdown
└── 下一步: Deploy
Stage 12: Deploy (DevOps Agent)
├── Skill: land-and-deploy
├── 輸入: 已核准 PR
├── 輸出: .gstack/deploy-reports/deploy-report.md
└── 🎉 完成
```
---
## Grill-Me 深度驗證詳細設計
### 觸發機制
在每個關鍵階段後Orchestrator 會詢問:
```
╔══════════════════════════════════════════════════════════════╗
║ 🔥 深度驗證機會 ║
╠══════════════════════════════════════════════════════════════╣
║ ║
║ 當前階段: PRD 撰寫 ║
║ 狀態: ✅ 初版已完成 ║
║ ║
║ 是否需要進行深度驗證 (grill-me)
║ 這將透過密集訪談壓力測試計畫的完整性。 ║
║ ║
║ [A] 是 - 進行深度驗證 (推薦用於關鍵功能) ║
║ [B] 否 - 直接進入下一階段 ║
║ ║
╚══════════════════════════════════════════════════════════════╝
```
### 驗證檢查清單
#### Stage 3.5 - PRD 深度驗證
```yaml
驗證項目:
功能性需求:
- "每個 FR 是否有明確的驗收標準?"
- "使用者故事是否覆蓋所有使用者角色?"
- "是否有遺漏的邊界情況?"
非功能性需求:
- "效能需求是否具體可量測?"
- "安全性需求是否完整?"
- "可用性和可靠性是否考量?"
技術可行性:
- "現有技術棧是否支援?"
- "是否有外部依賴風險?"
- "擴展性是否考量?"
業務邏輯:
- "所有業務規則是否明確?"
- "錯誤處理流程是否定義?"
- "狀態轉換是否清晰?"
```
### 整合流程圖
```mermaid
graph TD
A[Stage 3: PRD 初版] --> B{深度驗證?}
B -->|是| C[Stage 3.5: grill-me]
B -->|否| D[Stage 4: API Design]
C --> C1[問題 1: 需求完整性]
C1 --> C2[問題 2: 邊界情況]
C2 --> C3[問題 3: 風險評估]
C3 --> C4[...更多問題]
C4 --> E[強化 PRD]
E --> D
D --> F[後續階段]
```
---
## 各階段交付文件
| 階段 | Agent | 主要技能 | 輔助技能 | 交付文件 |
|------|-------|---------|---------|---------|
| 1 | PM | brainstorming | - | `docs/brainstorm/{date}-{feature}.md` |
| 2 | CEO Reviewer | plan-ceo-review | - | `docs/ceo-review/{date}-{feature}.md` |
| 3 | PM | write-a-prd | - | `docs/prd/{date}-{feature}.md` (初版) |
| 3.5 | PM | **grill-me** | - | `docs/prd/{date}-{feature}.md` (強化版) |
| 4 | Backend | be-api-design | design-an-interface | `docs/api/{date}-{feature}.yaml` |
| 5 | DBA | dba-schema | - | `docs/db/{date}-{feature}.sql` |
| 6 | UX | ux-prototype | - | `docs/design/{date}-{feature}/` |
| 7 | Design Reviewer | design-review | cso | `docs/design/review-report.md` |
| 8 | Orchestrator | prd-to-plan | dispatching-parallel-agents | `./plans/{feature}.md` |
| 9 | Backend | go-backend-dev | tdd | `internal/`, `cmd/`, `pkg/` |
| 10 | QA | qa | - | `.gstack/qa-reports/qa-report.md` |
| 11 | Code Reviewer | review | codex | PR 審核報告 |
| 12 | DevOps | land-and-deploy | - | `.gstack/deploy-reports/deploy-report.md` |
---
## 技能依賴關係
```yaml
技能依賴:
brainstorming:
輸入: 使用者想法
輸出: brainstorm.md
plan-ceo-review:
輸入: brainstorm.md
輸出: ceo-review.md
write-a-prd:
輸入: ceo-review.md
輸出: prd.md (初版)
grill-me: # 可選
輸入: prd.md (初版)
輸出: prd.md (強化版)
依賴: write-a-prd
be-api-design:
輸入: prd.md
輸出: api-spec.yaml
輔助: design-an-interface
dba-schema:
輸入: api-spec.yaml
輸出: schema.sql
ux-prototype:
輸入: prd.md, api-spec.yaml, schema.sql
輸出: design/
design-review:
輸入: design/
輸出: review-report.md
prd-to-plan:
輸入: prd.md, api-spec.yaml, design/
輸出: ./plans/{feature}.md
go-backend-dev:
輸入: ./plans/{feature}.md
輸出: 程式碼
輔助: tdd
qa:
輸入: 程式碼, prd.md (驗收標準)
輸出: qa-report.md
review:
輸入: PR
輸出: pr-review.md
輔助: codex
land-and-deploy:
輸入: pr-review.md (已核准)
輸出: deploy-report.md
```
---
## Golang 後端特定規則go-backend-dev
### 架構風格
```yaml
預設架構: Clean Architecture (適合中型專案)
專案結構:
cmd/api/main.go # 進入點
internal/
domain/ # Entities, Value Objects
usecase/ # Business Logic
interface/
http/ # Handlers
repository/ # Repository interfaces
infrastructure/ # DB, Cache implementations
pkg/
logger/ # Zap
errors/ # 自定義錯誤
validator/ # go-playground/validator
api/openapi.yaml
migrations/
test/
```
### 編碼規範
```yaml
命名:
Package: 小寫單數 (user, not users)
Interface: 方法名 + 'er' (Reader, Writer)
Exported: PascalCase
Internal: camelCase
錯誤處理:
- Always check errors
- Error strings lowercase
- Use fmt.Errorf with %w
API 設計:
RESTful: /api/v1/{resource}
狀態碼: 200, 201, 400, 401, 404, 422, 500
測試:
- Unit tests >= 80% 覆蓋率
- Integration tests for critical paths
- Use testify + mockery
```
---
## 實作優先順序
### Phase 1: 核心框架 (Week 1)
| 優先級 | Skill | 複雜度 | 說明 |
|-------|-------|--------|------|
| P0 | vibe-kanban | 高 | 主控協調器,整合所有技能 |
| P0 | grill-me 整合 | 中 | 設計深度驗證流程 |
### Phase 2: 設計階段技能 (Week 2)
| 優先級 | Skill | 複雜度 | 說明 |
|-------|-------|--------|------|
| P1 | be-api-design | 中 | OpenAPI 規格產出 |
| P1 | go-backend-dev | 高 | **Golang 後端實作** |
| P1 | dba-schema | 中 | 資料庫設計 |
### Phase 3: 整合測試 (Week 3)
- 整合所有現有技能
- 端到端流程測試
- 退回機制測試
### Phase 4: 優化 (Week 4)
- 效能優化
- 文件完善
- 使用指南
---
## 附錄
### A. 技術棧建議
**Golang 後端**:
- 框架: Gin 或 Echo
- ORM: GORM 或 sqlx
- 配置: Viper
- 日誌: Zap
- 驗證: go-playground/validator
- 測試: testify + mockery
- 文件: swag (Swagger)
**資料庫**:
- 主要: PostgreSQL
- 快取: Redis
- 遷移: golang-migrate/migrate
**部署**:
- 容器: Docker
- CI/CD: GitHub Actions
### B. 參考資源
1. [Uber Go Style Guide](https://github.com/uber-go/guide)
2. [golang-standards/project-layout](https://github.com/golang-standards/project-layout)
3. [Go Clean Architecture](https://github.com/bxcodec/go-clean-arch)
4. [A Philosophy of Software Design](https://web.stanford.edu/~ouster/cgi-bin/book.php) (for grill-me 概念)
---
**下一步**: 開始實作 `vibe-kanban` 主控技能?

File diff suppressed because it is too large Load Diff

115
design-idea/struct.md Normal file
View File

@ -0,0 +1,115 @@
.
├── build
│   └── Dockerfile
├── docker-compose.yml
├── etc
│   └── member.example.yaml
├── generate
│   └── protobuf
│   └── member.proto
├── go.mod
├── internal
│   ├── config
│   │   └── config.go
│   ├── logic
│   │   └── account
│   │   ├── bind_account_logic.go
│   │   ├── bind_user_info_logic.go
│   │   ├── bind_verify_email_logic.go
│   │   ├── bind_verify_phone_logic.go
│   │   ├── check_refresh_code_logic.go
│   │   ├── create_user_account_logic.go
│   │   ├── generate_refresh_code_logic.go
│   │   ├── get_u_i_d_by_account_logic.go
│   │   ├── get_user_account_info_logic.go
│   │   ├── get_user_info_logic.go
│   │   ├── line_code_to_access_token_logic.go
│   │   ├── line_get_profile_by_access_token_logic.go
│   │   ├── list_member_logic.go
│   │   ├── update_status_logic.go
│   │   ├── update_user_info_logic.go
│   │   ├── update_user_token_logic.go
│   │   ├── verify_google_auth_result_logic.go
│   │   ├── verify_platform_auth_result_logic.go
│   │   └── verify_refresh_code_logic.go
│   ├── server
│   │   └── account
│   │   └── account_server.go
│   └── svc
│   └── service_context.go
├── Makefile
├── member.go
├── pkg
│   ├── domain
│   │   ├── config
│   │   │   └── config.go
│   │   ├── const.go
│   │   ├── entity
│   │   │   ├── account_uid_table.go
│   │   │   ├── account.go
│   │   │   ├── auto_id.go
│   │   │   └── user.go
│   │   ├── errors.go
│   │   ├── member
│   │   │   ├── account_type_test.go
│   │   │   ├── account_type.go
│   │   │   ├── alert_type_test.go
│   │   │   ├── alert_type.go
│   │   │   ├── generate_code_type_test.go
│   │   │   ├── generate_code_type.go
│   │   │   ├── platform_test.go
│   │   │   ├── platform.go
│   │   │   ├── status_test.go
│   │   │   └── status.go
│   │   ├── redis.go
│   │   ├── repository
│   │   │   ├── account_uid.go
│   │   │   ├── account.go
│   │   │   ├── auto_id.go
│   │   │   ├── user.go
│   │   │   └── verify_code.go
│   │   └── usecase
│   │   ├── account.go
│   │   ├── common.go
│   │   ├── generate_uid.go
│   │   └── verify.go
│   ├── mock
│   │   ├── repository
│   │   │   ├── account_uid.go
│   │   │   ├── account.go
│   │   │   ├── auto_id.go
│   │   │   ├── user.go
│   │   │   └── verify_code.go
│   │   └── usecase
│   │   └── generate_uid.go
│   ├── repository
│   │   ├── account_test.go
│   │   ├── account_uid_test.go
│   │   ├── account_uid.go
│   │   ├── account.go
│   │   ├── auto_id_test.go
│   │   ├── auto_id.go
│   │   ├── error.go
│   │   ├── start_mongo_container_test.go
│   │   ├── user_test.go
│   │   ├── user.go
│   │   ├── verify_code_test.go
│   │   └── verify_code.go
│   └── usecase
│   ├── account.go
│   ├── binding_test.go
│   ├── binding.go
│   ├── generate_test.go
│   ├── generate_verify_code_utils_test.go
│   ├── generate_verify_code_utils.go
│   ├── generate.go
│   ├── member_test.go
│   ├── member.go
│   ├── password_utils_test.go
│   ├── password_utils.go
│   ├── verify_google_test.go
│   ├── verify_google.go
│   ├── verify_line.go
│   ├── verify_test.go
│   └── verify.go
└── readme.md

View File

@ -0,0 +1,109 @@
# Backend Agent (Golang 後端工程師)
## 角色定位
**Golang 後端工程師** — 負責 API 設計、伺服器端實作,確保高品質、可測試的 Golang 程式碼,遵循 Domain-Driven + go-zero 風格架構。
## 核心職責
1. **API 規格** — 根據 PRD 設計 RESTful API產出 OpenAPI 3.0 規格
2. **領域建模** — 定義領域實體、值物件和業務規則,與 PRD 和 DB Schema 對齊
3. **核心實作** — 遵循 Domain-Driven 架構建構伺服器端邏輯pkg/domain 定義 → pkg/usecase 實作 → internal/logic handler → pkg/repository 基礎設施)
4. **品質確保 (TDD)** — 使用測試驅動開發實作功能,確保高覆蓋率和可靠性
5. **跨團隊協作** — 與 DBA Agent 同步 Schema 設計、UX Agent 進行 API 整合、QA Agent 確認可測試性
## 使用技能
| 階段 | 技能 | 輔助 | 輸入 | 輸出 |
|-------|-------|-----------|-------|--------|
| 4: API 設計 | `be-api-design` | `design-an-interface` | PRD | `docs/api/{date}-{feature}.yaml` |
| 5: DB Schema | 與 DBA Agent 協作 | - | API 規格 + 領域模型 | 對齊確認 |
| 8: 任務分解 | 檢視 Orchestrator 計畫 | - | `./plans/{feature}.md` | 可行性確認 |
| 9: 實作 | `go-backend-dev` | `tdd` | 計畫 + API 規格 + DB Schema | 生產級 Go 程式碼 |
| 10: QA 支援 | Bug 修復支援 | - | QA 回報 | Bug 修復 + 回歸測試 |
| 11: Code Review | 回應 PR 回饋 | - | 審查意見 | 程式碼變更 |
## 工作原則
1. **API-First 設計** — 先定義 API 合約OpenAPI再寫實作程式碼
2. **Domain-Driven 架構**`pkg/domain/` 包含純抽象(實體、值物件、介面),`pkg/usecase/` 和 `pkg/repository/` 包含實作,`internal/logic/` 和 `internal/svc/` 處理組裝
3. **測試驅動開發** — 先寫測試Red再實作Green然後重構
4. **垂直切片** — 一次實作一個端到端切片,不要逐層實作
5. **錯誤透明** — 立即檢查每個錯誤;使用 `fmt.Errorf` 搭配 `%w` 包裝
6. **介面隔離** — 保持介面小型1-3 個方法);在消費處定義介面
## 回滾機制
```
設計審查駁回 API 規格 (Stage 7)
→ 修改 OpenAPI 規格技能be-api-design + design-an-interface
→ 如需變更 Schema與 DBA Agent 協調
QA 失敗 (Stage 10)
→ 回滾到 Stage 8任務分解
→ 修復 Bug + 新增回歸測試
→ 重新進入 Stage 10
Code Review 失敗 (Stage 11)
→ 處理 PR 回饋
→ 重新進入 Stage 10 驗證
DBA/UX 衝突
→ 與 DBA Agent 協調:調整領域模型或 API
→ 與 UX Agent 協調:調整 API 回應或請求格式
```
## 與其他 Agent 協作
```
Backend Agent ← PM Agent接收 PRD 和非功能性需求
Backend Agent ←→ DBA Agent對齊 API 資源與資料庫 SchemaStage 5
Backend Agent ←→ UX Agent確保 API 回應符合原型需求Stage 6
Backend Agent ← 設計審查者:接收設計回饋,修改 API 規格Stage 7
Backend Agent ← Orchestrator接收實作計畫Stage 8
Backend Agent → QA Agent提供可測試程式碼和 API 文件Stage 10
Backend Agent ← Code Reviewer實作 PR 審查的回饋Stage 11
```
## 決策權限
- 定義後端內部技術結構(套件、層級)
- 在批准的技術堆疊中選擇特定 Go 函式庫
- 決定 API 端點粒度和資源建模
- 設定內部測試策略單元、整合、E2E 邊界)
- 決定錯誤處理模式和回應格式
## 交付物檢查清單
### Stage 4: API 設計
- [ ] OpenAPI 3.0 規格儲存至 `docs/api/`
- [ ] PRD 所有功能需求映射至端點
- [ ] `design-an-interface` 替代方案已記錄
### Stage 5: DB 協作
- [ ] 領域模型與 DB Schema 對齊
- [ ] Repository 介面在 proposed schema 下可行
### Stage 9: 實作
- [ ] Domain-Driven 架構結構完整pkg/domain, pkg/usecase, internal/logic, pkg/repository
- [ ] 所有層級已實作
- [ ] 單元測試 >= 80%,業務邏輯 >= 90%
- [ ] 關鍵路徑整合測試通過
### Stage 10-11: QA 與 Code Review
- [ ] 所有 QA 回報的 Bug 已修復並有回歸測試
- [ ] PR 審查回饋已處理
## 常見問題處理
**Q: PRD 需求技術上不可行?**
A: 在 API 規格中記錄限制,提出替代方案,上報 PM Agent 調整範圍。
**Q: API 設計與 DB Schema 衝突?**
A: 與 DBA Agent 協調。優先改變映射層而非修改 DB Schema。
**Q: 發現效能瓶頸?**
A: 加入快取Redis與 DBA Agent 優化查詢,考慮對長時操作使用非同步。
**Q: 測試覆蓋率低於 80%**
A: 優先測試 usecase 層,使用表格驅動測試處理邊緣案例,為關鍵流程加入整合測試。

View File

@ -0,0 +1,146 @@
# PM Agent (Product Manager)
## 角色定位
**產品經理** — 負責需求探索、PRD 撰寫和產品規劃。
## 核心職責
1. **需求探索** — 透過訪談了解使用者需求
2. **PRD 撰寫** — 產出結構化的產品需求文件(包含功能與非功能性需求)
3. **使用者故事** — 定義清晰的使用者故事
4. **驗收標準** — 設定可測試的驗收標準
5. **優先排序** — 對功能和需求進行優先排序
## 使用技能
### Stage 1: 腦力激盪
- **技能**: `brainstorming`
- **輸入**: 使用者最初的的想法
- **輸出**: `docs/brainstorm/{date}-{feature}-design.md`
- **內容**:
- 問題陳述
- 目標使用者
- 功能列表
- 技術建議
### Stage 3: PRD 撰寫
- **技能**: `write-a-prd`
- **輸入**: CEO 審查結果
- **輸出**: `docs/prd/{date}-{feature}.md`
- **內容**:
- 問題陳述
- 解決方案
- 使用者故事(詳細列表)
- 實作決策
- 測試決策
- 非功能性需求(效能、安全等)
- 範圍外
### Stage 3.5: 深度驗證 (Grill-Me)
- **技能**: `grill-me`
- **觸發時機**: PRD 初稿完成後主動啟用以確保無遺漏
- **輸入**: PRD 初稿
- **驗證項目**:
- 每個功能需求的完整性
- 使用者故事的邊緣案例
- 非功能性需求的遺漏(重要)
- 驗收標準的可測試性
- **輸出**: 增強後的 PRD
## PRD 模板結構
```markdown
# PRD: {feature_name}
## Metadata
- Date: {date}
- Status: Draft | Review | Approved
- Author: PM Agent
## Problem Statement
{problem_description}
## Solution
{solution}
## User Stories
1. As a {role}, I want {feature}, so that {benefit}
2. ...
## Implementation Decisions
- {technical_decisions}
- {architecture_decisions}
## Testing Decisions
- {testing_strategy}
- {priority_test_items}
## Non-Functional Requirements
### NFR-001: Performance
- Description: (e.g., Response time < 200ms, Supports 100 concurrency)
- Measurement:
### NFR-002: Reliability/Security
- Description:
- Measurement:
## Out of Scope
- {omitted_features}
## Functional Requirements
### FR-001: {requirement_title}
- Description:
- Priority: P0 | P1 | P2
- User Stories:
## Acceptance Criteria
### AC-001: {acceptance_item}
- Given:
- When:
- Then:
- Automated: Yes/No
```
## 工作原則
1. **以使用者為中心** — 所有需求從使用者視角出發
2. **清晰且具體** — 避免模糊描述,致力於可執行性
3. **完整覆蓋** — 考慮正常流程、例外情況和非功能性限制
4. **可測試性** — 每個需求都應有清晰的驗收標準
5. **迭代精煉** — 定稿前必須透過 `grill-me` 進行深度驗證
## 與其他 Agent 協作
```
PM Agent ←→ CEO 審查者:接收審查回饋,調整範圍
PM Agent → Backend Agent提供 PRD 進行 API 設計
PM Agent → UX Agent提供需求進行原型設計
PM Agent → QA Agent提供驗收標準進行測試
```
## 決策權限
- 定義產品功能和範圍
- 設定需求優先順序
- 決定驗收標準
- 建議技術解決方案(非最終決定)
## 交付物檢查清單
- [ ] 腦力激盪文件已完成於 `docs/brainstorm/`
- [ ] PRD 文件已完成於 `docs/prd/`
- [ ] 使用者故事清晰且完整
- [ ] 驗收標準可測試
- [ ] 非功能性需求NFR明確定義且可衡量
- [ ] Grill-me 深度驗證已完成
## 常見問題處理
**Q: 使用者需求不清楚?**
A: 使用腦力激盪技能進行多輪訪談,直到需求清楚。
**Q: 技術可行性存疑?**
A: 在實作決策中標記風險,與 Backend Agent 討論。
**Q: 範圍太大?**
A: 與 CEO 審查者協助拆分為多個階段,定義 MVP。

View File

@ -0,0 +1,532 @@
---
name: be-api-design
description: "Backend Agent 使用此技能設計 API 規格。根據 PRD 產出 OpenAPI 3.0 規格,包含端點、請求/回應結構、錯誤處理。觸發時機PRD 通過後Stage 4。"
---
# /be-api-design — API 設計
Backend Agent 使用此技能設計 API 規格。
## 職責
1. 分析 PRD 中的功能性需求
2. 使用 `design-an-interface` 探索多種 API 設計方案
3. 設計 RESTful API 端點
4. 定義請求/回應 schema
5. 設計錯誤處理機制
6. 產出 OpenAPI 3.0 規格
## 輸入
- PRD 文件 (`docs/prd/{date}-{feature}.md`)
- 現有 API 風格 (專案中現有的 API 規格)
- 資料模型上下文
## 輸出
- API 規格文件: `docs/api/{date}-{feature}.yaml` (OpenAPI 3.0)
## 流程
```
讀取 PRD
識別資源與操作
呼叫 design-an-interface 探索 2-3 種設計方案
選定最佳方案
定義 OpenAPI Schema
設計錯誤處理
安全性審查
產出 OpenAPI 文件
```
### 步驟說明
**1. 讀取 PRD**
從 PRD 中提取所有功能性需求,識別:
- 資源(名詞):使用者、訂單、商品等
- 操作(動詞):建立、讀取、更新、刪除等
- 關係:資源之間的關聯(一對多、多對多)
- 非功能性需求:分頁、速率限制、認證等
**2. 識別資源與操作**
將功能性需求映射為 RESTful 資源:
- 每個名詞 → 潛在資源
- 每個動詞 → HTTP method
- 每個關係 → 巢狀資源或獨立端點
**3. 呼叫 design-an-interface**
使用 `design-an-interface` 技能,產生 2-3 種截然不同的 API 設計方案:
- 方案 A最小化方法數每個資源 1-3 個端點)
- 方案 B最大化彈性支援多種使用情境
- 方案 C最佳化最常見的操作
比較各方案的優劣,選定最佳設計。
**4. 定義 OpenAPI Schema**
使用下方模板產出完整的 OpenAPI 3.0 規格。
**5. 安全性審查**
確認所有端點都有適當的認證機制和權限控制。
**6. 產出文件**
儲存至 `docs/api/{date}-{feature}.yaml`
## 設計原則
### RESTful 設計
```yaml
資源導向:
- URL 代表資源,而非動作
- HTTP 方法代表動作
範例:
GET /api/v1/users # 列出使用者
GET /api/v1/users/{id} # 取得特定使用者
POST /api/v1/users # 建立使用者
PUT /api/v1/users/{id} # 完整更新
PATCH /api/v1/users/{id} # 部分更新
DELETE /api/v1/users/{id} # 刪除使用者
巢狀資源:
GET /api/v1/users/{id}/orders # 取得使用者的訂單
POST /api/v1/users/{id}/orders # 為使用者建立訂單
```
### HTTP 狀態碼
```yaml
成功:
200: OK # GET, PUT, PATCH, DELETE 成功
201: Created # POST 成功建立資源
204: No Content # DELETE 成功,無回應內容
客戶端錯誤:
400: Bad Request # 請求格式錯誤
401: Unauthorized # 未認證
403: Forbidden # 無權限
404: Not Found # 資源不存在
409: Conflict # 資源衝突 (如重複)
422: Unprocessable Entity # 驗證錯誤
429: Too Many Requests # 速率限制
伺服器錯誤:
500: Internal Server Error # 伺服器內部錯誤
502: Bad Gateway # 上游服務錯誤
503: Service Unavailable # 服務暫時不可用
```
### 回應格式
```yaml
成功回應:
type: object
properties:
data:
type: object
meta:
type: object
properties:
page:
type: integer
limit:
type: integer
total:
type: integer
total_pages:
type: integer
錯誤回應:
type: object
properties:
error:
type: object
properties:
code:
type: string
message:
type: string
details:
type: array
items:
type: object
properties:
field:
type: string
message:
type: string
```
## OpenAPI 3.0 模板
```yaml
openapi: 3.0.3
info:
title: {API 名稱}
version: 1.0.0
description: |
{描述}
Related PRD: {PRD 連結}
servers:
- url: https://api.example.com/v1
description: Production
- url: https://staging-api.example.com/v1
description: Staging
paths:
/users:
get:
summary: 列出使用者
tags:
- Users
parameters:
- name: page
in: query
schema:
type: integer
default: 1
- name: limit
in: query
schema:
type: integer
default: 20
maximum: 100
- name: search
in: query
schema:
type: string
responses:
'200':
description: 成功
content:
application/json:
schema:
$ref: '#/components/schemas/UserListResponse'
'401':
$ref: '#/components/responses/Unauthorized'
'500':
$ref: '#/components/responses/InternalError'
post:
summary: 建立使用者
tags:
- Users
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/CreateUserRequest'
responses:
'201':
description: 建立成功
content:
application/json:
schema:
$ref: '#/components/schemas/UserResponse'
'400':
$ref: '#/components/responses/BadRequest'
'422':
$ref: '#/components/responses/ValidationError'
/users/{id}:
parameters:
- name: id
in: path
required: true
schema:
type: string
get:
summary: 取得使用者
tags:
- Users
responses:
'200':
description: 成功
content:
application/json:
schema:
$ref: '#/components/schemas/UserResponse'
'404':
$ref: '#/components/responses/NotFound'
put:
summary: 完整更新使用者
tags:
- Users
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/UpdateUserRequest'
responses:
'200':
description: 更新成功
content:
application/json:
schema:
$ref: '#/components/schemas/UserResponse'
'404':
$ref: '#/components/responses/NotFound'
'422':
$ref: '#/components/responses/ValidationError'
patch:
summary: 部分更新使用者
tags:
- Users
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/PatchUserRequest'
responses:
'200':
description: 更新成功
content:
application/json:
schema:
$ref: '#/components/schemas/UserResponse'
'404':
$ref: '#/components/responses/NotFound'
delete:
summary: 刪除使用者
tags:
- Users
responses:
'204':
description: 刪除成功
'404':
$ref: '#/components/responses/NotFound'
components:
schemas:
User:
type: object
properties:
id:
type: string
example: "usr_123456"
email:
type: string
format: email
example: "user@example.com"
name:
type: string
example: "John Doe"
status:
type: string
enum: [active, inactive, suspended]
example: "active"
created_at:
type: string
format: date-time
updated_at:
type: string
format: date-time
required:
- id
- email
- name
- status
- created_at
- updated_at
CreateUserRequest:
type: object
properties:
email:
type: string
format: email
password:
type: string
minLength: 8
name:
type: string
minLength: 1
maxLength: 100
required:
- email
- password
- name
UpdateUserRequest:
type: object
properties:
email:
type: string
format: email
name:
type: string
minLength: 1
maxLength: 100
status:
type: string
enum: [active, inactive]
PatchUserRequest:
type: object
properties:
name:
type: string
minLength: 1
maxLength: 100
status:
type: string
enum: [active, inactive]
UserResponse:
type: object
properties:
data:
$ref: '#/components/schemas/User'
UserListResponse:
type: object
properties:
data:
type: array
items:
$ref: '#/components/schemas/User'
meta:
type: object
properties:
page:
type: integer
limit:
type: integer
total:
type: integer
total_pages:
type: integer
Error:
type: object
properties:
error:
type: object
properties:
code:
type: string
message:
type: string
details:
type: array
items:
type: object
properties:
field:
type: string
message:
type: string
responses:
BadRequest:
description: 請求格式錯誤
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
Unauthorized:
description: 未認證
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
NotFound:
description: 資源不存在
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
ValidationError:
description: 驗證錯誤
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
InternalError:
description: 伺服器內部錯誤
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
securitySchemes:
bearerAuth:
type: http
scheme: bearer
bearerFormat: JWT
security:
- bearerAuth: []
```
## 設計檢查清單
### 安全性
- [ ] 所有端點都有適當的認證機制
- [ ] 輸入驗證完整
- [ ] 速率限制設計
- [ ] CORS 配置
### 效能
- [ ] 分頁支援
- [ ] 快取策略
- [ ] 批次操作支援
### 可靠性
- [ ] 錯誤回應格式統一
- [ ] 重試機制建議
- [ ] 冪等性設計
### 一致性
- [ ] 命名規範一致 (資源用名詞複數)
- [ ] 回應格式一致 (data/meta/error 結構)
- [ ] 篩選/排序/分頁參數一致
## 相依技能
- **前置**: `write-a-prd` (PRD 通過後)
- **輔助**: `design-an-interface` (探索多種設計方案)
- **後續**: `dba-schema` (DB Schema 設計)
- **退回**: 可退回 `write-a-prd` 修改需求
## 退回機制
```
Design Review 退回 API 設計
修改 OpenAPI 規格
重新提交 (或重新呼叫 design-an-interface)
DBA Agent 發現 Schema 衝突
協商調整 domain model 或 API 回應格式
更新 OpenAPI 規格
```

View File

@ -0,0 +1,188 @@
---
name: design-an-interface
description: "Backend Agent 使用此技能探索多種 API 介面設計方案。根據「Design It Twice」原則產生多種截然不同的設計比較後選擇最佳方案。觸發時機API 設計階段Stage 4由 be-api-design 技能呼叫。"
---
# /design-an-interface — 介面設計探索
Backend Agent 使用此技能探索 API 介面設計方案。
基於 "A Philosophy of Software Design" 的 "Design It Twice" 原則:第一個想法通常不是最好的。產生多種截然不同的設計,然後比較選擇。
## 職責
1. 針對模組需求,產生 2-3 種截然不同的介面設計方案
2. 每種方案使用不同的設計約束
3. 比較方案的優劣
4. 協助選擇或合成最佳方案
## 輸入
- 模組描述(來自 PRD 的功能性需求)
- 使用者故事和操作場景
## 輸出
- 多種介面設計方案(含介面簽名、使用範例、優劣分析)
- 方案比較和建議
## 流程
```
收集需求
產生 2-3 種設計方案(平行子代理)
呈現各方案
比較方案(介面簡潔性、通用性、實作效率、深度)
合成最佳方案或選擇最適方案
```
### 步驟說明
**1. 收集需求**
在設計之前,先了解:
- [ ] 這個模組解決什麼問題?
- [ ] 誰是呼叫者?(其他模組、外部使用者、測試)
- [ ] 關鍵操作有哪些?
- [ ] 有什麼限制?(效能、相容性、現有模式)
- [ ] 什麼應該隱藏在內部?什麼應該暴露在外?
提問:「這個模組需要做什麼?誰會使用它?」
**2. 產生設計方案(平行子代理)**
同時產生 3+ 種截然不同的方案。每個方案必須遵循不同的約束:
```
方案 A最小化方法數 — 目標 1-3 個方法
方案 B最大化彈性 — 支援多種使用情境
方案 C最佳化最常見操作
方案 D可選參考特定範式或框架的設計
```
每個方案需包含:
1. 介面簽名types / methods
2. 使用範例(呼叫者如何使用)
3. 這個設計隱藏了什麼複雜度
4. 這個方案的取捨
**3. 呈現方案**
逐一展示每個方案,包含:
- 介面簽名types, methods, params
- 使用範例:呼叫者如何實際使用
- 隱藏的複雜度小介面隱藏大量實作vs 大介面薄實作(差)
讓使用者充分吸收每個方案後再進行比較。
**4. 比較方案**
依以下維度比較:
- **介面簡潔性**:方法少、參數簡單 → 更容易學習和正確使用
- **通用性 vs 專用性**:彈性 vs 專注,取捨在哪
- **實作效率**:介面形狀是否允許高效內部實作?
- **深度**小介面隱藏大量複雜度深模組vs 大介面薄實作(淺模組,差)
- **正確使用的容易度 vs 誤用的容易度**
用文字討論取捨,不要只用表格。強調方案分歧最大的地方。
**5. 合成最佳方案**
最佳設計往往結合多個方案的洞見。詢問:
- 「哪個方案最適合你的主要使用情境?」
- 「其他方案有沒有值得納入的元素?」
## 評估標準
來自 "A Philosophy of Software Design"
**介面簡潔性**:方法少、參數簡單 = 更容易學習和正確使用。
**通用性**:能否處理未來的使用情境而不需要修改。但要避免過度通用。
**實作效率**:介面形狀是否允許高效實作?還是迫使內部實作變得彆扭?
**深度**:小介面隱藏大量複雜度 = 深模組(好)。大介面薄實作 = 淺模組(避免)。
```
深模組(好):
┌─────────────────────┐
│ Small Interface │ ← 方法少,參數簡單
├─────────────────────┤
│ │
│ │
│ Deep Implementation│ ← 複雜邏輯隱藏在內部
│ │
│ │
└─────────────────────┘
淺模組(避免):
┌─────────────────────────────────┐
│ Large Interface │ ← 方法多,參數複雜
├─────────────────────────────────┤
│ Thin Implementation │ ← 只是穿隧
└─────────────────────────────────┘
```
## 反模式
- 不要讓子代理產生相似的設計 — 強制截然不同
- 不要跳過比較 — 價值在於對比
- 不要在此階段實作 — 這純粹是介面設計
- 不要基於實作工作量評價方案 — 只看介面品質
## Golang 介面設計範例
```go
// 方案 A: 最小化方法數
type UserRepository interface {
GetByID(ctx context.Context, id string) (*domain.User, error)
Save(ctx context.Context, user *domain.User) error
}
// 優點:簡潔,容易實作 mock
// 缺點Save 同時處理 Create 和 Update取決於是否已存在
// 方案 B: 分離讀寫
type UserReader interface {
GetByID(ctx context.Context, id string) (*domain.User, error)
List(ctx context.Context, page, limit int) ([]*domain.User, error)
}
type UserWriter interface {
Create(ctx context.Context, user *domain.User) error
Update(ctx context.Context, user *domain.User) error
Delete(ctx context.Context, id string) error
}
// 優點CQRS 友好,職責分離
// 缺點:方法數較多,但每個方法語意更清楚
// 方案 C: 最佳化常見操作
type UserService interface {
Register(ctx context.Context, email, password, name string) (*domain.User, error)
Authenticate(ctx context.Context, email, password string) (*domain.User, error)
GetProfile(ctx context.Context, id string) (*domain.User, error)
}
// 優點:直接對應業務操作,使用最直覺
// 缺點:每個新操作都要加方法,彈性較低
```
## 與 be-api-design 的整合
此技能由 `be-api-design` 在步驟 3 自動呼叫。API 設計流程:
```
be-api-design 步驟 1: 讀取 PRD
be-api-design 步驟 2: 識別資源與操作
→ design-an-interface: 探索 2-3 種 API 設計方案
be-api-design 步驟 4: 選定方案,定義 OpenAPI 規格
```
## 相依技能
- **前置**: `write-a-prd` (PRD 完成)
- **後續**: `be-api-design` (API 規格定義)

View File

@ -0,0 +1,15 @@
# 抽象工厂模式
## 描述
提供一个创建相关或依赖对象的接口,而无需指定它们具体的类。
## 使用场景
当你需要解决代码中关于该模式所描述的设计问题时,请加载此技能。
## 指导原则
1. 分析当前代码结构是否符合该模式的意图。
2. 遵循该模式的典型结构进行重构或实现。
3. 确保模式的引入降低了耦合度或提高了灵活性。
## 详细参考
更多详细信息、图解及代码示例请参考:[抽象工厂模式 - RefactoringGuru](https://refactoringguru.cn/design-patterns/abstract-factory)

View File

@ -0,0 +1,15 @@
# 适配器模式
## 描述
在两个不兼容的接口之间起到桥梁作用。
## 使用场景
当你需要解决代码中关于该模式所描述的设计问题时,请加载此技能。
## 指导原则
1. 分析当前代码结构是否符合该模式的意图。
2. 遵循该模式的典型结构进行重构或实现。
3. 确保模式的引入降低了耦合度或提高了灵活性。
## 详细参考
更多详细信息、图解及代码示例请参考:[适配器模式 - RefactoringGuru](https://refactoringguru.cn/design-patterns/adapter)

View File

@ -0,0 +1,15 @@
# 桥接模式
## 描述
将抽象部分与实现部分分离,使它们可以独立变化。
## 使用场景
当你需要解决代码中关于该模式所描述的设计问题时,请加载此技能。
## 指导原则
1. 分析当前代码结构是否符合该模式的意图。
2. 遵循该模式的典型结构进行重构或实现。
3. 确保模式的引入降低了耦合度或提高了灵活性。
## 详细参考
更多详细信息、图解及代码示例请参考:[桥接模式 - RefactoringGuru](https://refactoringguru.cn/design-patterns/bridge)

View File

@ -0,0 +1,15 @@
# 生成器模式
## 描述
将复杂对象的构建与其表示分离,使得同样的构建过程可以创建不同的表示。
## 使用场景
当你需要解决代码中关于该模式所描述的设计问题时,请加载此技能。
## 指导原则
1. 分析当前代码结构是否符合该模式的意图。
2. 遵循该模式的典型结构进行重构或实现。
3. 确保模式的引入降低了耦合度或提高了灵活性。
## 详细参考
更多详细信息、图解及代码示例请参考:[生成器模式 - RefactoringGuru](https://refactoringguru.cn/design-patterns/builder)

View File

@ -0,0 +1,15 @@
# 责任链模式
## 描述
使多个对象可以处理同一个请求。
## 使用场景
当你需要解决代码中关于该模式所描述的设计问题时,请加载此技能。
## 指导原则
1. 分析当前代码结构是否符合该模式的意图。
2. 遵循该模式的典型结构进行重构或实现。
3. 确保模式的引入降低了耦合度或提高了灵活性。
## 详细参考
更多详细信息、图解及代码示例请参考:[责任链模式 - RefactoringGuru](https://refactoringguru.cn/design-patterns/chain-of-responsibility)

View File

@ -0,0 +1,15 @@
# 命令模式
## 描述
将一个请求封装为一个对象,从而可以用不同的请求对客户进行参数化。
## 使用场景
当你需要解决代码中关于该模式所描述的设计问题时,请加载此技能。
## 指导原则
1. 分析当前代码结构是否符合该模式的意图。
2. 遵循该模式的典型结构进行重构或实现。
3. 确保模式的引入降低了耦合度或提高了灵活性。
## 详细参考
更多详细信息、图解及代码示例请参考:[命令模式 - RefactoringGuru](https://refactoringguru.cn/design-patterns/command)

View File

@ -0,0 +1,15 @@
# 组合模式
## 描述
将对象组合成树形结构以表示"部分-整体"层次结构。
## 使用场景
当你需要解决代码中关于该模式所描述的设计问题时,请加载此技能。
## 指导原则
1. 分析当前代码结构是否符合该模式的意图。
2. 遵循该模式的典型结构进行重构或实现。
3. 确保模式的引入降低了耦合度或提高了灵活性。
## 详细参考
更多详细信息、图解及代码示例请参考:[组合模式 - RefactoringGuru](https://refactoringguru.cn/design-patterns/composite)

View File

@ -0,0 +1,15 @@
# 装饰模式
## 描述
动态地给一个对象添加一些额外的职责。
## 使用场景
当你需要解决代码中关于该模式所描述的设计问题时,请加载此技能。
## 指导原则
1. 分析当前代码结构是否符合该模式的意图。
2. 遵循该模式的典型结构进行重构或实现。
3. 确保模式的引入降低了耦合度或提高了灵活性。
## 详细参考
更多详细信息、图解及代码示例请参考:[装饰模式 - RefactoringGuru](https://refactoringguru.cn/design-patterns/decorator)

View File

@ -0,0 +1,15 @@
# 外观模式
## 描述
提供一个统一的界面,以隐藏复杂子系统的实现细节。
## 使用场景
当你需要解决代码中关于该模式所描述的设计问题时,请加载此技能。
## 指导原则
1. 分析当前代码结构是否符合该模式的意图。
2. 遵循该模式的典型结构进行重构或实现。
3. 确保模式的引入降低了耦合度或提高了灵活性。
## 详细参考
更多详细信息、图解及代码示例请参考:[外观模式 - RefactoringGuru](https://refactoringguru.cn/design-patterns/facade)

View File

@ -0,0 +1,15 @@
# 工厂方法模式
## 描述
定义一个创建对象的接口,但让子类决定实例化哪个类。
## 使用场景
当你需要解决代码中关于该模式所描述的设计问题时,请加载此技能。
## 指导原则
1. 分析当前代码结构是否符合该模式的意图。
2. 遵循该模式的典型结构进行重构或实现。
3. 确保模式的引入降低了耦合度或提高了灵活性。
## 详细参考
更多详细信息、图解及代码示例请参考:[工厂方法模式 - RefactoringGuru](https://refactoringguru.cn/design-patterns/factory-method)

View File

@ -0,0 +1,15 @@
# 享元模式
## 描述
通过共享公共部分来支持大量细粒度对象的高效创建和使用。
## 使用场景
当你需要解决代码中关于该模式所描述的设计问题时,请加载此技能。
## 指导原则
1. 分析当前代码结构是否符合该模式的意图。
2. 遵循该模式的典型结构进行重构或实现。
3. 确保模式的引入降低了耦合度或提高了灵活性。
## 详细参考
更多详细信息、图解及代码示例请参考:[享元模式 - RefactoringGuru](https://refactoringguru.cn/design-patterns/flyweight)

View File

@ -0,0 +1,15 @@
# 迭代器模式
## 描述
提供一种方法顺序访问一个聚合对象中的元素,而无需公开其内部表示。
## 使用场景
当你需要解决代码中关于该模式所描述的设计问题时,请加载此技能。
## 指导原则
1. 分析当前代码结构是否符合该模式的意图。
2. 遵循该模式的典型结构进行重构或实现。
3. 确保模式的引入降低了耦合度或提高了灵活性。
## 详细参考
更多详细信息、图解及代码示例请参考:[迭代器模式 - RefactoringGuru](https://refactoringguru.cn/design-patterns/iterator)

View File

@ -0,0 +1,15 @@
# 中介者模式
## 描述
用一个中介对象来封装一系列类的交互。
## 使用场景
当你需要解决代码中关于该模式所描述的设计问题时,请加载此技能。
## 指导原则
1. 分析当前代码结构是否符合该模式的意图。
2. 遵循该模式的典型结构进行重构或实现。
3. 确保模式的引入降低了耦合度或提高了灵活性。
## 详细参考
更多详细信息、图解及代码示例请参考:[中介者模式 - RefactoringGuru](https://refactoringguru.cn/design-patterns/mediator)

View File

@ -0,0 +1,15 @@
# 备忘录模式
## 描述
在不破坏封装性的前提下,捕获一个对象的内部状态,以便该对象可以在以后恢复到原先状态。
## 使用场景
当你需要解决代码中关于该模式所描述的设计问题时,请加载此技能。
## 指导原则
1. 分析当前代码结构是否符合该模式的意图。
2. 遵循该模式的典型结构进行重构或实现。
3. 确保模式的引入降低了耦合度或提高了灵活性。
## 详细参考
更多详细信息、图解及代码示例请参考:[备忘录模式 - RefactoringGuru](https://refactoringguru.cn/design-patterns/memento)

View File

@ -0,0 +1,15 @@
# 观察者模式
## 描述
定义一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并自动更新。
## 使用场景
当你需要解决代码中关于该模式所描述的设计问题时,请加载此技能。
## 指导原则
1. 分析当前代码结构是否符合该模式的意图。
2. 遵循该模式的典型结构进行重构或实现。
3. 确保模式的引入降低了耦合度或提高了灵活性。
## 详细参考
更多详细信息、图解及代码示例请参考:[观察者模式 - RefactoringGuru](https://refactoringguru.cn/design-patterns/observer)

View File

@ -0,0 +1,15 @@
# 原型模式
## 描述
使用一个原型实例来创建其他实例。
## 使用场景
当你需要解决代码中关于该模式所描述的设计问题时,请加载此技能。
## 指导原则
1. 分析当前代码结构是否符合该模式的意图。
2. 遵循该模式的典型结构进行重构或实现。
3. 确保模式的引入降低了耦合度或提高了灵活性。
## 详细参考
更多详细信息、图解及代码示例请参考:[原型模式 - RefactoringGuru](https://refactoringguru.cn/design-patterns/prototype)

View File

@ -0,0 +1,15 @@
# 代理模式
## 描述
为其他对象提供一个代理以控制对这个对象的访问。
## 使用场景
当你需要解决代码中关于该模式所描述的设计问题时,请加载此技能。
## 指导原则
1. 分析当前代码结构是否符合该模式的意图。
2. 遵循该模式的典型结构进行重构或实现。
3. 确保模式的引入降低了耦合度或提高了灵活性。
## 详细参考
更多详细信息、图解及代码示例请参考:[代理模式 - RefactoringGuru](https://refactoringguru.cn/design-patterns/proxy)

View File

@ -0,0 +1,15 @@
# 单例模式
## 描述
确保一个类只有一个实例,并提供一个全局访问点。
## 使用场景
当你需要解决代码中关于该模式所描述的设计问题时,请加载此技能。
## 指导原则
1. 分析当前代码结构是否符合该模式的意图。
2. 遵循该模式的典型结构进行重构或实现。
3. 确保模式的引入降低了耦合度或提高了灵活性。
## 详细参考
更多详细信息、图解及代码示例请参考:[单例模式 - RefactoringGuru](https://refactoringguru.cn/design-patterns/singleton)

View File

@ -0,0 +1,15 @@
# 状态模式
## 描述
允许一个对象在内部状态改变时改变它的行为。
## 使用场景
当你需要解决代码中关于该模式所描述的设计问题时,请加载此技能。
## 指导原则
1. 分析当前代码结构是否符合该模式的意图。
2. 遵循该模式的典型结构进行重构或实现。
3. 确保模式的引入降低了耦合度或提高了灵活性。
## 详细参考
更多详细信息、图解及代码示例请参考:[状态模式 - RefactoringGuru](https://refactoringguru.cn/design-patterns/state)

View File

@ -0,0 +1,15 @@
# 策略模式
## 描述
定义一系列算法,把它们一个个封装起来,并且使它们可以相互替换。
## 使用场景
当你需要解决代码中关于该模式所描述的设计问题时,请加载此技能。
## 指导原则
1. 分析当前代码结构是否符合该模式的意图。
2. 遵循该模式的典型结构进行重构或实现。
3. 确保模式的引入降低了耦合度或提高了灵活性。
## 详细参考
更多详细信息、图解及代码示例请参考:[策略模式 - RefactoringGuru](https://refactoringguru.cn/design-patterns/strategy)

View File

@ -0,0 +1,15 @@
# 模板方法模式
## 描述
定义一个操作的骨架,而将一些步骤延迟到子类中。
## 使用场景
当你需要解决代码中关于该模式所描述的设计问题时,请加载此技能。
## 指导原则
1. 分析当前代码结构是否符合该模式的意图。
2. 遵循该模式的典型结构进行重构或实现。
3. 确保模式的引入降低了耦合度或提高了灵活性。
## 详细参考
更多详细信息、图解及代码示例请参考:[模板方法模式 - RefactoringGuru](https://refactoringguru.cn/design-patterns/template-method)

View File

@ -0,0 +1,15 @@
# 访问者模式
## 描述
在不改变元素类的前提下,定义作用于这些元素的新操作。
## 使用场景
当你需要解决代码中关于该模式所描述的设计问题时,请加载此技能。
## 指导原则
1. 分析当前代码结构是否符合该模式的意图。
2. 遵循该模式的典型结构进行重构或实现。
3. 确保模式的引入降低了耦合度或提高了灵活性。
## 详细参考
更多详细信息、图解及代码示例请参考:[访问者模式 - RefactoringGuru](https://refactoringguru.cn/design-patterns/visitor)

View File

@ -0,0 +1,813 @@
---
name: go-backend-dev
description: "Backend Agent 使用此技能實作 Golang 後端。根據實作計畫和 API 規格,使用 Domain-Driven + go-zero 風格架構和 TDD 流程產出 production-ready 程式碼。觸發時機Task Breakdown 完成後Stage 9。"
---
# /go-backend-dev — Golang 後端實作
Backend Agent 使用此技能實作 Golang 後端。
## 職責
1. 根據實作計畫建立專案結構Domain-Driven + go-zero 風格)
2. 使用 TDD 流程實作功能Red-Green-Refactor
3. 按垂直切片逐步交付(端到端,非逐層)
4. 實作 Domain / Usecase / Logic / Repository 各層
5. 撰寫單元測試和整合測試
## 輸入
- 實作計畫 (`./plans/{feature}.md`)
- API 規格 (`docs/api/{date}-{feature}.yaml`)
- DB Schema (`docs/db/{date}-{feature}.sql`)
## 輸出
- Golang 程式碼結構
- 測試程式碼(單元測試 >= 80%,業務邏輯 >= 90%
- Protobuf 定義(如需 gRPC
## 流程
```
讀取實作計畫 + API 規格 + DB Schema
識別垂直切片(每個切片 = 端到端功能)
對每個切片執行 TDD 循環:
├── RED: 寫測試 → 測試失敗
├── GREEN: 寫最少程式碼 → 測試通過
└── REFACTOR: 重構 → 測試仍然通過
切片內建構順序:
domain (entity/value object/interface)
→ pkg/domain/usecase (介面)
→ pkg/domain/repository (介面)
→ pkg/usecase (實作)
→ pkg/mock (mock)
→ internal/logic (handler 邏輯)
→ pkg/repository (基礎設施實作)
所有切片完成 → 執行整合測試
確認交付物檢查清單
```
### 步驟說明
**1. 讀取輸入**
同時閱讀三個文件:
- 實作計畫:了解垂直切片分解和優先順序
- API 規格:了解端點、請求/回應結構
- DB Schema了解資料表結構和關係
**2. 識別垂直切片**
不是水平切片(一層一層做),而是垂直切片(端到端):
```
✅ 正確方式(垂直):
切片 1: 使用者註冊 (domain.entity + domain.usecase介面 + usecase實作 + logic + repository)
切片 2: 使用者登入 (同上)
切片 3: 使用者列表 (同上)
❌ 錯誤方式(水平):
階段 1: 所有 domain entities
階段 2: 所有 usecases
階段 3: 所有 logic handlers
```
**3. TDD 循環(每個切片)**
對每個切片,遵循 Red-Green-Refactor
```
RED: 寫一個測試 → 測試失敗
GREEN: 寫最少的程式碼讓測試通過 → 測試通過
REFACTOR: 重構程式碼 → 測試仍然通過
```
切片內建構順序(由內而外):
1. `pkg/domain/entity/` — 定義 Entity 和 Value Object
2. `pkg/domain/member/` — 定義值物件和列舉(含測試)
3. `pkg/domain/usecase/` — 定義 Use Case 介面
4. `pkg/domain/repository/` — 定義 Repository 介面
5. `pkg/usecase/` — 實作業務邏輯(先寫測試)
6. `pkg/mock/` — 產生 mock
7. `internal/logic/` — Handler 邏輯
8. `pkg/repository/` — 基礎設施實作(含 DB 測試)
**4. 測試**
每個切片完成後,確保:
- 單元測試通過(`pkg/usecase/*_test.go`
- 值物件測試通過(`pkg/domain/member/*_test.go`
- Repository 測試通過(`pkg/repository/*_test.go`
- 整合測試通過(關鍵路徑)
- 測試覆蓋率達標
**5. 完成驗證**
最後確認所有交付物完整。
## 專案結構
```
project-root/
├── build/
│ └── Dockerfile # 建置映像
├── etc/
│ └── {service}.example.yaml # 範例設定檔
├── generate/
│ └── protobuf/
│ └── {service}.proto # Protobuf 定義(如需 gRPC
├── internal/ # 應用層(不對外暴露)
│ ├── config/
│ │ └── config.go # 應用配置
│ ├── logic/
│ │ └── {module}/
│ │ ├── create_{entity}_logic.go # 每個 use case 一個 logic 檔案
│ │ ├── get_{entity}_logic.go
│ │ ├── update_{entity}_logic.go
│ │ └── ...
│ ├── server/
│ │ └── {module}/
│ │ └── {module}_server.go # Server 定義HTTP/gRPC
│ └── svc/
│ └── service_context.go # 依賴注入容器
├── pkg/ # 領域層(可對外暴露)
│ ├── domain/
│ │ ├── config/
│ │ │ └── config.go # Domain 配置
│ │ ├── entity/
│ │ │ ├── {entity}.go # Entity 定義
│ │ │ ├── {entity}_uid_table.go # UID 對照表
│ │ │ └── auto_id.go # 自動 ID 產生
│ │ ├── {module}/
│ │ │ ├── {value_object}.go # 值物件和列舉
│ │ │ └── {value_object}_test.go # 值物件測試
│ │ ├── repository/
│ │ │ ├── {entity}.go # Repository 介面
│ │ │ └── ...
│ │ ├── usecase/
│ │ │ ├── {module}.go # Use Case 介面
│ │ │ └── ...
│ │ ├── errors.go # Domain sentinel errors
│ │ ├── const.go # Domain 常數
│ │ └── redis.go # Redis domain 定義
│ ├── mock/
│ │ ├── repository/
│ │ │ ├── {entity}.go # Repository mock
│ │ │ └── ...
│ │ └── usecase/
│ │ └── {module}.go # Use Case mock
│ ├── repository/
│ │ ├── {entity}.go # Repository 實作
│ │ ├── {entity}_test.go # Repository 測試
│ │ ├── {entity}_uid.go # UID Repository 實作
│ │ ├── {entity}_uid_test.go
│ │ ├── error.go # Repository 錯誤定義
│ │ └── start_{db}_container_test.go # testcontainers 啟動
│ └── usecase/
│ ├── {module}.go # Use Case 實作
│ ├── {operation}.go # 特定操作
│ ├── {operation}_test.go # Use Case 測試
│ └── {utils}.go # 工具函式
├── {service}.go # 應用程式進入點
├── Makefile
├── go.mod
├── go.sum
├── docker-compose.yml
└── readme.md
```
## 依賴方向規則
```
pkg/domain/ ← 無外部依賴(最內層,純定義)
pkg/domain/usecase/ ← Use Case 介面(只有介面定義)
pkg/domain/repository/ ← Repository 介面(只有介面定義)
pkg/usecase/ ← 依賴 domain 介面(業務邏輯實作)
pkg/mock/ ← 依賴 domain 介面(測試 mock
internal/logic/ ← 依賴 usecase 實作handler 邏輯)
internal/server/ ← 依賴 logicHTTP/gRPC server
internal/svc/ ← 依賴所有DI 容器,組裝依賴)
pkg/repository/ ← 依賴 domain 介面(基礎設施實作)
```
```
┌─────────────────────────────────┐
│ pkg/domain/ │ ← 純定義,無依賴
│ ├── entity/ │
│ ├── {module}/ (value objects)│
│ ├── repository/ (interfaces) │
│ ├── usecase/ (interfaces) │
│ ├── errors.go │
│ └── const.go │
├─────────────────────────────────┤
│ pkg/usecase/ │ ← 依賴 domain 介面
│ pkg/mock/ │ ← 依賴 domain 介面
├─────────────────────────────────┤
│ internal/logic/ │ ← 依賴 usecase
│ internal/server/ │
│ internal/config/ │
│ internal/svc/ │ ← DI 容器
├─────────────────────────────────┤
│ pkg/repository/ │ ← 依賴 domain 介面
└─────────────────────────────────┘
```
## 架構原則
### `pkg/domain/` — 純領域定義
`pkg/domain/` 是核心,只包含**介面和定義**,不包含實作:
```go
// pkg/domain/entity/user.go — Entity 定義
package entity
type User struct {
ID string `json:"id"`
Email string `json:"email"`
Name string `json:"name"`
Status string `json:"status"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
}
```
```go
// pkg/domain/member/status.go — 值物件(含測試)
package member
type Status string
const (
StatusActive Status = "active"
StatusInactive Status = "inactive"
)
func (s Status) IsValid() bool {
switch s {
case StatusActive, StatusInactive:
return true
}
return false
}
func NewStatus(s string) (Status, error) {
status := Status(s)
if !status.IsValid() {
return "", fmt.Errorf("invalid status: %s", s)
}
return status, nil
}
```
```go
// pkg/domain/member/status_test.go — 值物件測試
package member
func TestStatus_IsValid(t *testing.T) {
assert.True(t, StatusActive.IsValid())
assert.True(t, StatusInactive.IsValid())
assert.False(t, Status("unknown").IsValid())
}
func TestNewStatus(t *testing.T) {
status, err := NewStatus("active")
assert.NoError(t, err)
assert.Equal(t, StatusActive, status)
_, err = NewStatus("unknown")
assert.Error(t, err)
}
```
```go
// pkg/domain/repository/user.go — Repository 介面
package repository
type UserRepository interface {
GetByID(ctx context.Context, id string) (*entity.User, error)
GetByEmail(ctx context.Context, email string) (*entity.User, error)
Create(ctx context.Context, user *entity.User) error
Update(ctx context.Context, user *entity.User) error
Delete(ctx context.Context, id string) error
}
```
```go
// pkg/domain/usecase/user.go — Use Case 介面
package usecase
type UserUsecase interface {
CreateUser(ctx context.Context, input CreateUserInput) (*entity.User, error)
GetUser(ctx context.Context, id string) (*entity.User, error)
UpdateUser(ctx context.Context, id string, input UpdateUserInput) (*entity.User, error)
}
```
```go
// pkg/domain/errors.go — Domain sentinel errors
package domain
import "errors"
var (
ErrUserNotFound = errors.New("user not found")
ErrInvalidInput = errors.New("invalid input")
ErrDuplicateEmail = errors.New("email already exists")
)
```
### `pkg/usecase/` — 業務邏輯實作
每個檔案一個功能領域,測試檔案同目錄:
```go
// pkg/usecase/account.go — Use Case 進入點
package usecase
type AccountUsecase struct {
userRepo repository.UserRepository
accountRepo repository.AccountRepository
redis *redis.Client
}
func NewAccountUsecase(
userRepo repository.UserRepository,
accountRepo repository.AccountRepository,
redis *redis.Client,
) *AccountUsecase {
return &AccountUsecase{
userRepo: userRepo,
accountRepo: accountRepo,
redis: redis,
}
}
```
```go
// pkg/usecase/create_user.go — 單一操作
package usecase
func (uc *AccountUsecase) CreateUser(ctx context.Context, input CreateUserInput) (*entity.User, error) {
if err := input.Validate(); err != nil {
return nil, fmt.Errorf("validate input: %w", err)
}
existing, _ := uc.userRepo.GetByEmail(ctx, input.Email)
if existing != nil {
return nil, domain.ErrDuplicateEmail
}
user, err := entity.NewUser(input.Email, input.Password, input.Name)
if err != nil {
return nil, fmt.Errorf("create user: %w", err)
}
if err := uc.userRepo.Create(ctx, user); err != nil {
return nil, fmt.Errorf("save user: %w", err)
}
return user, nil
}
```
```go
// pkg/usecase/create_user_test.go — 測試同目錄
package usecase
func TestAccountUsecase_CreateUser_Success(t *testing.T) {
mockUserRepo := new(mock.UserRepository)
uc := NewAccountUsecase(mockUserRepo, nil, nil)
mockUserRepo.On("GetByEmail", mock.Anything, "test@example.com").Return(nil, nil)
mockUserRepo.On("Create", mock.Anything, mock.AnythingOfType("*entity.User")).Return(nil)
user, err := uc.CreateUser(context.Background(), input)
assert.NoError(t, err)
assert.NotNil(t, user)
mockUserRepo.AssertExpectations(t)
}
```
### `pkg/mock/` — 自動產生的 Mock
```go
// pkg/mock/repository/user.go — 由 mockery 產生
//go:generate mockery --name=UserRepository --output=../../mock/repository --outpkg=mock_repository
package mock_repository
import (
"github.com/stretchr/testify/mock"
"your-project/pkg/domain/repository"
)
type UserRepository struct {
mock.Mock
}
func (m *UserRepository) GetByID(ctx context.Context, id string) (*entity.User, error) {
args := m.Called(ctx, id)
if args.Get(0) == nil {
return nil, args.Error(1)
}
return args.Get(0).(*entity.User), args.Error(1)
}
```
### `internal/logic/` — Handler 邏輯
每個 use case 一個 logic 檔案go-zero 風格):
```go
// internal/logic/account/create_user_logic.go
package account
type CreateUserLogic struct {
ctx context.Context
svcCtx *svc.ServiceContext
}
func NewCreateUserLogic(ctx context.Context, svcCtx *svc.ServiceContext) *CreateUserLogic {
return &CreateUserLogic{
ctx: ctx,
svcCtx: svcCtx,
}
}
func (l *CreateUserLogic) CreateUser(req *types.CreateUserReq) (*types.UserResp, error) {
user, err := l.svcCtx.UserUsecase.CreateUser(l.ctx, usecase.CreateUserInput{
Email: req.Email,
Password: req.Password,
Name: req.Name,
})
if err != nil {
return nil, err
}
return &types.UserResp{
ID: user.ID,
Email: user.Email,
Name: user.Name,
}, nil
}
```
### `internal/svc/` — 依賴注入容器
```go
// internal/svc/service_context.go
package svc
type ServiceContext struct {
Config config.Config
UserUsecase usecase.UserUsecase
AccountUsecase usecase.AccountUsecase
}
func NewServiceContext(c config.Config) *ServiceContext {
db := mongo.NewClient(c.Mongo.URI)
redisClient := redis.NewClient(c.Redis)
userRepo := repository.NewUserRepository(db)
accountRepo := repository.NewAccountRepository(db)
return &ServiceContext{
Config: c,
UserUsecase: usecase.NewUserUsecase(userRepo, redisClient),
AccountUsecase: usecase.NewAccountUsecase(userRepo, accountRepo, redisClient),
}
}
```
### `pkg/repository/` — 基礎設施實作
```go
// pkg/repository/user.go
package repository
type userRepository struct {
db *mongo.Database
}
func NewUserRepository(db *mongo.Database) domain.Repository.UserRepository {
return &userRepository{db: db}
}
func (r *userRepository) GetByID(ctx context.Context, id string) (*entity.User, error) {
var user entity.User
err := r.db.Collection("users").FindOne(ctx, bson.M{"_id": id}).Decode(&user)
if err != nil {
if err == mongo.ErrNoDocuments {
return nil, domain.ErrUserNotFound
}
return nil, fmt.Errorf("find user by id: %w", err)
}
return &user, nil
}
```
```go
// pkg/repository/user_test.go
package repository
func TestUserRepository_GetByID_Success(t *testing.T) {
db := startMongoContainer(t)
defer db.Client().Disconnect(context.Background())
repo := NewUserRepository(db)
// ...
}
```
## 編碼規範
### 檔案命名
```
值物件和列舉: pkg/domain/{module}/{name}.go + _test.go
Entity pkg/domain/entity/{name}.go
Repository 介面pkg/domain/repository/{name}.go
Usecase 介面: pkg/domain/usecase/{module}.go
Usecase 實作: pkg/usecase/{operation}.go + _test.go
Usecase 工具: pkg/usecase/{module}_utils.go + _test.go
Repository 實作pkg/repository/{name}.go + _test.go
Mock pkg/mock/repository/{name}.go
pkg/mock/usecase/{module}.go
Handler 邏輯: internal/logic/{module}/{operation}_logic.go
Server internal/server/{module}/{module}_server.go
Service Contextinternal/svc/service_context.go
Protobuf 定義: generate/protobuf/{module}.proto
設定檔: etc/{service}.yaml
Dockerfile build/Dockerfile
```
### 命名規範
```go
// Package: 小寫,語意明確
package usecase // 不是 usecases
package repository // 不是 repositories
package entity // 不是 entities
// Entity struct: PascalCase無後綴
type User struct { ... } // 不是 UserModel, UserEntity
// Value Object: 基礎型別別名 + 方法
type Status string // 不是 StatusEnum
// Interface (介面): 放在 pkg/domain/ 下,語意命名
type UserRepository interface { ... } // 不是 UserRepo 或 UserRepositoryI
// Use Case struct: {Module}Usecase
type AccountUsecase struct { ... }
// Use Case 方法: 動詞開頭
func (uc *AccountUsecase) CreateUser(ctx context.Context, ...) (*entity.User, error)
func (uc *AccountUsecase) GetUser(ctx context.Context, id string) (*entity.User, error)
// Logic struct: {Operation}Logic
type CreateUserLogic struct { ... }
// Error: Err 前綴
var ErrUserNotFound = errors.New("user not found")
// Constant: PascalCaseexported或 camelCaseinternal
const MaxRetryCount = 3
const defaultPageSize = 20
```
### 錯誤處理
```go
// Sentinel errors — pkg/domain/errors.go
var (
ErrUserNotFound = errors.New("user not found")
ErrInvalidInput = errors.New("invalid input")
ErrDuplicateEmail = errors.New("email already exists")
)
// Error wrapping — always use %w
if err != nil {
return fmt.Errorf("create user: %w", err)
}
// Error checking — always use errors.Is
if errors.Is(err, domain.ErrUserNotFound) {
// handle not found
}
// Repository errors — pkg/repository/error.go
var (
ErrMongoConnection = errors.New("mongo connection failed")
ErrRedisConnection = errors.New("redis connection failed")
)
```
### 介面設計
```go
// 介面定義在 pkg/domain/(消費者端)
// 實作定義在 pkg/ 下(提供者端)
// Accept interfaces, return structs
func NewUserUsecase(repo repository.UserRepository, redis *redis.Client) *UserUsecase {
return &UserUsecase{repo: repo, redis: redis}
}
// Keep interfaces small (1-3 methods)
type UserRepository interface {
GetByID(ctx context.Context, id string) (*entity.User, error)
Create(ctx context.Context, user *entity.User) error
}
```
## TDD 規範
此技能與 `tdd` 技能整合,遵循共同的 TDD 原則。
### 測試金字塔
```
/\
/ \
/ E2E \ <- 少數關鍵流程
/--------\
/Integration\ <- DB + Redis (testcontainers)
/--------------\
/ Unit Tests \ <- 最多80%+ 覆蓋
/--------------------\
```
### 測試位置
```
測試檔案跟原始碼同目錄:
pkg/domain/member/status_test.go ← 值物件測試
pkg/usecase/create_user_test.go ← Use Case 測試
pkg/repository/user_test.go ← Repository 測試
pkg/repository/start_mongo_container_test.go ← testcontainers 啟動
```
### 垂直切片 TDD
每個切片按照以下順序:
```
切片: 使用者註冊
1. RED: 寫 TestStatus_IsValid (值物件)
2. GREEN: 寫 Status.IsValid()
3. RED: 寫 TestAccountUsecase_CreateUser_Success
4. GREEN: 寫 domain/entity, domain/usecase介面, pkg/usecase實作, mock
5. RED: 寫 TestAccountUsecase_CreateUser_DuplicateEmail
6. GREEN: 加入重複檢查
7. RED: 寫 TestUserRepository_Create (DB 測試)
8. GREEN: 寫 pkg/repository/user.go
9. RED: 寫 TestCreateUserLogic (handler 測試)
10. GREEN: 寫 internal/logic/account/create_user_logic.go
11. REFACTOR: 清理全部
```
### Mock 策略
```go
// 使用 mockery 自動產生 mock
// 在接口檔案加上 go:generate 指令
//go:generate mockery --name=UserRepository --output=../../mock/repository --outpkg=mock_repository
// 單元測試使用 mock
func TestAccountUsecase_CreateUser_Success(t *testing.T) {
mockRepo := new(mock_repository.UserRepository)
uc := usecase.NewAccountUsecase(mockRepo, nil, nil)
mockRepo.On("GetByEmail", mock.Anything, "test@example.com").Return(nil, nil)
mockRepo.On("Create", mock.Anything, mock.AnythingOfType("*entity.User")).Return(nil)
user, err := uc.CreateUser(context.Background(), input)
assert.NoError(t, err)
assert.NotNil(t, user)
}
```
### testcontainers 策略
```go
// pkg/repository/start_mongo_container_test.go
func startMongoContainer(t *testing.T) *mongo.Database {
ctx := context.Background()
req := testcontainers.ContainerRequest{
Image: "mongo:7",
ExposedPorts: []string{"27017/tcp"},
WaitingFor: wait.ForListeningPort("27017/tcp"),
}
mongoC, err := testcontainers.GenericContainer(ctx, testcontainers.GenericContainerRequest{
ContainerRequest: req,
Started: true,
})
require.NoError(t, err)
t.Cleanup(func() {
mongoC.Terminate(ctx)
})
// ... return connected database
}
```
### 覆蓋率要求
- 值物件 (`pkg/domain/member/`): >= 90%
- Use Case (`pkg/usecase/`): >= 90%
- Repository (`pkg/repository/`): >= 80%
- Logic (`internal/logic/`): >= 80%(整合測試為主)
- Critical paths: Integration tests required
## 垂直切片模板
每個垂直切片的檔案清單:
```
切片: {operation}_{entity}
新增/修改的檔案:
├── pkg/domain/entity/{entity}.go ← Entity 定義
├── pkg/domain/member/{value_object}.go ← 值物件(如需)
├── pkg/domain/member/{value_object}_test.go ← 值物件測試
├── pkg/domain/repository/{entity}.go ← Repository 介面
├── pkg/domain/usecase/{module}.go ← Use Case 介面
├── pkg/usecase/{operation}.go ← Use Case 實作
├── pkg/usecase/{operation}_test.go ← Use Case 測試
├── pkg/mock/repository/{entity}.go ← Repository mock
├── pkg/repository/{entity}.go ← Repository 實作
├── pkg/repository/{entity}_test.go ← Repository 測試
├── internal/logic/{module}/{operation}_logic.go ← Handler 邏輯
└── internal/svc/service_context.go ← 更新 DI
```
## 完成檢查清單
### 每個切片完成後
- [ ] 值物件測試通過
- [ ] Use Case 測試通過
- [ ] Repository 測試通過(含 DB
- [ ] 錯誤處理完整
- [ ] 依賴方向正確domain 無外部依賴)
### 全部完成後
- [ ] 專案結構符合 Domain-Driven + go-zero 風格
- [ ] `pkg/domain/` 包含所有 Entity、Value Object、介面定義
- [ ] `pkg/usecase/` 包含所有業務邏輯實作
- [ ] `pkg/repository/` 包含所有基礎設施實作
- [ ] `internal/logic/` 包含所有 Handler 邏輯
- [ ] `internal/svc/` 包含完整的依賴注入設定
- [ ] 單元測試 >= 80% 覆蓋率
- [ ] 業務邏輯 >= 90% 覆蓋率
- [ ] 整合測試通過(關鍵路徑)
- [ ] 錯誤處理一致且使用 `%w` wrapping
## 相依技能
- **前置**: `prd-to-plan` (實作計畫), `be-api-design` (API 規格), `dba-schema` (DB Schema)
- **輔助**: `tdd` (TDD Red-Green-Refactor 流程), `design-an-interface` (介面設計)
- **後續**: `qa` (QA 測試)
## 退回機制
```
QA 失敗 (Stage 10)
Orchestrator 重新分配修復任務
Backend Agent 修復 Bug + 新增回歸測試
重新進入 QA (Stage 10)
Code Review 退回 (Stage 11)
處理 PR 回饋
重新進入 QA (Stage 10) 驗證
實作計畫不可行
退回 Task Breakdown (Stage 8) 重新分解
```

View File

@ -0,0 +1,296 @@
---
name: tdd
description: "Backend Agent 使用此技能進行測試驅動開發。遵循 Red-Green-Refactor 循環和垂直切片原則確保測試覆蓋行為而非實作細節。觸發時機實作階段Stage 9由 go-backend-dev 技能整合使用。"
---
# /tdd — 測試驅動開發
Backend Agent 使用此技能進行測試驅動開發。
## 核心理念
**測試行為,而非實作細節。**
好的測試透過公開介面驗證行為,描述系統「做什麼」而非「怎麼做」。重構後測試仍然通過。
壞的測試與實作耦合mock 內部協作者、測試私有方法。重構後測試失敗,但行為沒有改變。
## 反模式:水平切片
**不要先寫完所有測試再寫所有實作。** 這是「水平切片」:
```
❌ 錯誤方式:
RED: test1, test2, test3, test4, test5
GREEN: impl1, impl2, impl3, impl4, impl5
✅ 正確方式(垂直切片):
RED→GREEN: test1 → impl1
RED→GREEN: test2 → impl2
RED→GREEN: test3 → impl3
```
水平切片會產生劣質測試:
- 大量寫的測試驗證「想像的」行為,而非「實際的」行為
- 測試會變成驗證資料結構和函式簽名,而非使用者可觀察的行為
- 測試對真正的變更不敏感 — 行為壞了還是通過,行為沒變但重構後卻失敗
## 流程
```
確認介面變更與測試範圍
寫第一個測試tracer bullet
RED: 測試失敗
GREEN: 寫最少程式碼讓測試通過
寫下一個測試
RED → GREEN 循環
所有行為測試完成
REFACTOR: 重構
確認所有測試仍然通過
```
### 步驟說明
**1. 規劃**
在寫任何程式碼之前:
- [ ] 與使用者確認需要哪些介面變更
- [ ] 確認哪些行為需要測試(排序優先順序)
- [ ] 識別深模組的機會(小介面,深實作)
- [ ] 為可測試性設計介面
- [ ] 列出要測試的行為(不是實作步驟)
- [ ] 取得使用者對測試計畫的認可
提問:「公開介面應該長什麼樣子?哪些行為最重要需要測試?」
**你不可能測試所有東西。** 與使用者確認哪些行為最重要,將測試精力集中在關鍵路徑和複雜邏輯,而不是每個可能的邊緣案例。
**2. Tracer Bullet**
寫一個測試,確認系統的一件事:
```
RED: 寫第一個行為的測試 → 測試失敗
GREEN: 寫最少的程式碼讓測試通過 → 測試通過
```
這是你的 tracer bullet — 證明端到端路徑可行。
**3. 遞增循環**
對每個剩餘行為:
```
RED: 寫下一個測試 → 失敗
GREEN: 最少程式碼讓測試通過 → 通過
```
規則:
- 一次一個測試
- 只寫足夠讓當前測試通過的程式碼
- 不要預測未來的測試
- 測試聚焦在可觀察的行為
**4. 重構**
所有測試通過後,尋找重構候選:
- [ ] 提取重複邏輯
- [ ] 加深模組(將複雜度移到簡單介面後方)
- [ ] 自然地應用 SOLID 原則
- [ ] 思考新程式碼揭示了什麼既有程式碼的問題
- [ ] 每個重構步驟後都跑測試
**絕對不要在 RED 狀態下重構。先回到 GREEN。**
## 好的測試 vs 壞的測試
### 好的測試
**整合風格**:透過真實介面測試,不是 mock 內部零件。
```go
// GOOD: 測試可觀察的行為
func TestUserUsecase_CreateUser_Success(t *testing.T) {
mockRepo := new(mock.UserRepository)
uc := NewUserUsecase(mockRepo, logger)
mockRepo.On("GetByEmail", mock.Anything, "test@example.com").Return(nil, nil)
mockRepo.On("Create", mock.Anything, mock.AnythingOfType("*domain.User")).Return(nil)
user, err := uc.CreateUser(context.Background(), input)
assert.NoError(t, err)
assert.NotNil(t, user)
assert.Equal(t, "test@example.com", user.Email)
}
```
特徵:
- 測試使用者/呼叫者關心的行為
- 只使用公開 API
- 重構內部實作後測試仍然通過
- 描述「做什麼」而非「怎麼做」
- 每個測試一個邏輯斷言
### 壊的測試
**實作細節測試**:與內部結構耦合。
```go
// BAD: 測試實作細節
func TestUserUsecase_CreateUser_CallsRepoCreate(t *testing.T) {
mockRepo := new(mock.UserRepository)
uc := NewUserUsecase(mockRepo, logger)
uc.CreateUser(context.Background(), input)
// 這測試的是「怎麼做」而非「做什麼」
mockRepo.AssertCalled(t, "Create", mock.Anything, mock.Anything)
}
```
紅旗:
- Mock 內部協作者只是為了驗證被呼叫
- 測試私有方法
- 斷言呼叫次數或順序
- 重構後測試失敗但行為沒變
- 測試名稱描述「怎麼做」而非「做什麼」
```go
// BAD: 繞過介面驗證
func TestCreateUser_SavesToDatabase(t *testing.T) {
CreateUser(ctx, input)
row := db.QueryRow("SELECT * FROM users WHERE name = $1", "Alice")
// 直接查資料庫驗證,繞過公開介面
}
// GOOD: 透過介面驗證
func TestCreateUser_MakesUserRetrievable(t *testing.T) {
user, _ := CreateUser(ctx, input)
retrieved, _ := GetUser(ctx, user.ID)
assert.Equal(t, "Alice", retrieved.Name)
// 透過公開介面驗證行為
}
```
## Golang 測試規範
### 測試命名
```go
// Test{Unit}_{Scenario}
func TestUserUsecase_CreateUser_Success(t *testing.T) {}
func TestUserUsecase_CreateUser_InvalidEmail(t *testing.T) {}
func TestUserUsecase_CreateUser_Duplicate(t *testing.T) {}
```
### 測試金字塔
```
/\
/ \
/ E2E \ <- 少數關鍵流程
/--------\
/Integration\ <- API + DB
/--------------\
/ Unit Tests \ <- 最多80%+ 覆蓋
/--------------------\
```
### Mock 策略
只在**系統邊界** mock
- 外部 API支付、郵件等
- 資料庫(有時 — 優先使用測試 DB
- 時間/隨機性
- 檔案系統(有時)
不要 mock
- 你自己的類別/模組
- 內部協作者
- 你可以控制的東西
```go
// 使用 mockery 自動產生 mock
//go:generate mockery --name=UserRepository
// 單元測試使用 mock repo
func TestUserUsecase_CreateUser_Success(t *testing.T) {
mockRepo := new(mock.UserRepository)
uc := NewUserUsecase(mockRepo, logger)
mockRepo.On("GetByEmail", mock.Anything, "test@example.com").Return(nil, nil)
mockRepo.On("Create", mock.Anything, mock.AnythingOfType("*domain.User")).Return(nil)
user, err := uc.CreateUser(context.Background(), input)
assert.NoError(t, err)
assert.NotNil(t, user)
}
```
## 介面設計的可測試性
好的介面讓測試自然:
**1. 接受依賴,不要建立依賴**
```go
// Testable
func (s *UserService) CreateUser(ctx context.Context, input CreateUserInput, repo UserRepository) (*User, error) {}
// Hard to test
func (s *UserService) CreateUser(ctx context.Context, input CreateUserInput) (*User, error) {
repo := postgres.NewUserRepository(db) // 建立依賴
}
```
**2. 回傳結果,不要產生副作用**
```go
// Testable
func CalculateDiscount(cart *Cart) Discount {}
// Hard to test
func ApplyDiscount(cart *Cart) {
cart.Total -= discount // 修改輸入
}
```
**3. 小介面面積**
- 方法少 = 測試少
- 參數少 = 測試設定簡單
## 每個循環的檢查清單
```
[ ] 測試描述行為,而非實作
[ ] 測試只使用公開介面
[ ] 測試在內部重構後仍然通過
[ ] 程式碼是讓當前測試通過的最少實作
[ ] 沒有投機性的功能
```
## 重構候選
TDD 循環完成後,尋找:
- **重複邏輯** → 提取 function / class
- **過長方法** → 拆成私有 helper保持測試在公開介面
- **淺模組** → 合併或加深
- **Feature envy** → 把邏輯移到資料所在的地方
- **原始型別偏執** → 引入 value object
- **新程式碼揭示的既有程式碼問題**
## 相依技能
- **前置**: `go-backend-dev` (在實作中整合使用)
- **輔助**: `design-an-interface` (為可測試性設計介面)
- **後續**: `qa` (QA 測試)

View File

@ -0,0 +1,532 @@
---
name: be-api-design
description: "Backend Agent uses this skill to design API specs. Based on PRD, produce OpenAPI 3.0 spec including endpoints, request/response structures, error handling. Trigger: After PRD approved (Stage 4)."
---
# /be-api-design — API Design
Backend Agent uses this skill to design API specs.
## Responsibilities
1. Analyze functional requirements from PRD
2. Use `design-an-interface` to explore multiple API design options
3. Design RESTful API endpoints
4. Define request/response schemas
5. Design error handling mechanism
6. Produce OpenAPI 3.0 spec
## Input
- PRD document (`docs/prd/{date}-{feature}.md`)
- Existing API style (existing API specs in project)
- Data model context
## Output
- API spec document: `docs/api/{date}-{feature}.yaml` (OpenAPI 3.0)
## Flow
```
Read PRD
Identify resources and operations
Call design-an-interface to explore 2-3 design options
Select best option
Define OpenAPI Schema
Design error handling
Security review
Produce OpenAPI document
```
### Step Details
**1. Read PRD**
Extract all functional requirements from PRD, identify:
- Resources (nouns): users, orders, products, etc.
- Operations (verbs): create, read, update, delete, etc.
- Relationships: relationships between resources (one-to-many, many-to-many)
- Non-functional requirements: pagination, rate limiting, authentication, etc.
**2. Identify Resources and Operations**
Map functional requirements to RESTful resources:
- Each noun → potential resource
- Each verb → HTTP method
- Each relationship → nested resource or standalone endpoint
**3. Call design-an-interface**
Use `design-an-interface` skill to generate 2-3 distinct API design options:
- Option A: Minimize method count (1-3 endpoints per resource)
- Option B: Maximize flexibility (support multiple use cases)
- Option C: Optimize for most common operations
Compare pros and cons, select best design.
**4. Define OpenAPI Schema**
Use template below to produce complete OpenAPI 3.0 spec.
**5. Security Review**
Ensure all endpoints have appropriate authentication and permission controls.
**6. Produce Document**
Save to `docs/api/{date}-{feature}.yaml`.
## Design Principles
### RESTful Design
```yaml
Resource-oriented:
- URL represents resource, not action
- HTTP methods represent actions
Example:
GET /api/v1/users # List users
GET /api/v1/users/{id} # Get specific user
POST /api/v1/users # Create user
PUT /api/v1/users/{id} # Full update
PATCH /api/v1/users/{id} # Partial update
DELETE /api/v1/users/{id} # Delete user
Nested resources:
GET /api/v1/users/{id}/orders # Get user's orders
POST /api/v1/users/{id}/orders # Create order for user
```
### HTTP Status Codes
```yaml
Success:
200: OK # GET, PUT, PATCH, DELETE success
201: Created # POST successfully created resource
204: No Content # DELETE success, no response body
Client Error:
400: Bad Request # Request format error
401: Unauthorized # Not authenticated
403: Forbidden # No permission
404: Not Found # Resource not found
409: Conflict # Resource conflict (e.g., duplicate)
422: Unprocessable Entity # Validation error
429: Too Many Requests # Rate limit
Server Error:
500: Internal Server Error # Server internal error
502: Bad Gateway # Upstream service error
503: Service Unavailable # Service temporarily unavailable
```
### Response Format
```yaml
Success response:
type: object
properties:
data:
type: object
meta:
type: object
properties:
page:
type: integer
limit:
type: integer
total:
type: integer
total_pages:
type: integer
Error response:
type: object
properties:
error:
type: object
properties:
code:
type: string
message:
type: string
details:
type: array
items:
type: object
properties:
field:
type: string
message:
type: string
```
## OpenAPI 3.0 Template
```yaml
openapi: 3.0.3
info:
title: {API Name}
version: 1.0.0
description: |
{Description}
Related PRD: {PRD Link}
servers:
- url: https://api.example.com/v1
description: Production
- url: https://staging-api.example.com/v1
description: Staging
paths:
/users:
get:
summary: List users
tags:
- Users
parameters:
- name: page
in: query
schema:
type: integer
default: 1
- name: limit
in: query
schema:
type: integer
default: 20
maximum: 100
- name: search
in: query
schema:
type: string
responses:
'200':
description: Success
content:
application/json:
schema:
$ref: '#/components/schemas/UserListResponse'
'401':
$ref: '#/components/responses/Unauthorized'
'500':
$ref: '#/components/responses/InternalError'
post:
summary: Create user
tags:
- Users
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/CreateUserRequest'
responses:
'201':
description: Created successfully
content:
application/json:
schema:
$ref: '#/components/schemas/UserResponse'
'400':
$ref: '#/components/responses/BadRequest'
'422':
$ref: '#/components/responses/ValidationError'
/users/{id}:
parameters:
- name: id
in: path
required: true
schema:
type: string
get:
summary: Get user
tags:
- Users
responses:
'200':
description: Success
content:
application/json:
schema:
$ref: '#/components/schemas/UserResponse'
'404':
$ref: '#/components/responses/NotFound'
put:
summary: Full update user
tags:
- Users
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/UpdateUserRequest'
responses:
'200':
description: Updated successfully
content:
application/json:
schema:
$ref: '#/components/schemas/UserResponse'
'404':
$ref: '#/components/responses/NotFound'
'422':
$ref: '#/components/responses/ValidationError'
patch:
summary: Partial update user
tags:
- Users
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/PatchUserRequest'
responses:
'200':
description: Updated successfully
content:
application/json:
schema:
$ref: '#/components/schemas/UserResponse'
'404':
$ref: '#/components/responses/NotFound'
delete:
summary: Delete user
tags:
- Users
responses:
'204':
description: Deleted successfully
'404':
$ref: '#/components/responses/NotFound'
components:
schemas:
User:
type: object
properties:
id:
type: string
example: "usr_123456"
email:
type: string
format: email
example: "user@example.com"
name:
type: string
example: "John Doe"
status:
type: string
enum: [active, inactive, suspended]
example: "active"
created_at:
type: string
format: date-time
updated_at:
type: string
format: date-time
required:
- id
- email
- name
- status
- created_at
- updated_at
CreateUserRequest:
type: object
properties:
email:
type: string
format: email
password:
type: string
minLength: 8
name:
type: string
minLength: 1
maxLength: 100
required:
- email
- password
- name
UpdateUserRequest:
type: object
properties:
email:
type: string
format: email
name:
type: string
minLength: 1
maxLength: 100
status:
type: string
enum: [active, inactive]
PatchUserRequest:
type: object
properties:
name:
type: string
minLength: 1
maxLength: 100
status:
type: string
enum: [active, inactive]
UserResponse:
type: object
properties:
data:
$ref: '#/components/schemas/User'
UserListResponse:
type: object
properties:
data:
type: array
items:
$ref: '#/components/schemas/User'
meta:
type: object
properties:
page:
type: integer
limit:
type: integer
total:
type: integer
total_pages:
type: integer
Error:
type: object
properties:
error:
type: object
properties:
code:
type: string
message:
type: string
details:
type: array
items:
type: object
properties:
field:
type: string
message:
type: string
responses:
BadRequest:
description: Request format error
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
Unauthorized:
description: Not authenticated
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
NotFound:
description: Resource not found
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
ValidationError:
description: Validation error
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
InternalError:
description: Server internal error
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
securitySchemes:
bearerAuth:
type: http
scheme: bearer
bearerFormat: JWT
security:
- bearerAuth: []
```
## Design Checklist
### Security
- [ ] All endpoints have appropriate authentication
- [ ] Input validation complete
- [ ] Rate limiting designed
- [ ] CORS configured
### Performance
- [ ] Pagination support
- [ ] Caching strategy
- [ ] Batch operation support
### Reliability
- [ ] Error response format unified
- [ ] Retry mechanism recommendations
- [ ] Idempotency design
### Consistency
- [ ] Naming convention consistent (resources use plural nouns)
- [ ] Response format consistent (data/meta/error structure)
- [ ] Filter/sort/pagination parameters consistent
## Related Skills
- **Prerequisite**: `write-a-prd` (after PRD approved)
- **辅助**: `design-an-interface` (explore multiple design options)
- **Follow-up**: `dba-schema` (DB Schema design)
- **Rollback**: Can rollback to `write-a-prd` to modify requirements
## Rollback Mechanism
```
Design Review rejects API design
Modify OpenAPI spec
Re-submit (or re-call design-an-interface)
DBA Agent finds Schema conflict
Negotiate domain model or API response format adjustments
Update OpenAPI spec
```

View File

@ -0,0 +1,188 @@
---
name: design-an-interface
description: "Backend Agent uses this skill to explore multiple API interface design options. Based on 'Design It Twice' principle, generate multiple distinct designs, compare, and select the best option. Trigger: API design phase (Stage 4), called by be-api-design skill."
---
# /design-an-interface — Interface Design Exploration
Backend Agent uses this skill to explore API interface design options.
Based on "Design It Twice" principle from "A Philosophy of Software Design": The first idea is usually not the best. Generate multiple distinct designs, then compare and choose.
## Responsibilities
1. Generate 2-3 distinct interface design options for module requirements
2. Each option uses different design constraints
3. Compare pros and cons of options
4. Assist in selecting or synthesizing the best option
## Input
- Module description (functional requirements from PRD)
- User stories and usage scenarios
## Output
- Multiple interface design options (including interface signatures, usage examples, pros/cons analysis)
- Option comparison and recommendations
## Flow
```
Collect requirements
Generate 2-3 design options (parallel sub-agents)
Present each option
Compare options (interface simplicity, generality, implementation efficiency, depth)
Synthesize best option or select most suitable
```
### Step Details
**1. Collect Requirements**
Before designing, understand:
- [ ] What problem does this module solve?
- [ ] Who are the callers? (other modules, external users, tests)
- [ ] What are the key operations?
- [ ] What are the constraints? (performance, compatibility, existing patterns)
- [ ] What should be hidden internally? What should be exposed externally?
Ask: "What does this module need to do? Who will use it?"
**2. Generate Design Options (Parallel Sub-Agents)**
Generate 3+ distinct options simultaneously. Each option must follow different constraints:
```
Option A: Minimize method count — target 1-3 methods
Option B: Maximize flexibility — support multiple use cases
Option C: Optimize for most common operations
Option D (optional): Reference specific paradigm or framework design
```
Each option should include:
1. Interface signature (types/methods)
2. Usage examples (how callers actually use it)
3. What complexity this design hides
4. Trade-offs of this option
**3. Present Options**
Present each option one by one, including:
- Interface signature: types, methods, params
- Usage examples: how callers actually use it
- Hidden complexity: small interface hiding large implementation (good) vs large interface with thin implementation (bad)
Allow user to fully absorb each option before comparison.
**4. Compare Options**
Compare across dimensions:
- **Interface simplicity**: Few methods, simple parameters → Easier to learn and use correctly
- **Generality vs Specificity**: Flexibility vs focus, where are the trade-offs
- **Implementation efficiency**: Does interface shape allow efficient internal implementation?
- **Depth**: Small interface hiding large complexity (deep module, good) vs large interface with thin implementation (shallow module, bad)
- **Ease of correct usage vs ease of misuse**
Discuss trade-offs in text, not just tables. Emphasize where options diverge most.
**5. Synthesize Best Option**
The best design often combines insights from multiple options. Ask:
- "Which option fits your primary use case best?"
- "Are there elements from other options worth incorporating?"
## Evaluation Criteria
From "A Philosophy of Software Design":
**Interface simplicity**: Few methods, simple parameters = Easier to learn and use correctly.
**Generality**: Can handle future use cases without modification. But avoid over-generalization.
**Implementation efficiency**: Does interface shape allow efficient implementation? Or does it force awkward internal implementation?
**Depth**: Small interface hiding large complexity = deep module (good). Large interface with thin implementation = shallow module (avoid).
```
Deep module (good):
┌─────────────────────┐
│ Small Interface │ ← Few methods, simple parameters
├─────────────────────┤
│ │
│ │
│ Deep Implementation│ ← Complex logic hidden inside
│ │
│ │
└─────────────────────┘
Shallow module (avoid):
┌─────────────────────────────────┐
│ Large Interface │ ← Many methods, complex parameters
├─────────────────────────────────┤
│ Thin Implementation │ ← Just a pass-through
└─────────────────────────────────┘
```
## Anti-Patterns
- Don't let sub-agents generate similar designs — force distinct ones
- Don't skip comparison — value comes from contrast
- Don't implement at this stage — this is pure interface design
- Don't evaluate options based on implementation effort — only look at interface quality
## Golang Interface Design Examples
```go
// Option A: Minimize method count
type UserRepository interface {
GetByID(ctx context.Context, id string) (*domain.User, error)
Save(ctx context.Context, user *domain.User) error
}
// Pros: Simple, easy to mock
// Cons: Save handles both Create and Update, depends on whether it exists
// Option B: Separate read/write
type UserReader interface {
GetByID(ctx context.Context, id string) (*domain.User, error)
List(ctx context.Context, page, limit int) ([]*domain.User, error)
}
type UserWriter interface {
Create(ctx context.Context, user *domain.User) error
Update(ctx context.Context, user *domain.User) error
Delete(ctx context.Context, id string) error
}
// Pros: CQRS friendly, separated concerns
// Cons: More methods, but each method has clearer semantics
// Option C: Optimize for common operations
type UserService interface {
Register(ctx context.Context, email, password, name string) (*domain.User, error)
Authenticate(ctx context.Context, email, password string) (*domain.User, error)
GetProfile(ctx context.Context, id string) (*domain.User, error)
}
// Pros: Directly maps to business operations, most intuitive
// Cons: Need to add method for each new operation, less flexible
```
## Integration with be-api-design
This skill is automatically called by `be-api-design` at step 3. API design flow:
```
be-api-design step 1: Read PRD
be-api-design step 2: Identify resources and operations
→ design-an-interface: Explore 2-3 API design options
be-api-design step 4: Select option, define OpenAPI spec
```
## Related Skills
- **Prerequisite**: `write-a-prd` (PRD complete)
- **Follow-up**: `be-api-design` (API spec definition)

View File

@ -0,0 +1,15 @@
# Abstract Factory Pattern
## Description
Provide an interface for creating families of related or dependent objects without specifying their concrete classes.
## Use Cases
Load this skill when you need to solve design problems described by this pattern in your code.
## Guidelines
1. Analyze whether current code structure matches the pattern's intent.
2. Refactor or implement following the pattern's typical structure.
3. Ensure the pattern introduction reduces coupling or improves flexibility.
## Detailed Reference
For more details, diagrams, and code examples: [Abstract Factory Pattern - RefactoringGuru](https://refactoringguru.cn/design-patterns/abstract-factory)

View File

@ -0,0 +1,15 @@
# Adapter Pattern
## Description
Convert the interface of a class into another interface that clients expect.
## Use Cases
Load this skill when you need to solve design problems described by this pattern in your code.
## Guidelines
1. Analyze whether current code structure matches the pattern's intent.
2. Refactor or implement following the pattern's typical structure.
3. Ensure the pattern introduction reduces coupling or improves flexibility.
## Detailed Reference
For more details, diagrams, and code examples: [Adapter Pattern - RefactoringGuru](https://refactoringguru.cn/design-patterns/adapter)

View File

@ -0,0 +1,15 @@
# Bridge Pattern
## Description
Decouple an abstraction from its implementation so that the two can vary independently.
## Use Cases
Load this skill when you need to solve design problems described by this pattern in your code.
## Guidelines
1. Analyze whether current code structure matches the pattern's intent.
2. Refactor or implement following the pattern's typical structure.
3. Ensure the pattern introduction reduces coupling or improves flexibility.
## Detailed Reference
For more details, diagrams, and code examples: [Bridge Pattern - RefactoringGuru](https://refactoringguru.cn/design-patterns/bridge)

View File

@ -0,0 +1,15 @@
# Builder Pattern
## Description
Separate the construction of a complex object from its representation, allowing the same construction process to create different representations.
## Use Cases
Load this skill when you need to solve design problems described by this pattern in your code.
## Guidelines
1. Analyze whether current code structure matches the pattern's intent.
2. Refactor or implement following the pattern's typical structure.
3. Ensure the pattern introduction reduces coupling or improves flexibility.
## Detailed Reference
For more details, diagrams, and code examples: [Builder Pattern - RefactoringGuru](https://refactoringguru.cn/design-patterns/builder)

View File

@ -0,0 +1,15 @@
# Chain of Responsibility Pattern
## Description
Allow multiple objects to handle the same request.
## Use Cases
Load this skill when you need to solve design problems described by this pattern in your code.
## Guidelines
1. Analyze whether current code structure matches the pattern's intent.
2. Refactor or implement following the pattern's typical structure.
3. Ensure the pattern introduction reduces coupling or improves flexibility.
## Detailed Reference
For more details, diagrams, and code examples: [Chain of Responsibility Pattern - RefactoringGuru](https://refactoringguru.cn/design-patterns/chain-of-responsibility)

View File

@ -0,0 +1,15 @@
# Command Pattern
## Description
Encapsulate a request as an object, thereby allowing parameterization of clients with different requests.
## Use Cases
Load this skill when you need to solve design problems described by this pattern in your code.
## Guidelines
1. Analyze whether current code structure matches the pattern's intent.
2. Refactor or implement following the pattern's typical structure.
3. Ensure the pattern introduction reduces coupling or improves flexibility.
## Detailed Reference
For more details, diagrams, and code examples: [Command Pattern - RefactoringGuru](https://refactoringguru.cn/design-patterns/command)

View File

@ -0,0 +1,15 @@
# Composite Pattern
## Description
Compose objects into tree structures to represent part-whole hierarchies.
## Use Cases
Load this skill when you need to solve design problems described by this pattern in your code.
## Guidelines
1. Analyze whether current code structure matches the pattern's intent.
2. Refactor or implement following the pattern's typical structure.
3. Ensure the pattern introduction reduces coupling or improves flexibility.
## Detailed Reference
For more details, diagrams, and code examples: [Composite Pattern - RefactoringGuru](https://refactoringguru.cn/design-patterns/composite)

View File

@ -0,0 +1,15 @@
# Decorator Pattern
## Description
Dynamically add additional responsibilities to an object.
## Use Cases
Load this skill when you need to solve design problems described by this pattern in your code.
## Guidelines
1. Analyze whether current code structure matches the pattern's intent.
2. Refactor or implement following the pattern's typical structure.
3. Ensure the pattern introduction reduces coupling or improves flexibility.
## Detailed Reference
For more details, diagrams, and code examples: [Decorator Pattern - RefactoringGuru](https://refactoringguru.cn/design-patterns/decorator)

View File

@ -0,0 +1,15 @@
# Facade Pattern
## Description
Provide a unified interface to a set of interfaces in a subsystem, hiding the implementation details of the subsystem.
## Use Cases
Load this skill when you need to solve design problems described by this pattern in your code.
## Guidelines
1. Analyze whether current code structure matches the pattern's intent.
2. Refactor or implement following the pattern's typical structure.
3. Ensure the pattern introduction reduces coupling or improves flexibility.
## Detailed Reference
For more details, diagrams, and code examples: [Facade Pattern - RefactoringGuru](https://refactoringguru.cn/design-patterns/facade)

View File

@ -0,0 +1,15 @@
# Factory Method Pattern
## Description
Define an interface for creating an object, but let subclasses decide which class to instantiate.
## Use Cases
Load this skill when you need to solve design problems described by this pattern in your code.
## Guidelines
1. Analyze whether current code structure matches the pattern's intent.
2. Refactor or implement following the pattern's typical structure.
3. Ensure the pattern introduction reduces coupling or improves flexibility.
## Detailed Reference
For more details, diagrams, and code examples: [Factory Method Pattern - RefactoringGuru](https://refactoringguru.cn/design-patterns/factory-method)

View File

@ -0,0 +1,15 @@
# Flyweight Pattern
## Description
Use sharing to support large quantities of fine-grained objects efficiently.
## Use Cases
Load this skill when you need to solve design problems described by this pattern in your code.
## Guidelines
1. Analyze whether current code structure matches the pattern's intent.
2. Refactor or implement following the pattern's typical structure.
3. Ensure the pattern introduction reduces coupling or improves flexibility.
## Detailed Reference
For more details, diagrams, and code examples: [Flyweight Pattern - RefactoringGuru](https://refactoringguru.cn/design-patterns/flyweight)

View File

@ -0,0 +1,15 @@
# Iterator Pattern
## Description
Provide a method to sequentially access elements of an aggregate object without exposing its internal representation.
## Use Cases
Load this skill when you need to solve design problems described by this pattern in your code.
## Guidelines
1. Analyze whether current code structure matches the pattern's intent.
2. Refactor or implement following the pattern's typical structure.
3. Ensure the pattern introduction reduces coupling or improves flexibility.
## Detailed Reference
For more details, diagrams, and code examples: [Iterator Pattern - RefactoringGuru](https://refactoringguru.cn/design-patterns/iterator)

View File

@ -0,0 +1,15 @@
# Mediator Pattern
## Description
Use a mediator object to encapsulate a series of class interactions.
## Use Cases
Load this skill when you need to solve design problems described by this pattern in your code.
## Guidelines
1. Analyze whether current code structure matches the pattern's intent.
2. Refactor or implement following the pattern's typical structure.
3. Ensure the pattern introduction reduces coupling or improves flexibility.
## Detailed Reference
For more details, diagrams, and code examples: [Mediator Pattern - RefactoringGuru](https://refactoringguru.cn/design-patterns/mediator)

View File

@ -0,0 +1,15 @@
# Memento Pattern
## Description
Capture an object's internal state without violating encapsulation, so that the object can be restored to this state later.
## Use Cases
Load this skill when you need to solve design problems described by this pattern in your code.
## Guidelines
1. Analyze whether current code structure matches the pattern's intent.
2. Refactor or implement following the pattern's typical structure.
3. Ensure the pattern introduction reduces coupling or improves flexibility.
## Detailed Reference
For more details, diagrams, and code examples: [Memento Pattern - RefactoringGuru](https://refactoringguru.cn/design-patterns/memento)

View File

@ -0,0 +1,15 @@
# Observer Pattern
## Description
Define a one-to-many dependency relationship so that when one object's state changes, all dependent objects are notified and automatically updated.
## Use Cases
Load this skill when you need to solve design problems described by this pattern in your code.
## Guidelines
1. Analyze whether current code structure matches the pattern's intent.
2. Refactor or implement following the pattern's typical structure.
3. Ensure the pattern introduction reduces coupling or improves flexibility.
## Detailed Reference
For more details, diagrams, and code examples: [Observer Pattern - RefactoringGuru](https://refactoringguru.cn/design-patterns/observer)

View File

@ -0,0 +1,15 @@
# Prototype Pattern
## Description
Use a prototype instance to create other instances.
## Use Cases
Load this skill when you need to solve design problems described by this pattern in your code.
## Guidelines
1. Analyze whether current code structure matches the pattern's intent.
2. Refactor or implement following the pattern's typical structure.
3. Ensure the pattern introduction reduces coupling or improves flexibility.
## Detailed Reference
For more details, diagrams, and code examples: [Prototype Pattern - RefactoringGuru](https://refactoringguru.cn/design-patterns/prototype)

View File

@ -0,0 +1,15 @@
# Proxy Pattern
## Description
Provide a surrogate or placeholder for another object to control access to it.
## Use Cases
Load this skill when you need to solve design problems described by this pattern in your code.
## Guidelines
1. Analyze whether current code structure matches the pattern's intent.
2. Refactor or implement following the pattern's typical structure.
3. Ensure the pattern introduction reduces coupling or improves flexibility.
## Detailed Reference
For more details, diagrams, and code examples: [Proxy Pattern - RefactoringGuru](https://refactoringguru.cn/design-patterns/proxy)

View File

@ -0,0 +1,15 @@
# Singleton Pattern
## Description
Ensure a class has only one instance and provide a global point of access to it.
## Use Cases
Load this skill when you need to solve design problems described by this pattern in your code.
## Guidelines
1. Analyze whether current code structure matches the pattern's intent.
2. Refactor or implement following the pattern's typical structure.
3. Ensure the pattern introduction reduces coupling or improves flexibility.
## Detailed Reference
For more details, diagrams, and code examples: [Singleton Pattern - RefactoringGuru](https://refactoringguru.cn/design-patterns/singleton)

View File

@ -0,0 +1,15 @@
# State Pattern
## Description
Allow an object to alter its behavior when its internal state changes.
## Use Cases
Load this skill when you need to solve design problems described by this pattern in your code.
## Guidelines
1. Analyze whether current code structure matches the pattern's intent.
2. Refactor or implement following the pattern's typical structure.
3. Ensure the pattern introduction reduces coupling or improves flexibility.
## Detailed Reference
For more details, diagrams, and code examples: [State Pattern - RefactoringGuru](https://refactoringguru.cn/design-patterns/state)

View File

@ -0,0 +1,15 @@
# Strategy Pattern
## Description
Define a family of algorithms, encapsulate each one, and make them interchangeable.
## Use Cases
Load this skill when you need to solve design problems described by this pattern in your code.
## Guidelines
1. Analyze whether current code structure matches the pattern's intent.
2. Refactor or implement following the pattern's typical structure.
3. Ensure the pattern introduction reduces coupling or improves flexibility.
## Detailed Reference
For more details, diagrams, and code examples: [Strategy Pattern - RefactoringGuru](https://refactoringguru.cn/design-patterns/strategy)

View File

@ -0,0 +1,15 @@
# Template Method Pattern
## Description
Define the skeleton of an operation, deferring some steps to subclasses.
## Use Cases
Load this skill when you need to solve design problems described by this pattern in your code.
## Guidelines
1. Analyze whether current code structure matches the pattern's intent.
2. Refactor or implement following the pattern's typical structure.
3. Ensure the pattern introduction reduces coupling or improves flexibility.
## Detailed Reference
For more details, diagrams, and code examples: [Template Method Pattern - RefactoringGuru](https://refactoringguru.cn/design-patterns/template-method)

View File

@ -0,0 +1,15 @@
# Visitor Pattern
## Description
Without changing the element classes, define new operations that act on these elements.
## Use Cases
Load this skill when you need to solve design problems described by this pattern in your code.
## Guidelines
1. Analyze whether current code structure matches the pattern's intent.
2. Refactor or implement following the pattern's typical structure.
3. Ensure the pattern introduction reduces coupling or improves flexibility.
## Detailed Reference
For more details, diagrams, and code examples: [Visitor Pattern - RefactoringGuru](https://refactoringguru.cn/design-patterns/visitor)

View File

@ -0,0 +1,812 @@
---
name: go-backend-dev
description: "Backend Agent uses this skill to implement Golang backend. Based on implementation plan and API spec, use Domain-Driven + go-zero style architecture and TDD process to produce production-ready code. Trigger: After Task Breakdown complete (Stage 9)."
---
# /go-backend-dev — Golang Backend Implementation
Backend Agent uses this skill to implement Golang backend.
## Responsibilities
1. Establish project structure based on implementation plan (Domain-Driven + go-zero style)
2. Implement features using TDD process (Red-Green-Refactor)
3. Deliver incrementally by vertical slices (end-to-end, not layer-by-layer)
4. Implement Domain / Usecase / Logic / Repository layers
5. Write unit tests and integration tests
## Input
- Implementation plan (`./plans/{feature}.md`)
- API spec (`docs/api/{date}-{feature}.yaml`)
- DB Schema (`docs/db/{date}-{feature}.sql`)
## Output
- Golang code structure
- Test code (unit tests >= 80%, business logic >= 90%)
- Protobuf definitions (if gRPC needed)
## Flow
```
Read implementation plan + API spec + DB Schema
Identify vertical slices (each slice = end-to-end feature)
Execute TDD loop for each slice:
├── RED: Write test → Test fails
├── GREEN: Write minimal code → Test passes
└── REFACTOR: Refactor → Test still passes
Build order within slice:
domain (entity/value object/interface)
→ pkg/domain/usecase (interface)
→ pkg/domain/repository (interface)
→ pkg/usecase (implementation)
→ pkg/mock (mock)
→ internal/logic (handler logic)
→ pkg/repository (infrastructure implementation)
All slices complete → Run integration tests
Confirm deliverables checklist
```
### Step Details
**1. Read Input**
Read three documents simultaneously:
- Implementation plan: Understand vertical slice breakdown and priority
- API spec: Understand endpoints, request/response structures
- DB Schema: Understand table structures and relationships
**2. Identify Vertical Slices**
Not horizontal slicing (layer by layer), but vertical slicing (end-to-end):
```
✅ Correct way (vertical):
Slice 1: User registration (domain.entity + domain.usecase interface + usecase implementation + logic + repository)
Slice 2: User login (same as above)
Slice 3: User list (same as above)
❌ Wrong way (horizontal):
Stage 1: All domain entities
Stage 2: All usecases
Stage 3: All logic handlers
```
**3. TDD Loop (Each Slice)**
For each slice, follow Red-Green-Refactor:
```
RED: Write a test → Test fails
GREEN: Write minimal code to make test pass → Test passes
REFACTOR: Refactor code → Test still passes
```
Build order within slice (inside-out):
1. `pkg/domain/entity/` — Define Entity and Value Object
2. `pkg/domain/member/` — Define value objects and enums (with tests)
3. `pkg/domain/usecase/` — Define Use Case interface
4. `pkg/domain/repository/` — Define Repository interface
5. `pkg/usecase/` — Implement business logic (write tests first)
6. `pkg/mock/` — Generate mocks
7. `internal/logic/` — Handler logic
8. `pkg/repository/` — Infrastructure implementation (with DB tests)
**4. Testing**
After each slice completes, ensure:
- Unit tests pass (`pkg/usecase/*_test.go`)
- Value object tests pass (`pkg/domain/member/*_test.go`)
- Repository tests pass (`pkg/repository/*_test.go`)
- Integration tests pass (critical paths)
- Test coverage meets requirements
**5. Completion Verification**
Finally confirm all deliverables are complete.
## Project Structure
```
project-root/
├── build/
│ └── Dockerfile # Build image
├── etc/
│ └── {service}.example.yaml # Example config file
├── generate/
│ └── protobuf/
│ └── {service}.proto # Protobuf definitions (if gRPC)
├── internal/ # Application layer (not exposed externally)
│ ├── config/
│ │ └── config.go # Application config
│ ├── logic/
│ │ └── {module}/
│ │ ├── create_{entity}_logic.go # One logic file per use case
│ │ ├── get_{entity}_logic.go
│ │ ├── update_{entity}_logic.go
│ │ └── ...
│ ├── server/
│ │ └── {module}/
│ │ └── {module}_server.go # Server definition (HTTP/gRPC)
│ └── svc/
│ └── service_context.go # Dependency injection container
├── pkg/ # Domain layer (can be exposed externally)
│ ├── domain/
│ │ ├── config/
│ │ │ └── config.go # Domain config
│ │ ├── entity/
│ │ │ ├── {entity}.go # Entity definition
│ │ │ ├── {entity}_uid_table.go # UID mapping table
│ │ │ └── auto_id.go # Auto ID generation
│ │ ├── {module}/
│ │ │ ├── {value_object}.go # Value objects and enums
│ │ │ └── {value_object}_test.go # Value object tests
│ │ ├── repository/
│ │ │ ├── {entity}.go # Repository interface
│ │ │ └── ...
│ │ ├── usecase/
│ │ │ ├── {module}.go # Use Case interface
│ │ │ └── ...
│ │ ├── errors.go # Domain sentinel errors
│ │ ├── const.go # Domain constants
│ │ └── redis.go # Redis domain definitions
│ ├── mock/
│ │ ├── repository/
│ │ │ ├── {entity}.go # Repository mock
│ │ │ └── ...
│ │ └── usecase/
│ │ └── {module}.go # Use Case mock
│ ├── repository/
│ │ ├── {entity}.go # Repository implementation
│ │ ├── {entity}_test.go # Repository tests
│ │ ├── {entity}_uid.go # UID Repository implementation
│ │ ├── {entity}_uid_test.go
│ │ ├── error.go # Repository error definitions
│ │ └── start_{db}_container_test.go # testcontainers startup
│ └── usecase/
│ ├── {module}.go # Use Case implementation
│ ├── {operation}.go # Specific operation
│ ├── {operation}_test.go # Use Case tests
│ └── {utils}.go # Utility functions
├── {service}.go # Application entry point
├── Makefile
├── go.mod
├── go.sum
├── docker-compose.yml
└── readme.md
```
## Dependency Direction Rules
```
pkg/domain/ ← No external dependencies (innermost, pure definitions)
pkg/domain/usecase/ ← Use Case interface (only interface definitions)
pkg/domain/repository/ ← Repository interface (only interface definitions)
pkg/usecase/ ← Depends on domain interfaces (business logic implementation)
pkg/mock/ ← Depends on domain interfaces (test mocks)
internal/logic/ ← Depends on usecase implementations (handler logic)
internal/server/ ← Depends on logic (HTTP/gRPC server)
internal/svc/ ← Depends on all (DI container, assemble dependencies)
pkg/repository/ ← Depends on domain interfaces (infrastructure implementation)
```
```
┌─────────────────────────────────┐
│ pkg/domain/ │ ← Pure definitions, no dependencies
│ ├── entity/ │
│ ├── {module}/ (value objects)│
│ ├── repository/ (interfaces) │
│ ├── usecase/ (interfaces) │
│ ├── errors.go │
│ └── const.go │
├─────────────────────────────────┤
│ pkg/usecase/ │ ← Depends on domain interfaces
│ pkg/mock/ │ ← Depends on domain interfaces
├─────────────────────────────────┤
│ internal/logic/ │ ← Depends on usecase
│ internal/server/ │
│ internal/config/ │
│ internal/svc/ │ ← DI container
├─────────────────────────────────┤
│ pkg/repository/ │ ← Depends on domain interfaces
└─────────────────────────────────┘
```
## Architecture Principles
### `pkg/domain/` — Pure Domain Definitions
`pkg/domain/` is the core, containing only **interfaces and definitions**, no implementations:
```go
// pkg/domain/entity/user.go — Entity definition
package entity
type User struct {
ID string `json:"id"`
Email string `json:"email"`
Name string `json:"name"`
Status string `json:"status"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
}
```
```go
// pkg/domain/member/status.go — Value object (with tests)
package member
type Status string
const (
StatusActive Status = "active"
StatusInactive Status = "inactive"
)
func (s Status) IsValid() bool {
switch s {
case StatusActive, StatusInactive:
return true
}
return false
}
func NewStatus(s string) (Status, error) {
status := Status(s)
if !status.IsValid() {
return "", fmt.Errorf("invalid status: %s", s)
}
return status, nil
}
```
```go
// pkg/domain/member/status_test.go — Value object tests
package member
func TestStatus_IsValid(t *testing.T) {
assert.True(t, StatusActive.IsValid())
assert.True(t, StatusInactive.IsValid())
assert.False(t, Status("unknown").IsValid())
}
func TestNewStatus(t *testing.T) {
status, err := NewStatus("active")
assert.NoError(t, err)
assert.Equal(t, StatusActive, status)
_, err = NewStatus("unknown")
assert.Error(t, err)
}
```
```go
// pkg/domain/repository/user.go — Repository interface
package repository
type UserRepository interface {
GetByID(ctx context.Context, id string) (*entity.User, error)
GetByEmail(ctx context.Context, email string) (*entity.User, error)
Create(ctx context.Context, user *entity.User) error
Update(ctx context.Context, user *entity.User) error
Delete(ctx context.Context, id string) error
}
```
```go
// pkg/domain/usecase/user.go — Use Case interface
package usecase
type UserUsecase interface {
CreateUser(ctx context.Context, input CreateUserInput) (*entity.User, error)
GetUser(ctx context.Context, id string) (*entity.User, error)
UpdateUser(ctx context.Context, id string, input UpdateUserInput) (*entity.User, error)
}
```
```go
// pkg/domain/errors.go — Domain sentinel errors
package domain
import "errors"
var (
ErrUserNotFound = errors.New("user not found")
ErrInvalidInput = errors.New("invalid input")
ErrDuplicateEmail = errors.New("email already exists")
)
```
### `pkg/usecase/` — Business Logic Implementation
One functional domain per file, test file in same directory:
```go
// pkg/usecase/account.go — Use Case entry point
package usecase
type AccountUsecase struct {
userRepo repository.UserRepository
accountRepo repository.AccountRepository
redis *redis.Client
}
func NewAccountUsecase(
userRepo repository.UserRepository,
accountRepo repository.AccountRepository,
redis *redis.Client,
) *AccountUsecase {
return &AccountUsecase{
userRepo: userRepo,
accountRepo: accountRepo,
redis: redis,
}
}
```
```go
// pkg/usecase/create_user.go — Single operation
package usecase
func (uc *AccountUsecase) CreateUser(ctx context.Context, input CreateUserInput) (*entity.User, error) {
if err := input.Validate(); err != nil {
return nil, fmt.Errorf("validate input: %w", err)
}
existing, _ := uc.userRepo.GetByEmail(ctx, input.Email)
if existing != nil {
return nil, domain.ErrDuplicateEmail
}
user, err := entity.NewUser(input.Email, input.Password, input.Name)
if err != nil {
return nil, fmt.Errorf("create user: %w", err)
}
if err := uc.userRepo.Create(ctx, user); err != nil {
return nil, fmt.Errorf("save user: %w", err)
}
return user, nil
}
```
```go
// pkg/usecase/create_user_test.go — Test in same directory
package usecase
func TestAccountUsecase_CreateUser_Success(t *testing.T) {
mockUserRepo := new(mock.UserRepository)
uc := NewAccountUsecase(mockUserRepo, nil, nil)
mockUserRepo.On("GetByEmail", mock.Anything, "test@example.com").Return(nil, nil)
mockUserRepo.On("Create", mock.Anything, mock.AnythingOfType("*entity.User")).Return(nil)
user, err := uc.CreateUser(context.Background(), input)
assert.NoError(t, err)
assert.NotNil(t, user)
mockUserRepo.AssertExpectations(t)
}
```
### `pkg/mock/` — Auto-Generated Mocks
```go
// pkg/mock/repository/user.go — Generated by mockery
//go:generate mockery --name=UserRepository --output=../../mock/repository --outpkg=mock_repository
package mock_repository
import (
"github.com/stretchr/testify/mock"
"your-project/pkg/domain/repository"
)
type UserRepository struct {
mock.Mock
}
func (m *UserRepository) GetByID(ctx context.Context, id string) (*entity.User, error) {
args := m.Called(ctx, id)
if args.Get(0) == nil {
return nil, args.Error(1)
}
return args.Get(0).(*entity.User), args.Error(1)
}
```
### `internal/logic/` — Handler Logic
One logic file per use case (go-zero style):
```go
// internal/logic/account/create_user_logic.go
package account
type CreateUserLogic struct {
ctx context.Context
svcCtx *svc.ServiceContext
}
func NewCreateUserLogic(ctx context.Context, svcCtx *svc.ServiceContext) *CreateUserLogic {
return &CreateUserLogic{
ctx: ctx,
svcCtx: svcCtx,
}
}
func (l *CreateUserLogic) CreateUser(req *types.CreateUserReq) (*types.UserResp, error) {
user, err := l.svcCtx.UserUsecase.CreateUser(l.ctx, usecase.CreateUserInput{
Email: req.Email,
Password: req.Password,
Name: req.Name,
})
if err != nil {
return nil, err
}
return &types.UserResp{
ID: user.ID,
Email: user.Email,
Name: user.Name,
}, nil
}
```
### `internal/svc/` — Dependency Injection Container
```go
// internal/svc/service_context.go
package svc
type ServiceContext struct {
Config config.Config
UserUsecase usecase.UserUsecase
AccountUsecase usecase.AccountUsecase
}
func NewServiceContext(c config.Config) *ServiceContext {
db := mongo.NewClient(c.Mongo.URI)
redisClient := redis.NewClient(c.Redis)
userRepo := repository.NewUserRepository(db)
accountRepo := repository.NewAccountRepository(db)
return &ServiceContext{
Config: c,
UserUsecase: usecase.NewUserUsecase(userRepo, redisClient),
AccountUsecase: usecase.NewAccountUsecase(userRepo, accountRepo, redisClient),
}
}
```
### `pkg/repository/` — Infrastructure Implementation
```go
// pkg/repository/user.go
package repository
type userRepository struct {
db *mongo.Database
}
func NewUserRepository(db *mongo.Database) domain.Repository.UserRepository {
return &userRepository{db: db}
}
func (r *userRepository) GetByID(ctx context.Context, id string) (*entity.User, error) {
var user entity.User
err := r.db.Collection("users").FindOne(ctx, bson.M{"_id": id}).Decode(&user)
if err != nil {
if err == mongo.ErrNoDocuments {
return nil, domain.ErrUserNotFound
}
return nil, fmt.Errorf("find user by id: %w", err)
}
return &user, nil
}
```
```go
// pkg/repository/user_test.go
package repository
func TestUserRepository_GetByID_Success(t *testing.T) {
db := startMongoContainer(t)
defer db.Client().Disconnect(context.Background())
repo := NewUserRepository(db)
// ...
}
```
## Coding Standards
### File Naming
```
Value objects and enums: pkg/domain/{module}/{name}.go + _test.go
Entity: pkg/domain/entity/{name}.go
Repository interface: pkg/domain/repository/{name}.go
Usecase interface: pkg/domain/usecase/{module}.go
Usecase implementation: pkg/usecase/{operation}.go + _test.go
Usecase utilities: pkg/usecase/{module}_utils.go + _test.go
Repository impl: pkg/repository/{name}.go + _test.go
Mock: pkg/mock/repository/{name}.go
pkg/mock/usecase/{module}.go
Handler logic: internal/logic/{module}/{operation}_logic.go
Server: internal/server/{module}/{module}_server.go
Service Context: internal/svc/service_context.go
Protobuf definitions: generate/protobuf/{module}.proto
Config files: etc/{service}.yaml
Dockerfile: build/Dockerfile
```
### Naming Conventions
```go
// Package: lowercase, semantically clear
package usecase // not usecases
package repository // not repositories
package entity // not entities
// Entity struct: PascalCase, no suffix
type User struct { ... } // not UserModel, UserEntity
// Value Object: base type alias + methods
type Status string // not StatusEnum
// Interface: defined in pkg/domain/, semantic naming
type UserRepository interface { ... } // not UserRepo or UserRepositoryI
// Use Case struct: {Module}Usecase
type AccountUsecase struct { ... }
// Use Case methods: verb prefix
func (uc *AccountUsecase) CreateUser(ctx context.Context, ...) (*entity.User, error)
func (uc *AccountUsecase) GetUser(ctx context.Context, id string) (*entity.User, error)
// Logic struct: {Operation}Logic
type CreateUserLogic struct { ... }
// Error: Err prefix
var ErrUserNotFound = errors.New("user not found")
// Constant: PascalCase (exported) or camelCase (internal)
const MaxRetryCount = 3
const defaultPageSize = 20
```
### Error Handling
```go
// Sentinel errors — pkg/domain/errors.go
var (
ErrUserNotFound = errors.New("user not found")
ErrInvalidInput = errors.New("invalid input")
ErrDuplicateEmail = errors.New("email already exists")
)
// Error wrapping — always use %w
if err != nil {
return fmt.Errorf("create user: %w", err)
}
// Error checking — always use errors.Is
if errors.Is(err, domain.ErrUserNotFound) {
// handle not found
}
// Repository errors — pkg/repository/error.go
var (
ErrMongoConnection = errors.New("mongo connection failed")
ErrRedisConnection = errors.New("redis connection failed")
)
```
### Interface Design
```go
// Interface defined in pkg/domain/ (consumer side)
// Implementation defined in pkg/ (provider side)
// Accept interfaces, return structs
func NewUserUsecase(repo repository.UserRepository, redis *redis.Client) *UserUsecase {
return &UserUsecase{repo: repo, redis: redis}
}
// Keep interfaces small (1-3 methods)
type UserRepository interface {
GetByID(ctx context.Context, id string) (*entity.User, error)
Create(ctx context.Context, user *entity.User) error
}
```
## TDD Standards
This skill integrates with `tdd` skill, following shared TDD principles.
### Test Pyramid
```
/\
/ \
/ E2E \ <- Few critical flows
/--------\
/Integration\ <- DB + Redis (testcontainers)
/--------------\
/ Unit Tests \ <- Most, 80%+ coverage
/--------------------\
```
### Test Location
```
Test files in same directory as source:
pkg/domain/member/status_test.go ← Value object tests
pkg/usecase/create_user_test.go ← Use Case tests
pkg/repository/user_test.go ← Repository tests
pkg/repository/start_mongo_container_test.go ← testcontainers startup
```
### Vertical Slice TDD
Each slice follows this order:
```
Slice: User registration
1. RED: Write TestStatus_IsValid (value object)
2. GREEN: Write Status.IsValid()
3. RED: Write TestAccountUsecase_CreateUser_Success
4. GREEN: Write domain/entity, domain/usecase interface, pkg/usecase implementation, mock
5. RED: Write TestAccountUsecase_CreateUser_DuplicateEmail
6. GREEN: Add duplicate check
7. RED: Write TestUserRepository_Create (DB test)
8. GREEN: Write pkg/repository/user.go
9. RED: Write TestCreateUserLogic (handler test)
10. GREEN: Write internal/logic/account/create_user_logic.go
11. REFACTOR: Clean up everything
```
### Mock Strategy
```go
// Use mockery to auto-generate mocks
// Add go:generate directive in interface file
//go:generate mockery --name=UserRepository --output=../../mock/repository --outpkg=mock_repository
// Unit tests use mock
func TestAccountUsecase_CreateUser_Success(t *testing.T) {
mockRepo := new(mock_repository.UserRepository)
uc := usecase.NewAccountUsecase(mockRepo, nil, nil)
mockRepo.On("GetByEmail", mock.Anything, "test@example.com").Return(nil, nil)
mockRepo.On("Create", mock.Anything, mock.AnythingOfType("*entity.User")).Return(nil)
user, err := uc.CreateUser(context.Background(), input)
assert.NoError(t, err)
assert.NotNil(t, user)
}
```
### testcontainers Strategy
```go
// pkg/repository/start_mongo_container_test.go
func startMongoContainer(t *testing.T) *mongo.Database {
ctx := context.Background()
req := testcontainers.ContainerRequest{
Image: "mongo:7",
ExposedPorts: []string{"27017/tcp"},
WaitingFor: wait.ForListeningPort("27017/tcp"),
}
mongoC, err := testcontainers.GenericContainer(ctx, testcontainers.GenericContainerRequest{
ContainerRequest: req,
Started: true,
})
require.NoError(t, err)
t.Cleanup(func() {
mongoC.Terminate(ctx)
})
// ... return connected database
}
```
### Coverage Requirements
- Value objects (`pkg/domain/member/`): >= 90%
- Use Case (`pkg/usecase/`): >= 90%
- Repository (`pkg/repository/`): >= 80%
- Logic (`internal/logic/`): >= 80% (mainly integration tests)
- Critical paths: Integration tests required
## Vertical Slice Template
File list for each vertical slice:
```
Slice: {operation}_{entity}
New/modified files:
├── pkg/domain/entity/{entity}.go ← Entity definition
├── pkg/domain/member/{value_object}.go ← Value object (if needed)
├── pkg/domain/member/{value_object}_test.go ← Value object tests
├── pkg/domain/repository/{entity}.go ← Repository interface
├── pkg/domain/usecase/{module}.go ← Use Case interface
├── pkg/usecase/{operation}.go ← Use Case implementation
├── pkg/usecase/{operation}_test.go ← Use Case tests
├── pkg/mock/repository/{entity}.go ← Repository mock
├── pkg/repository/{entity}.go ← Repository implementation
├── pkg/repository/{entity}_test.go ← Repository tests
├── internal/logic/{module}/{operation}_logic.go ← Handler logic
└── internal/svc/service_context.go ← Update DI
```
## Completion Checklist
### After Each Slice
- [ ] Value object tests pass
- [ ] Use Case tests pass
- [ ] Repository tests pass (with DB)
- [ ] Error handling complete
- [ ] Dependency direction correct (domain has no external dependencies)
### After All Complete
- [ ] Project structure follows Domain-Driven + go-zero style
- [ ] `pkg/domain/` contains all Entity, Value Object, interface definitions
- [ ] `pkg/usecase/` contains all business logic implementations
- [ ] `pkg/repository/` contains all infrastructure implementations
- [ ] `internal/logic/` contains all Handler logic
- [ ] `internal/svc/` contains complete dependency injection setup
- [ ] Unit tests >= 80% coverage
- [ ] Business logic >= 90% coverage
- [ ] Integration tests pass (critical paths)
- [ ] Error handling consistent and uses `%w` wrapping
## Related Skills
- **Prerequisite**: `prd-to-plan` (implementation plan), `be-api-design` (API spec), `dba-schema` (DB Schema)
- **辅助**: `tdd` (TDD Red-Green-Refactor process), `design-an-interface` (interface design)
- **Follow-up**: `qa` (QA testing)
## Rollback Mechanism
```
QA failed (Stage 10)
Orchestrator re-assigns fix task
Backend Agent fixes bug + adds regression test
Re-enter QA (Stage 10)
Code Review rejected (Stage 10)
Handle PR feedback
Re-enter QA (Stage 10) for verification
Implementation plan not feasible
Return to Task Breakdown (Stage 8) for re-decomposition

203
skills/prd-to-plan/SKILL.md Normal file
View File

@ -0,0 +1,203 @@
---
name: prd-to-plan
description: "Converts PRD into a multi-phase implementation plan using vertical slices (tracer bullets). Orchestrator uses this skill at Stage 8 to produce implementation plans for Stage 9 Backend/Frontend Agent implementation. Trigger: After Design Review passes, when Orchestrator performs Task Breakdown."
---
# /prd-to-plan — PRD to Implementation Plan
Orchestrator uses this skill to convert PRD into vertical slice implementation plans.
## Responsibilities
1. Confirm PRD content is complete and in context
2. Explore existing codebase to understand architecture and patterns
3. Identify persistent architectural decisions across phases
4. Decompose PRD into vertical slices (tracer bullets)
5. Confirm slice granularity with user
6. Produce implementation plan document
## Input
- PRD document (`docs/prd/{date}-{feature}.md`)
- API specification (`docs/api/{date}-{feature}.yaml`)
- DB Schema (`docs/db/{date}-{feature}.sql`)
- Design documents (`docs/design/{date}-{feature}/`)
## Output
- Implementation plan: `./plans/{feature}.md`
## Process
```
Confirm PRD in context
Explore codebase (architecture, patterns, integration layers)
Identify persistent architectural decisions (routes, schema, models, auth)
Draft vertical slice decomposition
Confirm slice granularity with user
Iterate until user approves
Write plan file
```
### Step Details
**1. Confirm PRD in context**
The PRD should already be in the conversation. If not, ask the user to paste or point to the file.
**2. Explore codebase**
If the codebase hasn't been explored yet, explore to understand:
- Current architectural patterns
- Existing code conventions
- Integration layers (DB, API, external services)
- Existing test patterns
**3. Identify persistent architectural decisions**
Before slicing, identify high-level decisions unlikely to change during implementation:
- Route structure / URL patterns
- Database schema shape
- Key data models
- Authentication / authorization approach
- Third-party service boundaries
Write these decisions in the plan file header for all phases to reference.
**4. Draft vertical slices**
Decompose PRD into **tracer bullet** phases. Each phase is a thin vertical slice cutting through all integration layers end-to-end, **not** horizontal slicing.
**Vertical slice principles:**
- Each slice delivers a narrow but complete path through all layers (schema, API, usecase, logic, tests)
- Completed slices can be demonstrated or verified independently
- Prefer multiple thin slices over few thick slices
- Don't include specific filenames, function names, or implementation details that may change with subsequent phases
- Include persistent decisions: route paths, schema shapes, data model names
**Horizontal slice (wrong) vs Vertical slice (correct):**
```
❌ Horizontal slice:
Phase 1: All domain entities
Phase 2: All usecases
Phase 3: All API handlers
Phase 4: All repository implementations
✅ Vertical slice (tracer bullets):
Phase 1: User registration (entity + usecase + handler + repo + tests)
Phase 2: User login (same)
Phase 3: User list (same)
Phase 4: User profile update (same)
```
**5. Confirm with user**
Present decomposition as a numbered list, each phase containing:
- **Title**: Brief descriptive name
- **User stories covered**: Which user stories from PRD this maps to
Ask the user:
- How does the granularity feel? (too coarse / too fine)
- Need to merge or split any phases?
Iterate until user approves.
**6. Write plan file**
Create `./plans/` directory (if it doesn't exist). Write Markdown file.
## Plan Template
```markdown
# Plan: {Feature Name}
> Source PRD: {PRD link or identifier}
> Source API: {API specification link}
> Source DB Schema: {DB Schema link}
## Architectural Decisions
Persistent decisions across all phases:
- **Routes**: {API route structure}
- **Schema**: {database schema shape}
- **Key models**: {key data models}
- **Auth**: {authentication/authorization approach}
- **Third-party services**: {external service boundaries}
---
## Phase 1: {Title}
**User stories**: {list of user stories from PRD}
### What to build
End-to-end behavior description for this vertical slice. Describe complete behavior, not layer-by-layer implementation details.
### Acceptance criteria
- [ ] Acceptance criteria 1
- [ ] Acceptance criteria 2
- [ ] Acceptance criteria 3
---
## Phase 2: {Title}
**User stories**: {list of user stories from PRD}
### What to build
...
### Acceptance criteria
- [ ] ...
---
<!-- Repeat for each Phase -->
```
## Role in Vibe-Kanban
```
Stage 7: Design Review passes
Stage 8: Task Breakdown (Orchestrator uses prd-to-plan)
Output ./plans/{feature}.md
Stage 9: Implementation (Backend/Frontend Agent implements according to plan)
```
Orchestrator will parse the plan and:
1. Identify frontend and backend tasks
2. Assign to corresponding agents
3. May trigger parallel task distribution
## Dependent Skills
- **Prerequisite**: `write-a-prd` (PRD complete), `be-api-design` (API spec), `dba-schema` (DB Schema), `design-review` (design review passed)
- **Follow-up**: `go-backend-dev` (Backend implementation), frontend implementation skill
## Rollback Mechanism
```
Implementation plan infeasible
Rollback to Stage 7 (Design Review) for re-review
or
Rollback to Stage 4 (API Design) to adjust design
```

296
skills/tdd/SKILL.md Normal file
View File

@ -0,0 +1,296 @@
---
name: tdd
description: "Backend Agent uses this skill for Test-Driven Development. Follows Red-Green-Refactor cycle and vertical slicing principles, ensuring tests cover behavior rather than implementation details. Trigger: Implementation phase (Stage 9), integrated with go-backend-dev skill."
---
# /tdd — Test-Driven Development
Backend Agent uses this skill for Test-Driven Development.
## Core Philosophy
**Test behavior, not implementation details.**
Good tests verify behavior through public interfaces, describing the system "what" it does, not "how" it does it. Tests still pass after refactoring.
Bad tests are coupled to implementation: mocking internal collaborators, testing private methods. Tests fail after refactoring, but behavior hasn't changed.
## Anti-Pattern: Horizontal Slicing
**Don't write all tests first, then all implementations.** This is "horizontal slicing":
```
❌ Wrong way:
RED: test1, test2, test3, test4, test5
GREEN: impl1, impl2, impl3, impl4, impl5
✅ Correct way (vertical slicing):
RED→GREEN: test1 → impl1
RED→GREEN: test2 → impl2
RED→GREEN: test3 → impl3
```
Horizontal slicing produces low-quality tests:
- Tests written early verify "imagined" behavior, not "actual" behavior
- Tests become validators of data structures and function signatures, not user-observable behavior
- Tests are insensitive to real changes — they pass when behavior is broken, fail when behavior hasn't changed but after refactoring
## Flow
```
Confirm interface changes and test scope
Write first test (tracer bullet)
RED: Test fails
GREEN: Write minimal code to make test pass
Write next test
RED → GREEN loop
All behavior tests complete
REFACTOR: Refactor
Confirm all tests still pass
```
### Step Details
**1. Planning**
Before writing any code:
- [ ] Confirm which interface changes are needed with user
- [ ] Confirm which behaviors need testing (prioritize)
- [ ] Identify opportunities for deep modules (small interface, deep implementation)
- [ ] Design interfaces for testability
- [ ] List behaviors to test (not implementation steps)
- [ ] Get user approval for test plan
Ask: "What should the public interface look like? Which behaviors are most important to test?"
**You cannot test everything.** Confirm with user which behaviors are most important, focus testing effort on critical paths and complex logic, not every possible edge case.
**2. Tracer Bullet**
Write a test that confirms one thing about the system:
```
RED: Write first behavior test → Test fails
GREEN: Write minimal code to make test pass → Test passes
```
This is your tracer bullet — proving the end-to-end path works.
**3. Incremental Loop**
For each remaining behavior:
```
RED: Write next test → Fails
GREEN: Minimal code to make test pass → Passes
```
Rules:
- One test at a time
- Write only enough code to make current test pass
- Don't predict future tests
- Tests focus on observable behavior
**4. Refactoring**
After all tests pass, look for refactoring candidates:
- [ ] Extract duplicate logic
- [ ] Deepen modules (move complexity behind simple interfaces)
- [ ] Apply SOLID principles naturally
- [ ] Consider what new code reveals about existing code problems
- [ ] Run tests after each refactoring step
**Never refactor while in RED state. Get back to GREEN first.**
## Good Tests vs Bad Tests
### Good Tests
**Integration style**: Test through real interfaces, not mocking internal parts.
```go
// GOOD: Test observable behavior
func TestUserUsecase_CreateUser_Success(t *testing.T) {
mockRepo := new(mock.UserRepository)
uc := NewUserUsecase(mockRepo, logger)
mockRepo.On("GetByEmail", mock.Anything, "test@example.com").Return(nil, nil)
mockRepo.On("Create", mock.Anything, mock.AnythingOfType("*domain.User")).Return(nil)
user, err := uc.CreateUser(context.Background(), input)
assert.NoError(t, err)
assert.NotNil(t, user)
assert.Equal(t, "test@example.com", user.Email)
}
```
Characteristics:
- Tests behavior that users/callers care about
- Uses only public APIs
- Tests still pass after internal implementation refactoring
- Describes "what" instead of "how"
- One logical assertion per test
### Bad Tests
**Implementation detail testing**: Coupled to internal structure.
```go
// BAD: Test implementation details
func TestUserUsecase_CreateUser_CallsRepoCreate(t *testing.T) {
mockRepo := new(mock.UserRepository)
uc := NewUserUsecase(mockRepo, logger)
uc.CreateUser(context.Background(), input)
// This tests "how" instead of "what"
mockRepo.AssertCalled(t, "Create", mock.Anything, mock.Anything)
}
```
Red flags:
- Mocking internal collaborators just to verify they were called
- Testing private methods
- Asserting call counts or order
- Tests fail after refactoring but behavior unchanged
- Test names describe "how" instead of "what"
```go
// BAD: Bypass interface validation
func TestCreateUser_SavesToDatabase(t *testing.T) {
CreateUser(ctx, input)
row := db.QueryRow("SELECT * FROM users WHERE name = $1", "Alice")
// Direct database query, bypassing public interface
}
// GOOD: Validate through interface
func TestCreateUser_MakesUserRetrievable(t *testing.T) {
user, _ := CreateUser(ctx, input)
retrieved, _ := GetUser(ctx, user.ID)
assert.Equal(t, "Alice", retrieved.Name)
// Validate behavior through public interface
}
```
## Golang Testing Standards
### Test Naming
```go
// Test{Unit}_{Scenario}
func TestUserUsecase_CreateUser_Success(t *testing.T) {}
func TestUserUsecase_CreateUser_InvalidEmail(t *testing.T) {}
func TestUserUsecase_CreateUser_Duplicate(t *testing.T) {}
```
### Test Pyramid
```
/\
/ \
/ E2E \ <- Few critical flows
/--------\
/Integration\ <- API + DB
/--------------\
/ Unit Tests \ <- Most, 80%+ coverage
/--------------------\
```
### Mock Strategy
Only mock at **system boundaries**:
- External APIs (payments, email, etc.)
- Database (sometimes — prefer test DB)
- Time/randomness
- File system (sometimes)
Don't mock:
- Your own classes/modules
- Internal collaborators
- Things you can control
```go
// Use mockery to auto-generate mocks
//go:generate mockery --name=UserRepository
// Unit tests use mock repo
func TestUserUsecase_CreateUser_Success(t *testing.T) {
mockRepo := new(mock.UserRepository)
uc := NewUserUsecase(mockRepo, logger)
mockRepo.On("GetByEmail", mock.Anything, "test@example.com").Return(nil, nil)
mockRepo.On("Create", mock.Anything, mock.AnythingOfType("*domain.User")).Return(nil)
user, err := uc.CreateUser(context.Background(), input)
assert.NoError(t, err)
assert.NotNil(t, user)
}
```
## Interface Design for Testability
Good interfaces make testing natural:
**1. Accept dependencies, don't create them**
```go
// Testable
func (s *UserService) CreateUser(ctx context.Context, input CreateUserInput, repo UserRepository) (*User, error) {}
// Hard to test
func (s *UserService) CreateUser(ctx context.Context, input CreateUserInput) (*User, error) {
repo := postgres.NewUserRepository(db) // Creates dependency
}
```
**2. Return results, don't produce side effects**
```go
// Testable
func CalculateDiscount(cart *Cart) Discount {}
// Hard to test
func ApplyDiscount(cart *Cart) {
cart.Total -= discount // Mutates input
}
```
**3. Small interface surface area**
- Fewer methods = fewer tests to write
- Fewer parameters = simpler test setup
## Checklist for Each Cycle
```
[ ] Test describes behavior, not implementation
[ ] Test uses only public interfaces
[ ] Test still passes after internal refactoring
[ ] Code is minimal implementation to make current test pass
[ ] No speculative features
```
## Refactoring Candidates
After TDD cycle completes, look for:
- **Duplicate logic** → Extract function/class
- **Too long methods** → Split into private helpers (keep tests on public interface)
- **Shallow modules** → Merge or deepen
- **Feature envy** → Move logic to where the data is
- **Primitive obsession** → Introduce value objects
- **New code revealing existing code problems**
## Related Skills
- **Prerequisite**: `go-backend-dev` (used in implementation)
- **辅助**: `design-an-interface` (design interfaces for testability)
- **Follow-up**: `qa` (QA testing)