一键导入
tdd-go
TDD workflow for dune-admin Go handlers and db.go functions. Use when adding a handler, implementing a feature, or fixing a bug in the Go backend.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
TDD workflow for dune-admin Go handlers and db.go functions. Use when adding a handler, implementing a feature, or fixing a bug in the Go backend.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
Scaffold a new full-stack tab for dune-admin — Go route+handler+db func, api/client.ts namespace, and React tab component following the BasesTab pattern.
Run before any git push or PR creation. Ensures gosec, vulncheck, tests, and lint all pass — and that the user has approved the commit.
| name | tdd-go |
| description | TDD workflow for dune-admin Go handlers and db.go functions. Use when adding a handler, implementing a feature, or fixing a bug in the Go backend. |
Write the failing test first. No production code without a red test.
If the function depends on a DB call or external I/O, extract an interface:
type fooQuerier interface {
fetchFoo(ctx context.Context, id int64) (*fooRow, error)
}
Production code uses globalDB; tests inject a stub.
func TestHandleFoo(t *testing.T) {
tests := []struct {
name string
input string
stubResult *fooRow
stubErr error
wantStatus int
}{
{"happy path", "42", &fooRow{ID: 42}, nil, http.StatusOK},
{"db error → 500", "42", nil, errors.New("boom"), http.StatusInternalServerError},
{"bad id → 400", "abc", nil, nil, http.StatusBadRequest},
{"nil db → 503", "42", nil, nil, http.StatusServiceUnavailable},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
// set up stub, call handler, assert tt.wantStatus
})
}
}
Run make test-race — confirm it fails before writing implementation.
Handler structure:
func handleGetFoo(w http.ResponseWriter, r *http.Request) {
if globalDB == nil {
jsonErr(w, errors.New("database not connected"), http.StatusServiceUnavailable)
return
}
id, err := strconv.ParseInt(r.PathValue("id"), 10, 64)
if err != nil {
jsonErr(w, fmt.Errorf("invalid id"), http.StatusBadRequest)
return
}
result, err := cmdFetchFoo(r.Context(), globalDB, id)
if err != nil {
if errors.Is(err, errNotFound) {
jsonErr(w, fmt.Errorf("not found"), http.StatusNotFound)
return
}
log.Printf("handleGetFoo: %v", err)
jsonErr(w, fmt.Errorf("internal error"), http.StatusInternalServerError)
return
}
jsonOK(w, result)
}
DB function in db.go:
func cmdFetchFoo(ctx context.Context, db *pgxpool.Pool, id int64) (*fooRow, error) {
row := db.QueryRow(ctx, `SELECT id, name FROM dune.foos WHERE id = $1`, id)
var f fooRow
if err := row.Scan(&f.ID, &f.Name); err != nil {
if errors.Is(err, pgx.ErrNoRows) {
return nil, errNotFound
}
return nil, fmt.Errorf("fetch foo %d: %w", id, err)
}
return &f, nil
}
make test-race # all tests pass, no races
make gosec # no new findings (not covered by make verify)
make verify # full suite
db.go, uses dune. schema prefixglobalDB == nil guard presentmake test-race greenmake gosec clean