- Go 1.25+
- PostgreSQL (via pgx + sqlc)
- Fiber v2 (HTTP framework)
- MCP Go (MCP library)
project/
├── cmd/ # Executable scripts (E2E, validation)
├── docs/ # Documentation
├── internal/ # Application code
│ ├── api/ # HTTP layer
│ │ ├── bind/ # Request binding helpers
│ │ ├── handlers/ # Route handlers
│ │ ├── middleware/ # Middleware (error handling)
│ │ ├── response/ # Response helpers
│ │ └── api_init.go # Server initialization
│ ├── constants/ # Error definitions and other constants
│ ├── db/postgres/ # Database layer
│ │ ├── sql/query/ # SQL queries
│ │ ├── sql/schema/ # SQL schema
│ │ └── *.go # Generated code by sqlc (do not edit)
│ ├── logic/ # Business logic (by domain)
│ ├── mcp/ # MCP layer
│ │ ├── tool_definitions/ # Tool schemas
│ │ ├── tools/ # Tool handlers
│ │ └── mcp_init.go # Server initialization
│ └── types/ # Type definitions
│ ├── feature_*_types.go # Domain types (Input/Output)
│ └── mcp_server_types.go # MCP config types
├── swagger/ # Generated API docs
├── main.go
├── sqlc.yaml
└── go.mod
┌─────────────────────────────────────────────┐
│ Interface Layer │
│ ┌─────────────────┐ ┌─────────────────┐ │
│ │ API Handlers │ │ MCP Tools │ │
│ └────────┬────────┘ └────────┬────────┘ │
└───────────┼────────────────────┼────────────┘
│ │
▼ ▼
┌─────────────────────────────────────────────┐
│ Business Logic Layer │
│ internal/logic/ │
│ (Protocol-independent, shared) │
└─────────────────────┬───────────────────────┘
│
▼
┌─────────────────────────────────────────────┐
│ Data Access Layer │
│ internal/db/postgres/ │
│ (sqlc generated) │
└─────────────────────────────────────────────┘
Interface Layer (api/handlers/, mcp/tools/)
- Request parsing and validation format
- Authentication context extraction
- Response formatting
- Error transformation
- Logging
Business Logic Layer (logic/)
- Input validation (business rules)
- Domain operations
- Data transformation
- Database calls via queries
- DO NOT log in logic layer
Data Access Layer (db/postgres/)
- Type-safe SQL queries (sqlc generated)
- Transaction management
- The logic layer should be protocol-independent and can be shared via any interface.
- Use
InputorOutputsuffix for types in logic layer.- DO NOT use protocol-specific suffixes like
RequestBody/ResponseBody,
except for external services (because they're already protocol-specific).
- DO NOT use protocol-specific suffixes like
- All DB queries are generated by sqlc.
- DO NOT edit the generated files or edit/create the DB-related code in
internal/db/postgres/. - Edit the schema and query in
internal/db/postgres/sql/and runsqlc generate.
- DO NOT edit the generated files or edit/create the DB-related code in
- All errors should be defined in
internal/constants/errors.go.- DO NOT use
fmt.Errorforerrors.Newdirectly.
- DO NOT use
- Basic, and common logics are defined in
github.com/BeaverHouse/go-common, my public Go library.- ALWAYS consider this first.
- (Optional) Auth logics are defined in
gitlab.com/tiny-clover/auth, my private Go library in GitLab.- ALWAYS use this in auth related logics.
- Use other helper functions or existing code as much as possible.
- Always maintain a consistent structure and avoid code duplication.
- Always try to write self-explanatory, human-readable code.
- Only write comments when it is necessary and critical. Allowed examples are:
- For
go doc - For explaining the complex logic (= it's super hard to understand without comments)
- For
For specific code examples, see the codebase itself.
# After SQL changes
sqlc generate
# After API changes
swag init -o swagger
# After dependency changes
go mod tidy
# Before commit
go test ./...
go build ./...