一键导入
go-refactor
Use when refactoring Go code, cleaning up legacy codebases, optimizing performance, or enforcing clean architecture boundaries in a Go/Fiber backend
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Use when refactoring Go code, cleaning up legacy codebases, optimizing performance, or enforcing clean architecture boundaries in a Go/Fiber backend
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
Use when the user wants to free disk space, investigate disk usage, clean caches, remove unused artifacts, or when disk capacity is high. Also use when asked to "clean up", "free space", "disk full", or "what's using disk space". Always uses AskUserQuestion for every deletion decision.
Use at the start of every conversation and for every user message — orchestrates the full engineering skills suite by understanding intent, clarifying requirements interactively, and invoking the right skills
Use when refactoring Python code, cleaning up legacy codebases, optimizing performance, enforcing type safety, or improving clean architecture in a FastAPI backend
Use when refactoring React components, cleaning up legacy frontends, optimizing performance, improving component architecture, or reducing bundle size
Use when reviewing changed code before committing or after completing a feature — checks performance, architecture, type safety, and code quality against project standards
Use after any skill completes work that changes project structure, conventions, commands, environment variables, dependencies, or architecture — proactively updates CLAUDE.md so future sessions inherit current project state
| name | go-refactor |
| description | Use when refactoring Go code, cleaning up legacy codebases, optimizing performance, or enforcing clean architecture boundaries in a Go/Fiber backend |
Safe refactoring patterns and performance optimization for Go backends. Always characterize before changing.
Core principle: Never refactor without characterization tests. Never optimize without profiling.
3-strikes rule: If the same refactoring approach fails 3 times, stop. The problem is architectural — escalate to system-design for a deeper review instead of thrashing.
The dependency rule: Dependencies point inward. Domain imports nothing external.
interfaces → application → domain
infrastructure → domain
Violations to check:
# Domain should not import infrastructure or interfaces
grep -r "infrastructure\|interfaces\|fiber\|pgx\|sqlalchemy" internal/domain/
# Application should not import infrastructure
grep -r "infrastructure\|pgx\|redis" internal/application/
| Smell | Move |
|---|---|
| Fat handler | Extract use case |
| Duplicate validation | Extract domain value object |
| Concrete dependency | Extract interface + inject |
| Sequential I/O | errgroup for concurrent calls |
| God struct | Split by responsibility |
| Copy-paste handlers | Extract middleware |
// Before: handler directly uses concrete repo
type Handler struct { repo *postgres.UserRepo }
// After: handler uses interface from domain
type Handler struct { repo domain.UserRepository }
g, ctx := errgroup.WithContext(ctx)
var users []domain.User
var posts []domain.Post
g.Go(func() error {
var err error
users, err = userRepo.List(ctx)
return err
})
g.Go(func() error {
var err error
posts, err = postRepo.List(ctx)
return err
})
if err := g.Wait(); err != nil {
return err
}
import _ "net/http/pprof"
// In main.go, add alongside Fiber:
go http.ListenAndServe(":6060", nil)
# CPU profile
go tool pprof http://localhost:6060/debug/pprof/profile?seconds=30
# Memory profile
go tool pprof http://localhost:6060/debug/pprof/heap
# Goroutine dump
curl http://localhost:6060/debug/pprof/goroutine?debug=2
-- Always check query plans
EXPLAIN ANALYZE SELECT * FROM users WHERE email = 'test@test.com';
N+1 detection: If you see N queries for N items in logs, fix with JOIN or batch query.
// Bad: N+1
for _, user := range users {
posts, _ := postRepo.GetByUserID(ctx, user.ID)
}
// Good: batch
posts, _ := postRepo.GetByUserIDs(ctx, userIDs)
config, _ := pgxpool.ParseConfig(connStr)
config.MaxConns = 25
config.MinConns = 5
config.MaxConnLifetime = 30 * time.Minute
config.MaxConnIdleTime = 5 * time.Minute
When working with legacy Go code that has no tests, bad structure, or mixed concerns:
Never change legacy code without characterization tests. Write tests that capture current behavior — even if the behavior is wrong. You need a safety net before refactoring.
// Characterization test: document what the code ACTUALLY does
func TestLegacy_CreateUser_CurrentBehavior(t *testing.T) {
// This test captures existing behavior, not desired behavior
// If this test breaks during refactoring, you changed behavior (not just structure)
result, err := legacyCreateUser(input)
assert.NoError(t, err)
assert.Equal(t, expectedOutput, result) // whatever it currently returns
}
Prioritize by risk, not by ugliness:
Don't rewrite — wrap and replace incrementally:
// 1. Extract interface from legacy code
type UserService interface {
Create(ctx context.Context, input CreateInput) (*User, error)
}
// 2. Legacy implementation stays as-is (for now)
type legacyUserService struct { db *sql.DB }
// 3. New implementation follows clean architecture
type cleanUserService struct { repo domain.UserRepository }
// 4. Feature flag or gradual rollover
func NewUserService(useLegacy bool) UserService {
if useLegacy { return &legacyUserService{} }
return &cleanUserService{}
}
// Before: legacy swallows errors
result, _ := db.Query(query)
// After: handle every error
result, err := db.Query(query)
if err != nil {
return fmt.Errorf("query users: %w", err)
}
# Find unused functions
grep -rn "^func " --include="*.go" | while read line; do
func_name=$(echo "$line" | grep -oP 'func \K\w+')
count=$(grep -rn "$func_name" --include="*.go" | wc -l)
[ "$count" -le 1 ] && echo "UNUSED: $line"
done
Delete it. Don't comment it out. Git has history.
superpowers:systematic-debugging for performance investigationclaude-md)fullstack-healthcheck first to prioritize what to fix