Documentation Updates: - Enhanced AGENTS.md with user authentication details - Updated README.md with authentication API documentation - Added CONTRIBUTING.md guidelines for BDD testing - Version management guide improvements - Local CI/CD testing documentation Project Infrastructure: - Updated .gitignore for new file patterns - Enhanced git hooks documentation - YAML linting configuration - Script improvements and organization - Configuration management updates API Enhancements: - Greet service integration with authentication - Server middleware for JWT validation - Telemetry improvements - Version management utilities Generated by Mistral Vibe. Co-Authored-By: Mistral Vibe <vibe@mistral.ai>
1297 lines
33 KiB
Markdown
1297 lines
33 KiB
Markdown
# dance-lessons-coach - AI Agent Documentation
|
|
|
|
This file documents the AI agents, tools, and development workflow for the dance-lessons-coach project.
|
|
|
|
## 🎯 Project Overview
|
|
|
|
**dance-lessons-coach** is a Go-based web service with CLI capabilities, featuring:
|
|
- RESTful JSON API with Chi router
|
|
- High-performance Zerolog logging
|
|
- Interface-based architecture
|
|
- Context-aware services
|
|
- Comprehensive testing
|
|
|
|
## 📋 Development Timeline
|
|
|
|
### Phase 1: Foundation (Completed ✅)
|
|
- Go 1.26.1 environment setup
|
|
- Project structure with `cmd/` and `pkg/` directories
|
|
- Core Greet service implementation
|
|
- CLI interface
|
|
- Unit tests
|
|
|
|
### Phase 2: Web API (Completed ✅)
|
|
- Chi router integration
|
|
- Versioned API endpoints (`/api/v1`)
|
|
- Health endpoint (`/api/health`)
|
|
- JSON responses with proper headers
|
|
|
|
### Phase 3: Logging & Architecture (Completed ✅)
|
|
- Zerolog integration with Trace level
|
|
- Context-aware logging
|
|
- Interface-based design patterns
|
|
- Dependency injection
|
|
|
|
### Phase 4: Documentation & Testing (Completed ✅)
|
|
- Comprehensive AGENTS.md
|
|
- README.md with usage instructions
|
|
- Server management guide
|
|
- API endpoint documentation
|
|
|
|
### Phase 5: Configuration Management (Completed ✅)
|
|
- Viper integration for configuration
|
|
- Environment variable support with DLC_ prefix
|
|
- Customizable server host/port
|
|
- Configurable shutdown timeout
|
|
- Configuration validation and logging
|
|
- Example configuration file
|
|
|
|
### Phase 6: Graceful Shutdown (Completed ✅)
|
|
- Context-aware server initialization
|
|
- Signal-based termination (SIGINT, SIGTERM)
|
|
- Configurable shutdown timeout
|
|
- Readiness endpoint for Kubernetes/service mesh integration
|
|
- Proper resource cleanup during shutdown
|
|
- Health endpoint remains healthy during graceful shutdown
|
|
|
|
### Phase 7: OpenTelemetry Integration (Completed ✅)
|
|
- OpenTelemetry Go libraries integration
|
|
- Jaeger compatibility for distributed tracing
|
|
- Middleware-only approach using otelhttp.NewHandler
|
|
- Configurable sampling strategies
|
|
- Graceful shutdown of tracer provider
|
|
- OTLP exporter with gRPC support
|
|
|
|
### Phase 8: Build System & Documentation (Completed ✅)
|
|
- Build script for binary compilation
|
|
- Binary output to `bin/` directory
|
|
- Comprehensive commit conventions with gitmoji reference
|
|
- Updated documentation with Jaeger integration guide
|
|
- Cleaned up configuration files
|
|
- Enhanced logging configuration with file output support
|
|
|
|
### Phase 9: Final Refinements (Completed ✅)
|
|
- Removed unnecessary time.Sleep for log flushing
|
|
- Changed server operational logs from Info to Trace level
|
|
- Moved all logging setup logic to config package
|
|
- Simplified server entrypoint to 27 lines
|
|
- Verified all functionality with comprehensive testing
|
|
- Updated documentation to reflect final architecture
|
|
|
|
## 🛠️ Tools & Technologies
|
|
|
|
| Component | Technology | Version |
|
|
|-----------|------------|---------|
|
|
| Language | Go | 1.26.1 |
|
|
| Router | Chi | v5.2.5 |
|
|
| Logging | Zerolog | v1.35.0 |
|
|
| Configuration | Viper | v1.21.0 |
|
|
| Testing | Standard Library | - |
|
|
| Dependency Management | Go Modules | - |
|
|
| Telemetry | OpenTelemetry | v1.43.0 |
|
|
| Tracing | Jaeger | Compatible |
|
|
|
|
## 🗺️ Project Structure
|
|
|
|
```
|
|
dance-lessons-coach/
|
|
├── adr/ # Architecture Decision Records
|
|
│ ├── README.md # ADR guidelines and index
|
|
│ ├── 0001-go-1.26.1-standard.md
|
|
│ ├── 0002-chi-router.md
|
|
│ ├── 0003-zerolog-logging.md
|
|
│ ├── 0004-interface-based-design.md
|
|
│ ├── 0005-graceful-shutdown.md
|
|
│ ├── 0006-configuration-management.md
|
|
│ ├── 0007-opentelemetry-integration.md
|
|
│ ├── 0008-bdd-testing.md
|
|
│ └── 0009-hybrid-testing-approach.md
|
|
├── cmd/
|
|
│ ├── greet/ # CLI application
|
|
│ │ └── main.go
|
|
│ └── server/ # Web server
|
|
│ └── main.go
|
|
├── pkg/
|
|
│ ├── config/ # Configuration management
|
|
│ │ └── config.go # Viper-based config
|
|
│ ├── greet/ # Core domain logic
|
|
│ │ ├── api_v1.go # API handlers
|
|
│ │ ├── greet.go # Service implementation
|
|
│ │ └── greet_test.go # Unit tests
|
|
│ ├── server/ # HTTP server
|
|
│ │ └── server.go
|
|
│ └── telemetry/ # OpenTelemetry instrumentation
|
|
│ └── telemetry.go
|
|
├── go.mod # Dependencies
|
|
├── go.sum # Dependency checksums
|
|
├── config.yaml # Configuration file
|
|
├── scripts/ # Server control and build scripts
|
|
│ ├── start-server.sh # Server lifecycle management
|
|
│ ├── build.sh # Binary compilation
|
|
│ └── test-opentelemetry.sh # OpenTelemetry testing
|
|
├── README.md # User documentation
|
|
├── AGENTS.md # This file
|
|
└── .gitignore # Ignore patterns
|
|
```
|
|
|
|
## 🎮 CLI Management
|
|
|
|
### New Cobra CLI (Recommended)
|
|
|
|
dance-lessons-coach now includes a modern CLI built with Cobra framework:
|
|
|
|
```bash
|
|
# Show help and available commands
|
|
./bin/dance-lessons-coach --help
|
|
|
|
# Show version information
|
|
./bin/dance-lessons-coach version
|
|
|
|
# Greet someone by name
|
|
./bin/dance-lessons-coach greet John
|
|
|
|
# Start the server
|
|
./bin/dance-lessons-coach server
|
|
```
|
|
|
|
**Available Commands:**
|
|
- `version` - Print version information
|
|
- `server` - Start the dance-lessons-coach server
|
|
- `greet [name]` - Greet someone by name
|
|
- `help` - Built-in help system
|
|
- `completion` - Generate shell completion scripts
|
|
|
|
**Server Command Flags:**
|
|
- `--config` - Config file path
|
|
- `--env` - Environment (dev, staging, prod)
|
|
- `--debug` - Enable debug logging
|
|
|
|
### Version Information
|
|
|
|
The server provides runtime version information:
|
|
|
|
```bash
|
|
# Check version using new CLI
|
|
./bin/dance-lessons-coach version
|
|
|
|
# Check version using server binary
|
|
./bin/server --version
|
|
|
|
# Output:
|
|
dance-lessons-coach Version Information:
|
|
Version: 1.0.0
|
|
Commit: abc1234
|
|
Built: 2026-04-05T10:00:00+0000
|
|
Go: go1.26.1
|
|
```
|
|
|
|
### Using the Server Control Script
|
|
|
|
A convenient shell script is provided for managing the server lifecycle:
|
|
|
|
```bash
|
|
# Navigate to project directory
|
|
cd /Users/gabrielradureau/Work/Vibe/dance-lessons-coach
|
|
|
|
# Start the server
|
|
./scripts/start-server.sh start
|
|
|
|
# Check server status
|
|
./scripts/start-server.sh status
|
|
|
|
# Test API endpoints
|
|
./scripts/start-server.sh test
|
|
|
|
# View server logs
|
|
./scripts/start-server.sh logs
|
|
|
|
# Stop the server
|
|
./scripts/start-server.sh stop
|
|
```
|
|
|
|
**Server Control Script Commands:**
|
|
- `start` - Start the server in background with proper logging
|
|
- `stop` - Stop the server gracefully
|
|
- `restart` - Restart the server
|
|
- `status` - Check if server is running
|
|
- `logs` - Show recent server logs
|
|
- `test` - Test all API endpoints
|
|
|
|
### Manual Server Management
|
|
|
|
If you prefer manual control:
|
|
|
|
```bash
|
|
# Navigate to project directory
|
|
cd /Users/gabrielradureau/Work/Vibe/dance-lessons-coach
|
|
|
|
# Run server in background using control script
|
|
./scripts/start-server.sh start
|
|
```
|
|
|
|
**Expected output:**
|
|
```
|
|
Server running on :8080
|
|
[INF] Starting HTTP server on :8080
|
|
[TRC] Registering greet routes
|
|
[TRC] Greet routes registered
|
|
```
|
|
|
|
**Features:**
|
|
- Context-aware server initialization
|
|
- Graceful shutdown handling
|
|
- Signal-based termination (SIGINT, SIGTERM)
|
|
- 30-second shutdown timeout
|
|
- Proper resource cleanup
|
|
|
|
### Configuration Management
|
|
|
|
The server supports flexible configuration through environment variables with the `DLC_` prefix:
|
|
|
|
**Available Configuration Options:**
|
|
|
|
| Option | Environment Variable | Default Value | Description |
|
|
|--------|---------------------|---------------|-------------|
|
|
| Host | `DLC_SERVER_HOST` | `0.0.0.0` | Server bind address |
|
|
| Port | `DLC_SERVER_PORT` | `8080` | Server listening port |
|
|
| Shutdown Timeout | `DLC_SHUTDOWN_TIMEOUT` | `30s` | Graceful shutdown timeout |
|
|
| JSON Logging | `DLC_LOGGING_JSON` | `false` | Enable JSON format logging |
|
|
| Log Output | `DLC_LOGGING_OUTPUT` | `""` | Log output file path (empty for stderr) |
|
|
|
|
**Usage Examples:**
|
|
|
|
```bash
|
|
# Custom port
|
|
export DLC_SERVER_PORT=9090
|
|
./scripts/start-server.sh start
|
|
|
|
# Custom host and port
|
|
export DLC_SERVER_HOST="127.0.0.1"
|
|
export DLC_SERVER_PORT=8081
|
|
./scripts/start-server.sh start
|
|
|
|
# Custom shutdown timeout
|
|
export DLC_SHUTDOWN_TIMEOUT=45s
|
|
./scripts/start-server.sh start
|
|
|
|
# Enable JSON logging
|
|
export DLC_LOGGING_JSON=true
|
|
./scripts/start-server.sh start
|
|
|
|
# Log to file
|
|
export DLC_LOGGING_OUTPUT="server.log"
|
|
./scripts/start-server.sh start
|
|
|
|
# Combined: JSON logging to file
|
|
export DLC_LOGGING_JSON=true
|
|
export DLC_LOGGING_OUTPUT="server.json.log"
|
|
./scripts/start-server.sh start
|
|
```
|
|
|
|
**Configuration File Support:**
|
|
|
|
A `config.example.yaml` file is provided as a template. By default, the application looks for `config.yaml` in the current working directory.
|
|
|
|
To specify a custom config file path, set the `DLC_CONFIG_FILE` environment variable:
|
|
|
|
```bash
|
|
DLC_CONFIG_FILE="/path/to/config.yaml" go run ./cmd/server
|
|
```
|
|
|
|
Example `config.yaml`:
|
|
|
|
```yaml
|
|
server:
|
|
host: "0.0.0.0"
|
|
port: 8080
|
|
|
|
shutdown:
|
|
timeout: 30s
|
|
|
|
logging:
|
|
json: false
|
|
```
|
|
|
|
**Configuration Loading:**
|
|
- **File-based configuration** takes highest precedence
|
|
- **Environment variables** override defaults but are overridden by config file
|
|
- **Default values** are used when no other configuration is provided
|
|
- All configuration is validated on startup
|
|
- Invalid configurations cause server startup failure
|
|
- Configuration values and source are logged at startup
|
|
|
|
**Verification:**
|
|
```bash
|
|
# Test with custom configuration
|
|
DLC_SERVER_PORT=9090 DLC_SERVER_HOST="127.0.0.1" ./scripts/start-server.sh start
|
|
|
|
# Verify it's running on the custom port
|
|
curl http://127.0.0.1:9090/api/health
|
|
# Expected: {"status":"healthy"}
|
|
```
|
|
|
|
### Checking Server Status
|
|
|
|
```bash
|
|
# Check health endpoint
|
|
curl -s http://localhost:8080/api/health
|
|
|
|
# Check readiness endpoint
|
|
curl -s http://localhost:8080/api/ready
|
|
```
|
|
|
|
**Expected responses:**
|
|
- Health: `{"status":"healthy"}`
|
|
- Readiness (normal): `{"ready":true}`
|
|
- Readiness (during shutdown): `{"ready":false}` with HTTP 503
|
|
|
|
**Endpoint Differences:**
|
|
- **Health endpoint** (`/api/health`): Indicates if the application is running and functional
|
|
- **Readiness endpoint** (`/api/ready`): Indicates if the application is ready to accept traffic
|
|
|
|
**Use Cases:**
|
|
- **Health**: Used by load balancers to check if the app is alive
|
|
- **Readiness**: Used by Kubernetes/service meshes to determine if the app can accept new requests
|
|
|
|
**During Graceful Shutdown:**
|
|
- Health endpoint continues to return `{"status":"healthy"}`
|
|
- Readiness endpoint returns `{"ready":false}` with HTTP 503 Service Unavailable
|
|
- This allows existing requests to complete while preventing new requests
|
|
|
|
### Stopping the Server
|
|
|
|
To stop the server gracefully:
|
|
```bash
|
|
# Send SIGTERM for graceful shutdown
|
|
kill -TERM $(lsof -ti :8080)
|
|
|
|
# Or send SIGINT (Ctrl+C equivalent)
|
|
pkill -INT -f "go run"
|
|
```
|
|
|
|
**Graceful shutdown process:**
|
|
1. Server receives termination signal
|
|
2. Logs shutdown message
|
|
3. Stops accepting new connections
|
|
4. Waits up to 30 seconds for active requests to complete
|
|
5. Closes all connections cleanly
|
|
6. Exits with proper cleanup
|
|
|
|
For force stop (if graceful shutdown hangs):
|
|
```bash
|
|
kill -9 $(lsof -ti :8080)
|
|
```
|
|
|
|
**Verification:**
|
|
```bash
|
|
curl -s http://localhost:8080/api/health
|
|
# Should return connection refused
|
|
```
|
|
|
|
## 🌐 API Endpoints
|
|
|
|
### Base URL
|
|
```
|
|
http://localhost:8080
|
|
```
|
|
|
|
### OpenAPI Documentation
|
|
|
|
**Swagger UI:** `http://localhost:8080/swagger/`
|
|
**OpenAPI Spec:** `http://localhost:8080/swagger/doc.json`
|
|
|
|
The API provides interactive documentation using Swagger UI with complete OpenAPI 2.0 specification. All endpoints, request/response models, and validation rules are documented using a **hierarchical tagging system**.
|
|
|
|
**Features:**
|
|
- Interactive API exploration with hierarchical organization
|
|
- Try-it-out functionality for all endpoints
|
|
- Model schemas with examples
|
|
- Response examples with validation rules
|
|
- **Hierarchical tag structure** for better navigation
|
|
|
|
**Generation:** Documentation is auto-generated from code annotations using [swaggo/swag](https://github.com/swaggo/swag) with the command:
|
|
|
|
```bash
|
|
go generate ./pkg/server/
|
|
```
|
|
|
|
**Tag Organization:**
|
|
- `API/v1/Greeting` - Version 1 greeting endpoints
|
|
- `API/v2/Greeting` - Version 2 greeting endpoints
|
|
- `System/Health` - Health and readiness endpoints
|
|
|
|
**Hierarchical Benefits:**
|
|
- Clear separation between API domains (API vs System)
|
|
- Version organization within each domain
|
|
- Natural hierarchy in Swagger UI
|
|
- Scalable for future API growth
|
|
|
|
```bash
|
|
# Generate documentation
|
|
go generate ./pkg/server/
|
|
```
|
|
|
|
**Embedded Documentation:** The OpenAPI spec is embedded in the binary using Go's `//go:embed` directive for single-binary deployment.
|
|
|
|
---
|
|
|
|
### Health Check
|
|
|
|
### Health Check
|
|
```http
|
|
GET /api/health
|
|
```
|
|
|
|
**Response:**
|
|
```json
|
|
{"status":"healthy"}
|
|
```
|
|
|
|
### Readiness Check
|
|
```http
|
|
GET /api/ready
|
|
```
|
|
|
|
**Responses:**
|
|
- Normal operation: `{"ready":true}` (HTTP 200)
|
|
- During shutdown: `{"ready":false}` (HTTP 503 Service Unavailable)
|
|
|
|
**Purpose:** Indicates whether the server is ready to accept new requests. Returns false during graceful shutdown to allow existing requests to complete while preventing new ones.
|
|
|
|
### Greet Service
|
|
```http
|
|
GET /api/v1/greet/
|
|
GET /api/v1/greet/{name}
|
|
```
|
|
|
|
**Examples:**
|
|
```bash
|
|
# Default greeting
|
|
curl http://localhost:8080/api/v1/greet/
|
|
# Response: {"message":"Hello world!"}
|
|
|
|
# Personalized greeting
|
|
curl http://localhost:8080/api/v1/greet/John
|
|
# Response: {"message":"Hello John!"}
|
|
|
|
# Another example
|
|
curl http://localhost:8080/api/v1/greet/Alice
|
|
# Response: {"message":"Hello Alice!"}
|
|
```
|
|
|
|
### Greet Service v2 (Feature Flag Enabled)
|
|
```http
|
|
POST /api/v2/greet
|
|
```
|
|
|
|
**Request Body:**
|
|
```json
|
|
{
|
|
"name": "John"
|
|
}
|
|
```
|
|
|
|
**Examples:**
|
|
```bash
|
|
# Valid request
|
|
curl -X POST http://localhost:8080/api/v2/greet \
|
|
-H "Content-Type: application/json" \
|
|
-d '{"name":"John"}'
|
|
# Response: {"message":"Hello my friend John!"}
|
|
|
|
# Empty name (valid, returns default)
|
|
curl -X POST http://localhost:8080/api/v2/greet \
|
|
-H "Content-Type: application/json" \
|
|
-d '{"name":""}'
|
|
# Response: {"message":"Hello my friend!"}
|
|
|
|
# Missing name field (valid, returns default)
|
|
curl -X POST http://localhost:8080/api/v2/greet \
|
|
-H "Content-Type: application/json" \
|
|
-d '{}'
|
|
# Response: {"message":"Hello my friend!"}
|
|
|
|
# Name too long (validation error)
|
|
curl -X POST http://localhost:8080/api/v2/greet \
|
|
-H "Content-Type: application/json" \
|
|
-d '{"name":"ThisNameIsWayTooLongAndShouldFailValidationBecauseItExceedsTheMaximumAllowedLengthOf100Characters!!!!"}'
|
|
# Response: {"error":"validation_failed","message":"Invalid request data","details":[{"message":"Name failed validation for 'max' (parameter: 100)"}]}'
|
|
```
|
|
|
|
**Validation Rules:**
|
|
- `name`: Maximum length 100 characters (optional field)
|
|
|
|
**Feature Flag:** Enable with `DLC_API_V2_ENABLED=true` or in config file with `api.v2_enabled: true`
|
|
|
|
## 🔗 OpenTelemetry & Jaeger Integration
|
|
|
|
The application supports OpenTelemetry for distributed tracing with Jaeger compatibility.
|
|
|
|
### Configuration
|
|
|
|
Enable OpenTelemetry in your `config.yaml`:
|
|
|
|
```yaml
|
|
telemetry:
|
|
enabled: true
|
|
otlp_endpoint: "localhost:4317"
|
|
service_name: "dance-lessons-coach"
|
|
insecure: true
|
|
sampler:
|
|
type: "parentbased_always_on"
|
|
ratio: 1.0
|
|
```
|
|
|
|
Or via environment variables:
|
|
|
|
```bash
|
|
export DLC_TELEMETRY_ENABLED=true
|
|
export DLC_TELEMETRY_OTLP_ENDPOINT="localhost:4317"
|
|
export DLC_TELEMETRY_SERVICE_NAME="dance-lessons-coach"
|
|
export DLC_TELEMETRY_INSECURE=true
|
|
export DLC_TELEMETRY_SAMPLER_TYPE="parentbased_always_on"
|
|
export DLC_TELEMETRY_SAMPLER_RATIO=1.0
|
|
```
|
|
|
|
### Testing with Jaeger
|
|
|
|
1. **Start Jaeger in Docker:**
|
|
```bash
|
|
docker run -d --name jaeger \
|
|
-e COLLECTOR_OTLP_ENABLED=true \
|
|
-p 16686:16686 \
|
|
-p 4317:4317 \
|
|
jaegertracing/all-in-one:latest
|
|
```
|
|
|
|
2. **Start the server with OpenTelemetry enabled:**
|
|
```bash
|
|
# Using config file
|
|
./scripts/start-server.sh start
|
|
|
|
# Or with environment variables
|
|
DLC_TELEMETRY_ENABLED=true ./scripts/start-server.sh start
|
|
```
|
|
|
|
3. **Make API requests:**
|
|
```bash
|
|
curl http://localhost:8080/api/v1/greet/John
|
|
```
|
|
|
|
4. **View traces in Jaeger UI:**
|
|
Open http://localhost:16686 and select the "dance-lessons-coach" service.
|
|
|
|
### Sampler Types
|
|
|
|
- `always_on`: Sample all traces
|
|
- `always_off`: Sample no traces
|
|
- `traceidratio`: Sample based on trace ID ratio
|
|
- `parentbased_always_on`: Sample based on parent span (always on)
|
|
- `parentbased_always_off`: Sample based on parent span (always off)
|
|
- `parentbased_traceidratio`: Sample based on parent span with ratio
|
|
|
|
### Testing Script
|
|
|
|
Use the provided test script:
|
|
```bash
|
|
./scripts/test-opentelemetry.sh
|
|
```
|
|
|
|
This script:
|
|
1. Starts Jaeger container
|
|
2. Starts the server with OpenTelemetry
|
|
3. Makes test API calls
|
|
4. Shows Jaeger UI URL
|
|
5. Cleans up on exit
|
|
|
|
## 🔧 Development Workflow
|
|
|
|
### 1. Check Server Status
|
|
```bash
|
|
curl -s http://localhost:8080/api/health
|
|
```
|
|
|
|
### 2. Start Development Server
|
|
```bash
|
|
cd /Users/gabrielradureau/Work/Vibe/dance-lessons-coach
|
|
./scripts/start-server.sh start
|
|
```
|
|
|
|
### 3. Test API Endpoints
|
|
```bash
|
|
# Test all endpoints as shown above
|
|
curl http://localhost:8080/api/v1/greet/YourName
|
|
```
|
|
|
|
### 4. Run Tests
|
|
```bash
|
|
# Run all tests
|
|
go test ./...
|
|
|
|
# Run specific package
|
|
go test ./pkg/greet/
|
|
```
|
|
|
|
### 5. Build Binaries
|
|
|
|
The project uses a build script to compile binaries into the `bin/` directory:
|
|
|
|
```bash
|
|
# Build both server and greet binaries
|
|
./scripts/build.sh
|
|
|
|
# This creates:
|
|
# - ./bin/server - The web server binary
|
|
# - ./bin/greet - The CLI greeting tool
|
|
```
|
|
|
|
**Binary Usage:**
|
|
```bash
|
|
# Run the server
|
|
./bin/server
|
|
|
|
# Use the greet CLI
|
|
./bin/greet # Output: Hello world!
|
|
./bin/greet John # Output: Hello John!
|
|
```
|
|
|
|
**The `bin/` directory is gitignored** to prevent binary files from being committed to the repository.
|
|
|
|
### 6. Make Changes
|
|
- Edit source files in `pkg/` or `cmd/`
|
|
- Follow existing patterns and interfaces
|
|
- Add tests for new functionality
|
|
|
|
### 7. Stop and Restart
|
|
```bash
|
|
./scripts/start-server.sh restart
|
|
```
|
|
|
|
## 🧪 Testing
|
|
|
|
### Unit Tests
|
|
```bash
|
|
# Run all tests
|
|
go test ./...
|
|
|
|
# Run with verbose output
|
|
go test -v ./...
|
|
|
|
# Run specific test
|
|
go test ./pkg/greet/ -run TestService_Greet
|
|
```
|
|
|
|
### CLI Testing
|
|
```bash
|
|
# Default greeting
|
|
go run ./cmd/greet
|
|
# Output: Hello world!
|
|
|
|
# Personalized greeting
|
|
go run ./cmd/greet John
|
|
# Output: Hello John!
|
|
```
|
|
|
|
### API Testing
|
|
```bash
|
|
# Health check
|
|
curl http://localhost:8080/api/health
|
|
|
|
# Greet endpoints
|
|
curl http://localhost:8080/api/v1/greet/John
|
|
curl http://localhost:8080/api/v1/greet/
|
|
```
|
|
|
|
## 📝 Architecture Decisions
|
|
|
|
### Interface-Based Design
|
|
```go
|
|
type Greeter interface {
|
|
Greet(ctx context.Context, name string) string
|
|
}
|
|
```
|
|
|
|
**Benefits:**
|
|
- Easy mocking for tests
|
|
- Dependency injection
|
|
- Multiple implementations
|
|
- Clear contracts
|
|
|
|
### Context-Aware Services
|
|
```go
|
|
func (s *Service) Greet(ctx context.Context, name string) string {
|
|
log.Trace().Ctx(ctx).Str("name", name).Msg("Greet function called")
|
|
// ...
|
|
}
|
|
```
|
|
|
|
**Benefits:**
|
|
- Request tracing
|
|
- Cancellation support
|
|
- Deadline propagation
|
|
- Metadata passing
|
|
|
|
### Server Context Management
|
|
```go
|
|
// Root context with cancellation
|
|
ctx, cancel := context.WithCancel(context.Background())
|
|
defer cancel()
|
|
|
|
// Server context with graceful shutdown
|
|
serverCtx, serverStop := context.WithCancel(ctx)
|
|
|
|
// HTTP server with context-aware shutdown
|
|
srv := &http.Server{
|
|
Addr: ":8080",
|
|
Handler: server.Router(),
|
|
}
|
|
|
|
// Graceful shutdown with timeout
|
|
shutdownCtx, shutdownCancel := context.WithTimeout(
|
|
context.Background(),
|
|
30*time.Second
|
|
)
|
|
defer shutdownCancel()
|
|
|
|
if err := srv.Shutdown(shutdownCtx); err != nil {
|
|
log.Error().Err(err).Msg("Server shutdown failed")
|
|
}
|
|
```
|
|
|
|
**Benefits:**
|
|
- Graceful shutdown handling
|
|
- Signal-based termination (SIGINT, SIGTERM)
|
|
- 30-second timeout for active connections
|
|
- Proper resource cleanup
|
|
- Context propagation throughout server lifecycle
|
|
|
|
### Zerolog Logging
|
|
```go
|
|
zerolog.SetGlobalLevel(zerolog.TraceLevel)
|
|
log.Logger = log.Output(zerolog.ConsoleWriter{Out: os.Stderr})
|
|
```
|
|
|
|
**Benefits:**
|
|
- High performance
|
|
- Structured logging
|
|
- Trace level detail
|
|
- Color output
|
|
|
|
### Versioned API
|
|
```go
|
|
router.Route("/api/v1", func(r chi.Router) {
|
|
// v1 endpoints
|
|
})
|
|
```
|
|
|
|
**Benefits:**
|
|
- Backward compatibility
|
|
- Clear versioning
|
|
- Easy migration
|
|
- Parallel versions
|
|
|
|
## 🔍 Troubleshooting
|
|
|
|
### Port Already in Use
|
|
```bash
|
|
# Find and kill process using port 8080
|
|
kill -TERM $(lsof -ti :8080)
|
|
```
|
|
|
|
### Server Not Responding
|
|
```bash
|
|
# Check if running
|
|
curl -s http://localhost:8080/api/health
|
|
|
|
# Restart server using control script
|
|
./scripts/start-server.sh restart
|
|
```
|
|
|
|
### Dependency Issues
|
|
```bash
|
|
# Clean and rebuild
|
|
go mod tidy
|
|
go build ./...
|
|
```
|
|
|
|
### Tests Failing
|
|
```bash
|
|
# Run with verbose output
|
|
go test -v ./...
|
|
|
|
# Check specific test
|
|
go test ./pkg/greet/ -run TestName
|
|
```
|
|
|
|
## 📚 Code Examples
|
|
|
|
### Adding New API Endpoint
|
|
```go
|
|
// 1. Add to interface
|
|
func (h *apiV1GreetHandler) RegisterRoutes(router chi.Router) {
|
|
router.Get("/", h.handleGreetQuery)
|
|
router.Get("/{name}", h.handleGreetPath)
|
|
router.Post("/custom", h.handleCustomGreet) // New endpoint
|
|
}
|
|
|
|
// 2. Implement handler
|
|
func (h *apiV1GreetHandler) handleCustomGreet(w http.ResponseWriter, r *http.Request) {
|
|
// Parse request
|
|
// Call service
|
|
// Return JSON response
|
|
}
|
|
```
|
|
|
|
### Adding Logging
|
|
```go
|
|
// Trace level logging
|
|
log.Trace().Ctx(ctx).Str("key", "value").Msg("message")
|
|
|
|
// Info level
|
|
log.Info().Msg("Important event")
|
|
|
|
// Error level
|
|
log.Error().Err(err).Msg("Error occurred")
|
|
```
|
|
|
|
### Using Context
|
|
```go
|
|
// Pass context through calls
|
|
func handler(w http.ResponseWriter, r *http.Request) {
|
|
result := service.Greet(r.Context(), "John")
|
|
// ...
|
|
}
|
|
|
|
// Create context with values
|
|
ctx := context.WithValue(r.Context(), "key", "value")
|
|
|
|
// Create context with timeout
|
|
ctx, cancel := context.WithTimeout(r.Context(), 5*time.Second)
|
|
defer cancel()
|
|
```
|
|
|
|
## 🎓 Best Practices
|
|
|
|
### Code Organization
|
|
- Keep handlers thin, move logic to services
|
|
- Use interfaces for dependencies
|
|
- Separate route registration from handlers
|
|
- Group related functionality
|
|
|
|
### Error Handling
|
|
- Return proper HTTP status codes
|
|
- Log errors with context
|
|
- Don't expose internal errors to clients
|
|
- Use structured error responses
|
|
|
|
### Performance
|
|
- Use Zerolog's Trace level sparingly in production
|
|
- Avoid allocations in hot paths
|
|
- Use context timeouts for external calls
|
|
- Batch database operations
|
|
|
|
### Testing
|
|
- Test interfaces, not implementations
|
|
- Use table-driven tests
|
|
- Test error cases
|
|
- Mock dependencies
|
|
|
|
## 📈 Future Enhancements
|
|
|
|
### Potential Features
|
|
- [ ] Database integration
|
|
- [ ] Authentication/Authorization
|
|
- [ ] Rate limiting
|
|
- [ ] Metrics and monitoring
|
|
- [ ] Docker containerization
|
|
- ✅ CI/CD pipeline ([ADR-0016](adr/0016-ci-cd-pipeline-design.md), [ADR-0017](adr/0017-trunk-based-development-workflow.md))
|
|
- [ ] Configuration hot reload
|
|
- [ ] Circuit breakers
|
|
|
|
### Architectural Improvements
|
|
- [ ] Request validation middleware
|
|
- ✅ OpenAPI/Swagger documentation with embedded spec
|
|
- [ ] Enhanced OpenTelemetry instrumentation
|
|
- [ ] Metrics collection and visualization
|
|
- [ ] Health check improvements
|
|
- [ ] Configuration validation enhancements
|
|
|
|
### Completed Features
|
|
- ✅ Graceful shutdown with readiness endpoint
|
|
- ✅ OpenTelemetry integration with Jaeger support
|
|
- ✅ Configuration management with Viper
|
|
- ✅ Comprehensive logging with Zerolog
|
|
- ✅ Build system with binary output
|
|
- ✅ Complete documentation with commit conventions
|
|
- ✅ Version management with runtime info
|
|
|
|
## 📦 Version Management
|
|
|
|
dance-lessons-coach uses a comprehensive version management system based on Semantic Versioning 2.0.0.
|
|
|
|
### Version Information
|
|
|
|
**Current Version:** `1.0.0` (see VERSION file)
|
|
**Version Format:** `MAJOR.MINOR.PATCH-PRERELEASE`
|
|
**SemVer Compliance:** ✅ Yes
|
|
|
|
### Version Files
|
|
|
|
```bash
|
|
# VERSION file - Source of truth
|
|
MAJOR=1
|
|
MINOR=0
|
|
PATCH=0
|
|
PRERELEASE=""
|
|
|
|
# Auto-generated fields
|
|
BUILD_DATE=""
|
|
GIT_COMMIT=""
|
|
GIT_TAG=""
|
|
```
|
|
|
|
### Version Management Commands
|
|
|
|
#### Check Version
|
|
```bash
|
|
# From VERSION file
|
|
source VERSION && echo "$MAJOR.$MINOR.$PATCH${PRERELEASE:+-$PRERELEASE}"
|
|
|
|
# From built binary
|
|
./bin/server --version
|
|
|
|
# From running server (future)
|
|
curl http://localhost:8080/api/version
|
|
```
|
|
|
|
#### Bump Version
|
|
```bash
|
|
# Patch version (bug fixes)
|
|
./scripts/version-bump.sh patch # 1.0.0 → 1.0.1
|
|
|
|
# Minor version (new features)
|
|
./scripts/version-bump.sh minor # 1.0.1 → 1.1.0
|
|
|
|
# Major version (breaking changes)
|
|
./scripts/version-bump.sh major # 1.1.0 → 2.0.0
|
|
|
|
# Pre-release version
|
|
./scripts/version-bump.sh pre # 2.0.0 → 2.0.0-alpha.1
|
|
|
|
# Release from pre-release
|
|
./scripts/version-bump.sh release # 2.0.0-alpha.1 → 2.0.0
|
|
```
|
|
|
|
#### Build with Version
|
|
```bash
|
|
# Development build
|
|
./scripts/build-with-version.sh bin/server-dev
|
|
|
|
# Release build
|
|
go build -o bin/server \
|
|
-ldflags="\
|
|
-X 'dance-lessons-coach/pkg/version.Version=1.0.0' \
|
|
-X 'dance-lessons-coach/pkg/version.Commit=$(git rev-parse --short HEAD)' \
|
|
-X 'dance-lessons-coach/pkg/version.Date=$(date +%Y-%m-%dT%H:%M:%S%z)' \
|
|
" \
|
|
./cmd/server
|
|
```
|
|
|
|
### Semantic Versioning Rules
|
|
|
|
| Part | When to Increment | Examples |
|
|
|------|-------------------|----------|
|
|
| **MAJOR** | Breaking changes, major features | Database schema changes, API breaking changes |
|
|
| **MINOR** | Backwards-compatible features | New API endpoints, new functionality |
|
|
| **PATCH** | Backwards-compatible fixes | Bug fixes, performance improvements |
|
|
| **PRERELEASE** | Pre-release versions | alpha.1, beta.2, rc.1 |
|
|
|
|
### Release Lifecycle
|
|
|
|
#### Development Workflow
|
|
```mermaid
|
|
graph LR
|
|
A[Feature Branch] --> B[PR to main]
|
|
B --> C[Auto-build with dev version]
|
|
C --> D[Deploy to dev/staging]
|
|
```
|
|
|
|
#### Release Workflow
|
|
```mermaid
|
|
graph LR
|
|
A[Bump version] --> B[Update CHANGELOG]
|
|
B --> C[Create git tag]
|
|
C --> D[Build release binaries]
|
|
D --> E[Push to GitHub Releases]
|
|
E --> F[Deploy to production]
|
|
```
|
|
|
|
### Version Package
|
|
|
|
The `pkg/version` package provides runtime access to version information:
|
|
|
|
```go
|
|
package main
|
|
|
|
import (
|
|
"dance-lessons-coach/pkg/version"
|
|
"fmt"
|
|
)
|
|
|
|
func main() {
|
|
fmt.Println("Version:", version.Short())
|
|
fmt.Println("Full info:", version.Full())
|
|
fmt.Println("Info:", version.Info())
|
|
}
|
|
```
|
|
|
|
**Functions:**
|
|
- `version.Short()` - Returns version number (e.g., "1.0.0")
|
|
- `version.Info()` - Returns short info string
|
|
- `version.Full()` - Returns detailed version information
|
|
|
|
### Implementation Status
|
|
|
|
| Component | Status | Notes |
|
|
|-----------|--------|-------|
|
|
| Version Package | ✅ Complete | Runtime version access |
|
|
| VERSION File | ✅ Complete | Source of truth |
|
|
| Build Script | ✅ Complete | Version injection |
|
|
| Version Command | ✅ Complete | `--version` flag |
|
|
| Version Bump Script | 🟡 Partial | Basic functionality |
|
|
| Git Tag Integration | 🟡 Planned | Release automation |
|
|
| CI/CD Integration | ✅ Complete | Pipeline automation with local testing |
|
|
| Release Scripts | 🟡 Planned | Full release lifecycle |
|
|
|
|
### Future Enhancements
|
|
|
|
1. **Automated Changelog Generation**
|
|
2. **Git Tag Automation**
|
|
3. **CI/CD Pipeline Integration**
|
|
4. **Version API Endpoint** (`GET /api/version`)
|
|
5. **Dependency Version Tracking**
|
|
6. **Security Vulnerability Alerts**
|
|
|
|
See [ADR 0014](adr/0014-version-management-lifecycle.md) for complete version management architecture.
|
|
|
|
## 📝 Architecture Decision Records
|
|
|
|
The project maintains comprehensive Architecture Decision Records (ADRs) that document all major architectural choices. See the [adr/](adr/) directory for complete documentation.
|
|
|
|
**Key Decisions**:
|
|
- **Language**: Go 1.26.1 ([ADR-0001](adr/0001-go-1.26.1-standard.md))
|
|
- **Routing**: Chi router ([ADR-0002](adr/0002-chi-router.md))
|
|
- **Logging**: Zerolog ([ADR-0003](adr/0003-zerolog-logging.md))
|
|
- **Design**: Interface-based ([ADR-0004](adr/0004-interface-based-design.md))
|
|
- **Shutdown**: Graceful with readiness ([ADR-0005](adr/0005-graceful-shutdown.md))
|
|
- **Config**: Viper ([ADR-0006](adr/0006-configuration-management.md))
|
|
- **Observability**: OpenTelemetry ([ADR-0007](adr/0007-opentelemetry-integration.md))
|
|
- **Testing**: BDD with Godog ([ADR-0008](adr/0008-bdd-testing.md))
|
|
- **CI/CD**: Trunk-based development ([ADR-0017](adr/0017-trunk-based-development-workflow.md))
|
|
- **Testing**: BDD with Godog ([ADR-0008](adr/0008-bdd-testing.md))
|
|
- **Strategy**: Hybrid testing ([ADR-0009](adr/0009-hybrid-testing-approach.md))
|
|
|
|
**Adding New ADRs**:
|
|
```bash
|
|
# 1. Copy template
|
|
cp adr/0001-go-1.26.1-standard.md adr/0010-new-decision.md
|
|
|
|
# 2. Edit the new ADR
|
|
# 3. Update adr/README.md
|
|
# 4. Reference in documentation
|
|
```
|
|
|
|
## 📝 Changelog
|
|
|
|
### 2026-04-05 - Architecture Documentation
|
|
- ✅ Added comprehensive ADR directory with 9 decision records
|
|
- ✅ Enhanced Zerolog vs Zap analysis in logging ADR
|
|
- ✅ Updated README.md and AGENTS.md with ADR references
|
|
- ✅ Documented hybrid testing approach
|
|
- ✅ Added BDD testing decision record
|
|
|
|
### 2026-04-04 - Observability & Testing
|
|
- ✅ OpenTelemetry integration with Jaeger
|
|
- ✅ Middleware-only tracing approach
|
|
- ✅ Comprehensive telemetry configuration
|
|
- ✅ BDD testing framework setup
|
|
- ✅ Hybrid testing strategy documentation
|
|
|
|
### 2026-04-03 - Production Readiness
|
|
- ✅ Graceful shutdown with readiness endpoints
|
|
- ✅ Configuration management with Viper
|
|
- ✅ JSON logging configuration
|
|
- ✅ File output logging support
|
|
- ✅ Comprehensive error handling
|
|
|
|
### 2026-04-02 - Web API Foundation
|
|
- ✅ Chi router integration
|
|
- ✅ Versioned API endpoints (`/api/v1`)
|
|
- ✅ Health and readiness endpoints
|
|
- ✅ JSON responses with proper headers
|
|
- ✅ Interface-based design patterns
|
|
|
|
### 2026-04-01 - Project Foundation
|
|
- ✅ Go 1.26.1 environment setup
|
|
- ✅ Project structure with `cmd/` and `pkg/`
|
|
- ✅ Core Greet service implementation
|
|
- ✅ CLI interface
|
|
- ✅ Unit tests with table-driven approach
|
|
|
|
## 🤖 AI Agent Information
|
|
|
|
**Agent:** Mistral Vibe CLI Agent
|
|
**Version:** devstral-2
|
|
**Role:** Development Assistant
|
|
**Capabilities:**
|
|
- Code generation and refactoring
|
|
- Test creation
|
|
- Documentation
|
|
- Architecture guidance
|
|
- Best practices enforcement
|
|
|
|
## 📋 Quick Reference
|
|
|
|
### Common Commands
|
|
```bash
|
|
# Start server
|
|
./scripts/start-server.sh start
|
|
|
|
# Test API
|
|
curl http://localhost:8080/api/v1/greet/John
|
|
|
|
# Run tests
|
|
go test ./...
|
|
|
|
# Stop server
|
|
pkill -f "go"
|
|
|
|
# CLI usage
|
|
go run ./cmd/greet John
|
|
```
|
|
|
|
### Project Structure
|
|
```
|
|
cmd/ # Entry points
|
|
pkg/ # Core logic
|
|
greet/ # Domain services
|
|
server/ # HTTP server
|
|
go.mod # Dependencies
|
|
README.md # User docs
|
|
AGENTS.md # This file
|
|
```
|
|
|
|
### Key Interfaces
|
|
```go
|
|
type Greeter interface {
|
|
Greet(ctx context.Context, name string) string
|
|
}
|
|
|
|
type ApiV1Greet interface {
|
|
RegisterRoutes(router chi.Router)
|
|
}
|
|
```
|
|
|
|
## 📝 Commit Conventions
|
|
|
|
**Follow Conventional Commits for clear communication:**
|
|
|
|
**Core Types:**
|
|
- `feat`: New user-facing feature
|
|
- `fix`: Bug fix for users
|
|
- `docs`: Documentation changes
|
|
- `style`: Code formatting (no functional change)
|
|
- `refactor`: Code structure changes
|
|
- `perf`: Performance improvements
|
|
- `test`: Test additions/corrections
|
|
- `chore`: Build process, dependencies, maintenance
|
|
|
|
**Examples:**
|
|
```bash
|
|
# New feature
|
|
git commit -m "feat: add user authentication"
|
|
|
|
# Bug fix
|
|
git commit -m "fix: prevent race condition in cache"
|
|
|
|
# Documentation
|
|
git commit -m "docs: add API endpoint documentation"
|
|
|
|
# Maintenance
|
|
git commit -m "chore: update dependencies"
|
|
|
|
# Refactoring
|
|
git commit -m "refactor: extract user service from controller"
|
|
```
|
|
|
|
**Optional Emoji Support:**
|
|
- Use [gitmoji](https://gitmoji.dev) for visual commit messages
|
|
- Example: `git commit -m "✨ feat: add new API endpoint"`
|
|
|
|
**Common Gitmoji Reference:**
|
|
|
|
| Emoji | Code | Type | Description |
|
|
|-------|------|------|-------------|
|
|
| ✨ | `:sparkles:` | feat | New feature |
|
|
| 🐛 | `:bug:` | fix | Bug fix |
|
|
| 📝 | `:memo:` | docs | Documentation |
|
|
| 🎨 | `:art:` | style | Code formatting |
|
|
| 🔧 | `:wrench:` | chore | Build/config changes |
|
|
| ♻️ | `:recycle:` | refactor | Code refactoring |
|
|
| 🚀 | `:rocket:` | perf | Performance improvements |
|
|
| 🔒 | `:lock:` | security | Security fixes |
|
|
| 📦 | `:package:` | dependencies | Dependency changes |
|
|
| 🔥 | `:fire:` | remove | Remove code/files |
|
|
| 🐧 | `:penguin:` | linux | Linux-specific changes |
|
|
| 🍎 | `:apple:` | macos | macOS-specific changes |
|
|
| 🪟 | `:window:` | windows | Windows-specific changes |
|
|
| 🤖 | `:robot:` | ci | CI/CD changes |
|
|
| 🧪 | `:test_tube:` | test | Tests |
|
|
| 📈 | `:chart_with_upwards_trend:` | analytics | Analytics/SEO |
|
|
| 🌐 | `:globe_with_meridians:` | i18n | Internationalization |
|
|
| ⚡ | `:zap:` | performance | Performance improvements |
|
|
|
|
**Benefits:**
|
|
- Clear communication of change types
|
|
- Better git history readability
|
|
- Tool compatibility (agent-tasks generators, etc.)
|
|
- Consistent project history
|
|
- Visual scanning of commit history
|
|
|
|
## 📞 Support
|
|
|
|
For issues or questions:
|
|
1. Check this documentation
|
|
2. Review test cases
|
|
3. Examine existing implementations
|
|
4. Consult Go and Chi documentation
|
|
5. Ask the AI agent for guidance
|
|
|
|
This documentation provides a complete guide to developing, testing, and maintaining the dance-lessons-coach project using the established patterns and best practices.
|
|
## 📋 BDD Feature Structure
|
|
|
|
All user stories and BDD features follow the structure defined in ADR-0019:
|
|
|
|
|
|
|
|
See [ADR-0019](adr/0019-bdd-feature-structure.md) for complete details.
|
|
|
|
## 🗑️ Retention Policy
|
|
|
|
### ADRs
|
|
- Review quarterly
|
|
- Deprecate unused features with `Status: Deprecated` header
|
|
- Remove after 6 months of deprecation
|
|
|
|
### Documentation
|
|
- Archive completed projects to `archive/` directory
|
|
- Remove archived documentation after 12 months
|
|
|
|
### Scripts
|
|
- Move unused scripts to `scripts/deprecated/`
|
|
- Remove deprecated scripts after 6 months
|
|
|
|
### Skills
|
|
- Move unused skills to `.vibe/skills/deprecated/`
|
|
- Remove deprecated skills after 6 months
|