Go project structure -- cmd/internal layout, handler/service/repository layers, Makefile, config from environment, domain error types, test placement, dependency injection
90
84%
Does it follow best practices?
Impact
100%
1.02xAverage score across 5 eval scenarios
Passed
No known issues
{
"context": "Tests whether the agent scaffolds a Go payment microservice with proper cmd/internal layout, handler/service/repository layers, domain error types, config from environment, Makefile, test placement, and dependency injection.",
"type": "weighted_checklist",
"checklist": [
{
"name": "cmd/server/main.go entry point",
"description": "main.go is in cmd/server/ (or cmd/<name>/) and contains dependency wiring and server startup only -- no HTTP handler logic or SQL queries",
"max_score": 8
},
{
"name": "internal/ directory used",
"description": "Application packages are inside internal/ directory (internal/handler/, internal/service/, internal/repository/, etc.)",
"max_score": 8
},
{
"name": "Handler layer separated",
"description": "HTTP handlers are in internal/handler/ package with a Handler struct, constructor, and route registration method. Handlers call service methods, not database queries directly.",
"max_score": 7
},
{
"name": "Service layer with interface",
"description": "Business logic is in internal/service/ package. The service defines an interface for its repository dependency (e.g., PaymentRepository interface) rather than depending on concrete types.",
"max_score": 8
},
{
"name": "Repository layer separated",
"description": "Database queries are in internal/repository/ (or internal/store/) package, separate from handlers and service logic",
"max_score": 7
},
{
"name": "Domain models in own package",
"description": "Domain types (Payment, PaymentStatus, CreatePaymentRequest) are in internal/domain/ or internal/model/ package",
"max_score": 6
},
{
"name": "Domain error types",
"description": "Domain error types (AppError, NotFoundError, ValidationError) are defined in the domain package with HTTP status codes, not scattered across handlers",
"max_score": 7
},
{
"name": "Config from environment",
"description": "Configuration is in internal/config/ with a Config struct that loads from environment variables (os.Getenv or envconfig) with defaults -- not hardcoded values",
"max_score": 7
},
{
"name": "go.mod with module path",
"description": "go.mod exists with a proper module path set",
"max_score": 5
},
{
"name": "Makefile with standard targets",
"description": "Makefile exists with at least build, test, and run targets. Test target uses go test ./...",
"max_score": 6
},
{
"name": "Test files alongside source",
"description": "At least one _test.go file exists in the same directory as its source code (e.g., internal/service/payments_test.go), NOT in a separate tests/ directory",
"max_score": 7
},
{
"name": "Table-driven tests",
"description": "Tests use table-driven pattern with test case structs and t.Run() subtests",
"max_score": 5
},
{
"name": ".gitignore for Go",
"description": ".gitignore exists and includes bin/, coverage.out or *.test, and .env",
"max_score": 4
},
{
"name": "Constructor-based DI in main.go",
"description": "main.go wires dependencies using constructor functions (e.g., NewOrderRepo -> NewOrderService -> NewHandler), not global variables",
"max_score": 6
},
{
"name": "Graceful shutdown",
"description": "main.go includes signal handling for graceful shutdown (os.Signal, syscall.SIGTERM)",
"max_score": 4
}
]
}