Back to results

Filtered result set

53 / 83 matches

SkillHub ClubBuild BackendBackend

backend-dev-guidelines

Provides concrete implementation patterns for Go backend development using Chi router, PostgreSQL with sqlc, and Clean Architecture. Includes specific checklists for new features and services, layered architecture diagrams, and 8 key rules with code examples showing correct vs. incorrect approaches.

Packaged view

This page reorganizes the original catalog entry around fit, installability, and workflow context first. The original raw source lives below.

Stars
0
Hot score
74
Updated
March 20, 2026
Overall rating
A8.8
Composite score
5.6
Best-practice grade
B84.0

Install command

npx @skill-hub/cli install jhouser-actionphase-backend-dev-guidelines
go-developmentclean-architectureapi-guidelinessqlcchi-router

Repository

jhouser/actionphase

Skill path: .claude/skills/backend-dev-guidelines

Provides concrete implementation patterns for Go backend development using Chi router, PostgreSQL with sqlc, and Clean Architecture. Includes specific checklists for new features and services, layered architecture diagrams, and 8 key rules with code examples showing correct vs. incorrect approaches.

Open repository

Best for

Primary workflow: Build Backend.

Technical facets: Backend.

Target audience: Go developers building REST APIs with Chi router and PostgreSQL, especially teams adopting Clean Architecture and sqlc for type-safe database access.

License: Unknown.

Original source

Catalog source: SkillHub Club.

Repository owner: jhouser.

This is still a mirrored public skill entry. Review the repository before installing into production workflows.

What it helps with

  • Install backend-dev-guidelines into Claude Code, Codex CLI, Gemini CLI, or OpenCode workflows
  • Review https://github.com/jhouser/actionphase before adding backend-dev-guidelines to shared team environments
  • Use backend-dev-guidelines for backend workflows

Works across

Claude CodeCodex CLIGemini CLIOpenCode

Favorites: 0.

Sub-skills: 0.

Aggregator: No.

Original source / Raw SKILL.md

---
name: backend-dev-guidelines
description: Comprehensive backend development guide for Go/Chi/PostgreSQL with Clean Architecture. Use when creating routes, handlers, services, interfaces, middleware, working with Chi APIs, sqlc database access, JWT authentication, request validation, correlation IDs, or async patterns. Covers layered architecture (routes → handlers → services → database), interface-first development, error handling, observability, testing strategies, and service decomposition patterns.
---

# Backend Development Guidelines

## Purpose

Establish consistency and best practices for ActionPhase backend development using Go, Chi router, PostgreSQL with sqlc, and Clean Architecture principles.

## When to Use This Skill

Automatically activates when working on:
- Creating or modifying routes, endpoints, APIs
- Building handlers, services, interfaces
- Implementing middleware (auth, CORS, recovery, correlation IDs)
- Database operations with sqlc
- JWT authentication and refresh tokens
- Input validation and error handling
- Observability (structured logging, correlation IDs)
- Backend testing and refactoring
- Service decomposition

---

## Quick Start

### New Backend Feature Checklist

- [ ] **Migration**: Database schema changes (if needed)
- [ ] **SQL Queries**: Write queries in `queries/*.sql`
- [ ] **Code Generation**: Run `just sqlgen`
- [ ] **Interface**: Define in `core/interfaces.go`
- [ ] **Tests**: Write unit tests first (TDD)
- [ ] **Service**: Implement business logic
- [ ] **Handler**: HTTP request handling
- [ ] **API Tests**: Test endpoints with curl
- [ ] **Documentation**: Update API docs

### New Service Checklist

- [ ] Interface definition in `core/interfaces.go`
- [ ] Compile-time verification: `var _ Interface = (*Implementation)(nil)`
- [ ] Constructor function with dependencies
- [ ] Unit tests with mocks
- [ ] Error handling with correlation IDs
- [ ] Structured logging
- [ ] Input validation

---

## Architecture Overview

### Layered Architecture

```
HTTP Request
    ↓
Middleware (correlation ID, auth, CORS, recovery)
    ↓
Routes (Chi router)
    ↓
Handlers (request binding, validation)
    ↓
Services (business logic)
    ↓
sqlc Queries (type-safe SQL)
    ↓
PostgreSQL
```

**Key Principle:** Each layer has ONE responsibility.

**See**: `.claude/context/ARCHITECTURE.md` for complete details.

---

## Directory Structure

```
backend/
├── cmd/server/           # Application entry point
├── pkg/
│   ├── core/            # Domain models, interfaces, errors
│   │   ├── interfaces.go  # ALL service interfaces
│   │   ├── models.go      # Business entities
│   │   └── errors.go      # Typed errors
│   ├── db/
│   │   ├── queries/       # SQL files (*.sql)
│   │   ├── models/        # Generated by sqlc
│   │   ├── migrations/    # Schema migrations
│   │   └── services/      # Service implementations
│   │       ├── phases/    # Decomposed phase service
│   │       ├── actions/   # Decomposed action service
│   │       ├── messages/  # Decomposed message service
│   │       └── *.go       # Other services
│   ├── http/
│   │   ├── root.go        # Routing + middleware
│   │   ├── middleware/    # Custom middleware
│   │   └── */api.go       # HTTP handlers
│   └── util/             # Utilities
├── .env                  # Environment variables
└── justfile             # Development commands
```

**Naming Conventions:**
- Packages: `lowercase` - `services`, `middleware`
- Files: `snake_case.go` - `user_service.go`, `auth_api.go`
- Types: `PascalCase` - `GameService`, `UserHandler`
- Functions: `PascalCase` (exported), `camelCase` (private)
- Interfaces: `PascalCase + Interface` - `GameServiceInterface`

---

## Core Principles (8 Key Rules)

### 1. Interfaces First, Implementation Second

**ALL service interfaces MUST be defined in** `backend/pkg/core/interfaces.go`

```go
// ✅ ALWAYS: Define interface first
type GameServiceInterface interface {
    CreateGame(ctx context.Context, req *CreateGameRequest) (*Game, error)
    GetGame(ctx context.Context, id int) (*Game, error)
}

// ✅ ALWAYS: Compile-time verification
var _ GameServiceInterface = (*GameService)(nil)

type GameService struct {
    DB *pgxpool.Pool
}

func (s *GameService) CreateGame(ctx context.Context, req *CreateGameRequest) (*Game, error) {
    // Implementation
}
```

**Benefits**: Easy mocking, clear contracts, compile-time safety, dependency injection.

### 2. Use sqlc for Type-Safe SQL

```go
// ❌ NEVER: Raw SQL with manual mapping
row := db.QueryRow("SELECT id, title FROM games WHERE id = $1", id)
var game Game
row.Scan(&game.ID, &game.Title)

// ✅ ALWAYS: sqlc-generated queries
queries := db.New(pool)
game, err := queries.GetGame(ctx, id)
```

**Workflow**: Write SQL → `just sqlgen` → Use generated code

### 3. Handlers Only Handle HTTP, Services Contain Logic

```go
// ❌ NEVER: Business logic in handlers
func (h *Handler) CreateGame(w http.ResponseWriter, r *http.Request) {
    // 200 lines of validation, business logic, database calls
}

// ✅ ALWAYS: Delegate to service layer
func (h *Handler) CreateGame(w http.ResponseWriter, r *http.Request) {
    ctx := r.Context()
    correlationID := middleware.GetCorrelationID(ctx)

    var req core.CreateGameRequest
    if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
        core.WriteError(w, core.ErrInvalidRequest(err, correlationID))
        return
    }

    game, err := h.service.CreateGame(ctx, &req)
    if err != nil {
        core.WriteError(w, err)
        return
    }

    core.WriteJSON(w, http.StatusCreated, game)
}
```

### 4. Always Use Correlation IDs

```go
// Generate in middleware
correlationID := uuid.New().String()
ctx = context.WithValue(ctx, middleware.CorrelationIDKey, correlationID)

// Use in logging
log.Info().
    Str("correlation_id", correlationID).
    Str("user_id", userID).
    Msg("Game created")

// Include in errors
return core.ErrNotFound("game", gameID, correlationID)
```

### 5. Structured Logging with Context

```go
// ✅ ALWAYS: Use zerolog with structured fields
log.Info().
    Str("correlation_id", correlationID).
    Str("user_id", userID).
    Int("game_id", gameID).
    Str("action", "create_game").
    Msg("Game created successfully")

// ❌ NEVER: fmt.Println or log.Println
fmt.Println("Game created:", gameID)
```

### 6. Validate All Input at Handler Layer

```go
// Validate before passing to service
if req.Title == "" {
    return core.ErrInvalidRequest(
        errors.New("title is required"),
        correlationID,
    )
}

if len(req.Title) > 255 {
    return core.ErrInvalidRequest(
        errors.New("title too long"),
        correlationID,
    )
}
```

### 7. Use Typed Errors with Context

```go
// Define in core/errors.go
type APIError struct {
    Code          string `json:"code"`
    Message       string `json:"message"`
    CorrelationID string `json:"correlation_id,omitempty"`
    HTTPStatus    int    `json:"-"`
}

// Usage
if game == nil {
    return nil, core.ErrNotFound("game", gameID, correlationID)
}
```

### 8. Test-Driven Development (TDD)

```go
// Write test first (should fail)
func TestCreateGame(t *testing.T) {
    service := &GameService{DB: mockDB}
    game, err := service.CreateGame(ctx, req)
    require.NoError(t, err)
    assert.Equal(t, "Test Game", game.Title)
}

// Then implement
// Then verify test passes
```

---

## Common Imports

```go
// HTTP and routing
import (
    "net/http"
    "github.com/go-chi/chi/v5"
    "github.com/go-chi/chi/v5/middleware"
    "github.com/go-chi/cors"
)

// Database
import (
    "github.com/jackc/pgx/v5/pgxpool"
    "actionphase/backend/pkg/db"
)

// Logging
import (
    "github.com/rs/zerolog"
    "github.com/rs/zerolog/log"
)

// JWT
import (
    "github.com/golang-jwt/jwt/v5"
)

// Testing
import (
    "testing"
    "github.com/stretchr/testify/assert"
    "github.com/stretchr/testify/require"
)

// Context and errors
import (
    "context"
    "errors"
)
```

---

## Quick Reference

### HTTP Status Codes

| Code | Use Case |
|------|----------|
| 200 | Success |
| 201 | Created |
| 204 | No Content |
| 400 | Bad Request |
| 401 | Unauthorized |
| 403 | Forbidden |
| 404 | Not Found |
| 500 | Server Error |

### justfile Commands

```bash
just dev              # Start server with .env
just sqlgen           # Generate Go from SQL
just test             # Run all tests
just test-mocks       # Fast unit tests (~300ms)
just migrate          # Apply migrations
just make_migration   # Create new migration
```

### Database Name

**CRITICAL**: Database name is **`actionphase`**, NOT `database`

```
postgres://postgres:example@localhost:5432/actionphase
```

---

## Anti-Patterns to Avoid

❌ Business logic in handlers
❌ Raw SQL without sqlc
❌ Missing correlation IDs
❌ No error handling
❌ No input validation
❌ fmt.Println instead of structured logging
❌ Direct process.env in code (use config)
❌ Forgetting interface definitions
❌ Skipping tests

---

## Service Decomposition Pattern

### When to Decompose

Decompose a service when:
- File exceeds **500 lines**
- Multiple distinct responsibilities emerge
- Testing becomes difficult
- Code navigation is hard

### How to Decompose

**Example**: Phase service decomposition (1056 lines → 6 files)

```
services/phases.go (1056 lines)
    ↓
services/phases/
├── service.go        # Main service struct + constructor
├── crud.go           # Create, Read, Update, Delete
├── transitions.go    # State transitions
├── validation.go     # Validation logic
├── history.go        # History tracking
└── converters.go     # Model conversions
```

**Pattern**:
1. Create package directory: `services/phases/`
2. Move service struct to `service.go`
3. Group related methods into focused files
4. Update imports across codebase
5. Run tests to verify

**See**: `.claude/planning/REFACTOR_00_MASTER_PLAN.md`

---

## Navigation Guide

| Need to... | Read this |
|------------|-----------|
| Understand architecture | `.claude/context/ARCHITECTURE.md` |
| See complete patterns | `.claude/reference/BACKEND_ARCHITECTURE.md` |
| Handle errors properly | `.claude/reference/ERROR_HANDLING.md` |
| Implement logging | `.claude/reference/LOGGING_STANDARDS.md` |
| Document APIs | `.claude/reference/API_DOCUMENTATION.md` |
| Write tests | `.claude/context/TESTING.md` |
| Use test fixtures | `.claude/context/TEST_DATA.md` |

---

## Key Files Reference

**Must Read Before Coding:**
- `backend/pkg/core/interfaces.go` - ALL service contracts
- `backend/pkg/core/models.go` - Business entities
- `backend/pkg/core/errors.go` - Error types
- `backend/pkg/http/root.go` - Routing + middleware

**Implementation Examples:**
- `backend/pkg/db/services/games.go` - Simple service
- `backend/pkg/db/services/phases/` - Decomposed service
- `backend/pkg/db/queries/games.sql` - sqlc patterns

---

## Testing Requirements

**MANDATORY**: Tests for all new features and bug fixes

### Test Types

1. **Unit Tests** (FAST - run first)
   - Mock dependencies using interfaces
   - Test business logic in isolation
   - Run: `just test-mocks` (~300ms)

2. **Integration Tests** (with database)
   - Test with real PostgreSQL
   - Use test fixtures
   - Run: `SKIP_DB_TESTS=false just test`

3. **API Tests** (curl verification)
   - Verify endpoints return correct data
   - Test before E2E tests
   - Pattern: `./backend/scripts/api-test.sh`

4. **E2E Tests** (LAST)
   - Only after unit + API + component tests pass
   - See: `.claude/context/TESTING.md`

### Bug Fix Process

1. Write test that reproduces bug (should fail)
2. Fix the bug
3. Verify test passes
4. Commit test and fix together

**See**: `.claude/context/TESTING.md` for complete testing guide

---

## Authentication Pattern

**JWT Access Tokens** (15 min) + **Refresh Tokens** (7 days)

- Access tokens for API requests (in Authorization header)
- Refresh tokens stored in database sessions
- User ID **NOT in JWT** - fetched from `/api/v1/auth/me`
- Automatic refresh via frontend interceptors

**Security**: JWT only contains `sub` (username), `exp`, `iat`, `jti`

**See**: `/docs/adrs/003-authentication-strategy.md`

---

## Related Context Files

- **`.claude/context/ARCHITECTURE.md`** - Complete architecture patterns
- **`.claude/context/TESTING.md`** - Testing philosophy and patterns
- **`.claude/context/TEST_DATA.md`** - Test fixtures overview
- **`.claude/reference/BACKEND_ARCHITECTURE.md`** - Detailed implementation guide
- **`.claude/reference/ERROR_HANDLING.md`** - Error patterns
- **`.claude/reference/LOGGING_STANDARDS.md`** - Logging best practices
- **`.claude/reference/API_DOCUMENTATION.md`** - API endpoint docs

---

## ADR References

- **ADR-001**: Technology Stack Selection (Go, Chi, PostgreSQL, sqlc)
- **ADR-002**: Database Design (Hybrid relational-document with JSONB)
- **ADR-003**: Authentication Strategy (JWT + Refresh Tokens)
- **ADR-004**: API Design Principles (RESTful, versioned)
- **ADR-006**: Observability Approach (Structured logging, correlation IDs)
- **ADR-007**: Testing Strategy (Test pyramid, TDD)

**Location**: `/docs/adrs/`

---

**Skill Status**: COMPLETE ✅
**Line Count**: < 500 ✅
**Tech Stack**: Go, Chi, PostgreSQL, sqlc ✅
**Progressive Disclosure**: Links to detailed context files ✅
backend-dev-guidelines | SkillHub