Files
goplt/docs/content/stories/epic0/0.2-configuration-management-system.md
0x1d 610677af72
All checks were successful
CI / Lint (pull_request) Successful in 10s
CI / Format Check (pull_request) Successful in 2s
CI / Test (pull_request) Successful in 11s
CI / Build (pull_request) Successful in 6s
docs: mark all epic0 stories as completed
Update status of all epic0 stories (0.1-0.5) from Pending to Completed:
- 0.1: Project Initialization - Directory structure and Go module setup
- 0.2: Configuration Management System - Viper-based config implemented
- 0.3: Structured Logging System - Zap logger with middleware implemented
- 0.4: CI/CD Pipeline - GitHub Actions workflow with tests and linting
- 0.5: DI and Bootstrap - FX-based DI container with lifecycle management

All stories have been implemented with tests and are working.
2025-11-05 13:44:00 +01:00

172 lines
5.4 KiB
Markdown

# Story 0.2: Configuration Management System
## Metadata
- **Story ID**: 0.2
- **Title**: Configuration Management System
- **Epic**: 0 - Project Setup & Foundation
- **Status**: Completed
- **Priority**: High
- **Estimated Time**: 4-6 hours
- **Dependencies**: 0.1
## Goal
Implement a flexible configuration system that loads settings from YAML files, environment variables, and supports type-safe access. The system must be injectable via DI and usable by all modules.
## Description
This story implements a complete configuration management system using Viper that provides a clean interface for accessing configuration values. The system supports multiple configuration sources (YAML files, environment variables) with proper precedence and type-safe accessors.
## Deliverables
### 1. Configuration Interface (`pkg/config/config.go`)
Define `ConfigProvider` interface with:
- `Get(key string) any` - Get any value
- `Unmarshal(v any) error` - Unmarshal into struct
- `GetString(key string) string` - Type-safe string getter
- `GetInt(key string) int` - Type-safe int getter
- `GetBool(key string) bool` - Type-safe bool getter
- `GetStringSlice(key string) []string` - Type-safe slice getter
- `GetDuration(key string) time.Duration` - Type-safe duration getter
- `IsSet(key string) bool` - Check if key exists
### 2. Viper Implementation (`internal/config/config.go`)
Implement `ConfigProvider` using Viper:
- Load `config/default.yaml` as baseline
- Merge environment-specific YAML files (development/production)
- Apply environment variable overrides (uppercase with underscores)
- Support nested configuration keys (dot notation)
- Provide all type-safe getters
- Support unmarshaling into structs
- Handle configuration validation errors
### 3. Configuration Loader (`internal/config/loader.go`)
- `LoadConfig(env string) (ConfigProvider, error)` function
- Environment detection (development/production)
- Configuration file discovery
- Validation of required configuration keys
- Error handling and reporting
### 4. Configuration Files
Create configuration files:
**`config/default.yaml`** - Base configuration:
```yaml
environment: development
server:
port: 8080
host: "0.0.0.0"
read_timeout: 30s
write_timeout: 30s
database:
driver: "postgres"
dsn: ""
max_connections: 25
max_idle_connections: 5
logging:
level: "info"
format: "json"
output: "stdout"
```
**`config/development.yaml`** - Development overrides:
```yaml
environment: development
logging:
level: "debug"
format: "console"
```
**`config/production.yaml`** - Production overrides:
```yaml
environment: production
logging:
level: "warn"
format: "json"
```
### 5. DI Integration
- Provider function for ConfigProvider
- Register in DI container
- Make configurable via FX
## Implementation Steps
1. **Install Dependencies**
```bash
go get github.com/spf13/viper@v1.18.0
go get github.com/spf13/cobra@v1.8.0
```
2. **Create Configuration Interface**
- Define `ConfigProvider` interface in `pkg/config/config.go`
- Add package documentation
- Export interface for use by modules
3. **Implement Viper Configuration**
- Create `internal/config/config.go`
- Implement all interface methods
- Handle configuration loading and merging
- Support nested keys and environment variables
4. **Create Configuration Loader**
- Implement `LoadConfig()` function
- Add environment detection logic
- Add validation logic
- Handle errors gracefully
5. **Create Configuration Files**
- Create `config/default.yaml` with base configuration
- Create `config/development.yaml` with dev overrides
- Create `config/production.yaml` with prod overrides
- Ensure proper YAML structure
6. **Integrate with DI**
- Create provider function
- Register in DI container
- Test injection
## Acceptance Criteria
- [ ] `ConfigProvider` interface is defined and documented
- [ ] Viper implementation loads YAML files successfully
- [ ] Environment variables override YAML values
- [ ] Type-safe getters work correctly (string, int, bool, etc.)
- [ ] Configuration can be unmarshaled into structs
- [ ] Nested keys work with dot notation
- [ ] Configuration system is injectable via DI container
- [ ] All modules can access configuration through interface
- [ ] Configuration validation works
- [ ] Error handling is comprehensive
## Related ADRs
- [ADR-0004: Configuration Management](../../adr/0004-configuration-management.md)
## Implementation Notes
- Use Viper's automatic environment variable support (uppercase with underscores)
- Support both single-level and nested configuration keys
- Consider adding configuration schema validation in future
- Environment variable format: `SERVER_PORT`, `DATABASE_DSN`, etc.
- Configuration files should be in YAML for readability
- Support secret manager integration placeholder (Epic 6)
## Testing
```bash
# Test configuration loading
go test ./internal/config/...
# Test type-safe getters
go run -c "test config getters"
# Test environment variable overrides
export SERVER_PORT=9090
go run cmd/platform/main.go
```
## Files to Create/Modify
- `pkg/config/config.go` - Configuration interface
- `internal/config/config.go` - Viper implementation
- `internal/config/loader.go` - Configuration loader
- `config/default.yaml` - Base configuration
- `config/development.yaml` - Development configuration
- `config/production.yaml` - Production configuration
- `internal/di/providers.go` - Add config provider