go-project-setup
Estrutura e setup de projetos Go idiomáticos. Use quando criar projeto Go, configurar módulo, ou revisar estrutura Go.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Estrutura e setup de projetos Go idiomáticos. Use quando criar projeto Go, configurar módulo, ou revisar estrutura Go.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
Acione o `tech-writer` para criar um novo Architecture Decision Record (ADR).
Template e guia para ADRs (Architecture Decision Records): quando criar, estrutura, exemplos. Use quando documentar decisões arquiteturais ou criar ADRs.
Padrões Android modernos: Kotlin, Jetpack Compose, MVVM, Hilt, Room, Navigation, Coroutines, testes. Use quando implementar features em Android nativo.
Padrões Angular modernos: Standalone Components, Signals, inject(), HttpClient, RxJS, Testing. Use quando implementar features em Angular ou configurar projeto Angular.
Migração AngularJS para Angular: estratégia incremental, ngUpgrade, dual-boot, padrões de coexistência. Use quando planejar ou executar migração de AngularJS (1.x) para Angular moderno.
Design de API REST seguindo boas práticas. Use quando pedirem para projetar API, definir endpoints, criar contrato REST ou OpenAPI.
| name | go-project-setup |
| description | Estrutura e setup de projetos Go idiomáticos. Use quando criar projeto Go, configurar módulo, ou revisar estrutura Go. |
| argument-hint | [contexto adicional] |
Guia para estruturar projetos Go seguindo convenções da comunidade.
myservice/
├── cmd/
│ └── server/
│ └── main.go # Entrypoint — wiring e inicialização
├── internal/
│ ├── domain/
│ │ ├── order.go # Entidades e regras de negócio
│ │ ├── order_test.go
│ │ └── repository.go # Interfaces de persistência
│ ├── handler/
│ │ ├── order.go # HTTP handlers
│ │ └── order_test.go
│ ├── service/
│ │ ├── order.go # Lógica de aplicação
│ │ └── order_test.go
│ ├── repository/
│ │ ├── postgres/
│ │ │ ├── order.go # Implementação PostgreSQL
│ │ │ └── order_test.go
│ │ └── dynamodb/
│ │ └── order.go # Implementação DynamoDB
│ └── config/
│ └── config.go # Configuração da aplicação
├── pkg/ # Só se houver reuso externo REAL
├── go.mod
├── go.sum
├── Makefile
└── Dockerfile
lambda-go/
├── cmd/
│ └── handler/
│ └── main.go # Lambda entrypoint
├── internal/
│ ├── domain/ # Lógica de negócio (testável sem AWS)
│ ├── handler/ # Handler que recebe evento
│ └── adapter/ # Integrações (DynamoDB, SQS, etc)
├── go.mod
├── go.sum
├── Makefile
└── Dockerfile
// ERRADO — interface no pacote que implementa
// repository/order.go
type OrderRepository interface { ... }
type postgresOrderRepo struct { ... }
// CORRETO — interface no pacote que consome
// service/order.go
type OrderRepository interface {
FindByID(ctx context.Context, id string) (*domain.Order, error)
Save(ctx context.Context, order *domain.Order) error
}
type OrderService struct {
repo OrderRepository // depende da interface, não da implementação
}
// SEMPRE receber context como primeiro parâmetro
func (s *OrderService) Process(ctx context.Context, orderID string) error {
order, err := s.repo.FindByID(ctx, orderID)
if err != nil {
return fmt.Errorf("finding order %s: %w", orderID, err)
}
// ...
}
// Erros de domínio tipados
type OrderNotFoundError struct {
ID string
}
func (e *OrderNotFoundError) Error() string {
return fmt.Sprintf("order %s not found", e.ID)
}
// Wrap com contexto — SEMPRE
result, err := s.repo.Save(ctx, order)
if err != nil {
return fmt.Errorf("saving order %s: %w", order.ID, err)
}
// Check por tipo — usar errors.As
var notFound *OrderNotFoundError
if errors.As(err, ¬Found) {
// handle not found
}
// Functional options para structs complexas
type Server struct {
addr string
timeout time.Duration
logger *slog.Logger
}
type Option func(*Server)
func WithTimeout(d time.Duration) Option {
return func(s *Server) { s.timeout = d }
}
func NewServer(addr string, opts ...Option) *Server {
s := &Server{addr: addr, timeout: 30 * time.Second, logger: slog.Default()}
for _, opt := range opts {
opt(s)
}
return s
}
logger := slog.New(slog.NewJSONHandler(os.Stdout, &slog.HandlerOptions{Level: slog.LevelInfo}))
logger.Info("order created",
slog.String("orderId", order.ID),
slog.String("customerId", order.CustomerID),
slog.Duration("duration", elapsed),
)
type Config struct {
Port int `env:"PORT" envDefault:"8080"`
DatabaseURL string `env:"DATABASE_URL,required"`
Timeout time.Duration `env:"TIMEOUT" envDefault:"30s"`
LogLevel string `env:"LOG_LEVEL" envDefault:"info"`
}
// Usar: github.com/caarlos0/env/v11
func LoadConfig() (*Config, error) {
cfg := &Config{}
if err := env.Parse(cfg); err != nil {
return nil, fmt.Errorf("parsing config: %w", err)
}
return cfg, nil
}
func main() {
cfg, err := config.LoadConfig()
if err != nil {
slog.Error("failed to load config", "error", err)
os.Exit(1)
}
// Wiring
repo := postgres.NewOrderRepository(db)
svc := service.NewOrderService(repo)
h := handler.NewOrderHandler(svc)
// Router
r := chi.NewRouter()
r.Use(middleware.RequestID, middleware.RealIP, middleware.Logger, middleware.Recoverer)
r.Route("/api/v1", func(r chi.Router) {
r.Get("/orders/{id}", h.GetOrder)
r.Post("/orders", h.CreateOrder)
})
r.Get("/health", func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusOK)
})
// Graceful shutdown
srv := &http.Server{Addr: fmt.Sprintf(":%d", cfg.Port), Handler: r}
go func() {
if err := srv.ListenAndServe(); err != nil && err != http.ErrServerClosed {
slog.Error("server error", "error", err)
}
}()
quit := make(chan os.Signal, 1)
signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)
<-quit
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
srv.Shutdown(ctx)
}
.PHONY: build test lint run
build:
go build -ldflags="-s -w" -o bin/server ./cmd/server
test:
go test -race -cover ./...
lint:
golangci-lint run ./...
run:
go run ./cmd/server
cmd/ para entrypoints, internal/ para código privado?pkg/ somente com reuso externo justificado?context.Context como primeiro parâmetro?fmt.Errorf("context: %w", err)?panic como controle de fluxo?slog para logging estruturado?