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.
172 lines
5.4 KiB
Markdown
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
|
|
|