6.4 KiB
6.4 KiB
Go Code Quality Standards
Reference guide for reviewing Go code quality in PRs.
Common Issues to Watch For
Error Handling
Bad:
result, _ := doSomething()
Good:
result, err := doSomething()
if err != nil {
return fmt.Errorf("failed to do something: %w", err)
}
Context Propagation
Bad:
func handleRequest(c *gin.Context) {
result := callExternalAPI() // No timeout
}
Good:
func handleRequest(c *gin.Context) {
ctx := c.Request.Context()
result, err := callExternalAPIWithContext(ctx)
}
Resource Cleanup
Bad:
file, _ := os.Open("data.txt")
// Missing Close()
Good:
file, err := os.Open("data.txt")
if err != nil {
return err
}
defer file.Close()
Hardcoded Values
Bad:
timeout := 30 * time.Second
apiURL := "https://api.example.com"
Good:
const defaultTimeout = 30 * time.Second
apiURL := os.Getenv("API_URL")
if apiURL == "" {
return errors.New("API_URL environment variable required")
}
Swag Documentation Standards
Complete Handler Documentation
// GetFile godoc
//
// @Summary Retrieve file by ID
// @Description Returns detailed information about a specific file including metadata, permissions, and sharing status
// @Tags files
// @Accept json
// @Produce json
// @Param id path string true "File ID"
// @Param X-Tenant-ID header string true "Tenant identifier"
// @Success 200 {object} model.File
// @Failure 400 {string} string "Invalid file ID"
// @Failure 404 {string} string "File not found"
// @Failure 500 {string} string "Internal server error"
// @Router /v1/files/{id} [get]
func GetFile(c *gin.Context) {
// implementation
}
Required Swag Elements
- @Summary - One line description (< 120 chars)
- @Description - Detailed explanation of behavior
- @Tags - Logical grouping (files, folders, sessions, etc.)
- @Accept - Content-Type accepted (if body expected)
- @Produce - Content-Type returned
- @Param - Document EVERY parameter (path, query, header, body)
- @Success - All successful response codes with types
- @Failure - All error response codes with descriptions
- @Router - Exact route path and HTTP method
Common Swag Mistakes
- Missing
@Paramfor headers (X-Tenant-ID, Authorization) - Incomplete
@Failuredocumentation (only documenting 400/500) - Generic descriptions ("Get file" vs "Retrieve file with metadata and permissions")
- Wrong model references (string vs object)
- Missing
@Accepton POST/PUT handlers
Project-Specific Patterns
SQL Style
Use lowercase SQL keywords:
query := "select id, name from users where active = ?"
Not:
query := "SELECT id, name FROM users WHERE active = ?"
Layer Separation
- Handlers (
/internal/server/): HTTP routing, request/response mapping - Service (
/internal/service/): Business logic, validation, orchestration - API Clients (
/internal/api/): External service communication
Don't put business logic in handlers or HTTP code in services.
Database Operations
Prefer stored procedures for complex queries:
- Type-safe parameters
- Optimized execution
- Centralized logic
Test Organization
- Unit tests:
/internal/service/*_test.go - Integration tests:
/api-tests/*_test.go - Helpers:
/api-tests/helpers/*.go
Security Checklist
- No secrets in code (use env vars)
- All user inputs validated
- Authentication checks on protected endpoints
- Authorization checks for resource access
- SQL queries use parameterization (no string concatenation)
- Sensitive data not logged
- CORS configured appropriately
- Rate limiting considered for public endpoints
Performance Considerations
- Database queries are efficient (no N+1 queries)
- Appropriate indexes exist for queries
- Large lists are paginated
- File uploads handle streaming (not loading entire file in memory)
- Long operations use SSE for progress updates
- Context timeouts prevent hanging requests
- Connection pooling configured properly
Code Organization Red Flags
- God functions (>100 lines)
- Deep nesting (>4 levels)
- Duplicate code (consider extracting helper)
- Magic numbers without constants
- Inconsistent naming conventions
- Missing package documentation
- Circular dependencies between packages
Testing Red Flags
- Tests that don't assert anything
- Tests that sleep/use arbitrary timeouts
- Tests that depend on external services (without mocking)
- Tests that share state (global variables)
- Tests with no cleanup (leaked resources)
- Missing table-driven tests for multiple cases
- No error case testing
Documentation Standards
Anchor Comments for AI Review
Use these ONLY during development, remove before merge:
// AIDEV-NOTE:- Important business logic explanation// AIDEV-TODO:- Incomplete work or needed improvement// AIDEV-QUESTION:- Uncertainty or need for discussion
These should be reviewed and removed before PR approval.
Regular Comments
Only add comments when:
- Explaining non-obvious business rules
- Documenting complex algorithms
- Clarifying why (not what) code does something
- Warning about edge cases or gotchas
Don't comment obvious code:
// Bad: Obvious
// increment counter
counter++
// Good: Explains why
// Skip deleted items to maintain accurate active count
if !item.IsDeleted {
counter++
}
Go-Specific Best Practices
- Use
gofmtformatting (enforced bymake tidy) - Follow Effective Go guidelines
- Use short variable names in limited scopes (i, err, ok)
- Use descriptive names for package-level and exported items
- Prefer composition over inheritance
- Use interfaces for abstraction, not just for mocking
- Keep interfaces small and focused
- Return errors, don't panic (except in init() for fatal issues)
- Use
context.Contextfor cancellation and deadlines - Avoid global mutable state
Makefile Integration
Always verify the Makefile has these targets and run them:
make testormake test-unit- Unit tests must passmake test-api- Integration tests must passmake lint- Linting must pass with no errorsmake tidy- Code must be properly formattedmake docs- If Swag is used, docs must generate successfully
Failing any of these is grounds for requesting changes.