# 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