# ADR-052: Configuration System Architecture

## Status
Accepted

## Context
StarPunk v1.1.1 "Polish" introduces several configurable features to improve production readiness and user experience. Currently, configuration values are hardcoded throughout the application, making customization difficult. We need a consistent, simple approach to configuration management that:

1. Maintains backward compatibility
2. Provides sensible defaults
3. Follows Python best practices
4. Minimizes complexity
5. Supports environment-based configuration

## Decision
We will implement a centralized configuration system using environment variables with fallback defaults, managed through a single configuration module.

### Configuration Architecture

```
Environment Variables (highest priority)
    ↓
Configuration File (optional, .env)
    ↓
Default Values (in code)
```

### Configuration Module Structure

Location: `starpunk/config.py`

Categories:
1. **Search Configuration**
   - `SEARCH_ENABLED`: bool (default: True)
   - `SEARCH_TITLE_LENGTH`: int (default: 100)
   - `SEARCH_HIGHLIGHT_CLASS`: str (default: "highlight")
   - `SEARCH_MIN_SCORE`: float (default: 0.0)

2. **Performance Configuration**
   - `PERF_MONITORING_ENABLED`: bool (default: False)
   - `PERF_SLOW_QUERY_THRESHOLD`: float (default: 1.0 seconds)
   - `PERF_LOG_QUERIES`: bool (default: False)
   - `PERF_MEMORY_TRACKING`: bool (default: False)

3. **Database Configuration**
   - `DB_CONNECTION_POOL_SIZE`: int (default: 5)
   - `DB_CONNECTION_TIMEOUT`: float (default: 10.0)
   - `DB_WAL_MODE`: bool (default: True)
   - `DB_BUSY_TIMEOUT`: int (default: 5000 ms)

4. **Logging Configuration**
   - `LOG_LEVEL`: str (default: "INFO")
   - `LOG_FORMAT`: str (default: structured JSON)
   - `LOG_FILE_PATH`: str (default: None)
   - `LOG_ROTATION`: bool (default: False)

5. **Production Configuration**
   - `SESSION_TIMEOUT`: int (default: 86400 seconds)
   - `HEALTH_CHECK_DETAILED`: bool (default: False)
   - `ERROR_DETAILS_IN_RESPONSE`: bool (default: False)

### Implementation Pattern

```python
# starpunk/config.py
import os
from typing import Any, Optional

class Config:
    """Centralized configuration management"""

    @staticmethod
    def get_bool(key: str, default: bool = False) -> bool:
        """Get boolean configuration value"""
        value = os.environ.get(key, "").lower()
        if value in ("true", "1", "yes", "on"):
            return True
        elif value in ("false", "0", "no", "off"):
            return False
        return default

    @staticmethod
    def get_int(key: str, default: int) -> int:
        """Get integer configuration value"""
        try:
            return int(os.environ.get(key, default))
        except (ValueError, TypeError):
            return default

    @staticmethod
    def get_float(key: str, default: float) -> float:
        """Get float configuration value"""
        try:
            return float(os.environ.get(key, default))
        except (ValueError, TypeError):
            return default

    @staticmethod
    def get_str(key: str, default: str = "") -> str:
        """Get string configuration value"""
        return os.environ.get(key, default)

# Configuration instances
SEARCH_ENABLED = Config.get_bool("STARPUNK_SEARCH_ENABLED", True)
SEARCH_TITLE_LENGTH = Config.get_int("STARPUNK_SEARCH_TITLE_LENGTH", 100)
# ... etc
```

### Environment Variable Naming Convention

All StarPunk environment variables are prefixed with `STARPUNK_` to avoid conflicts:
- `STARPUNK_SEARCH_ENABLED`
- `STARPUNK_PERF_MONITORING_ENABLED`
- `STARPUNK_DB_CONNECTION_POOL_SIZE`
- etc.

## Rationale

### Why Environment Variables?
1. **Standard Practice**: Follows 12-factor app methodology
2. **Container Friendly**: Works well with Docker/Kubernetes
3. **No Dependencies**: Built into Python stdlib
4. **Security**: Sensitive values not in code
5. **Simple**: No complex configuration parsing

### Why Not Alternative Approaches?

**YAML/TOML/INI Files**:
- Adds parsing complexity
- Requires file management
- Not as container-friendly
- Additional dependency

**Database Configuration**:
- Circular dependency (need config to connect to DB)
- Makes deployment more complex
- Not suitable for bootstrap configuration

**Python Config Files**:
- Security risk if user-editable
- Import complexity
- Not standard practice

### Why Centralized Module?
1. **Single Source**: All configuration in one place
2. **Type Safety**: Helper methods ensure correct types
3. **Documentation**: Self-documenting defaults
4. **Testing**: Easy to mock for tests
5. **Validation**: Can add validation logic centrally

## Consequences

### Positive
1. **Backward Compatible**: All existing deployments continue working with defaults
2. **Production Ready**: Ops teams can configure without code changes
3. **Simple Implementation**: ~100 lines of code
4. **Testable**: Easy to test different configurations
5. **Documented**: Configuration options clear in one file
6. **Flexible**: Can override any setting via environment

### Negative
1. **Environment Pollution**: Many environment variables in production
2. **No Validation**: Invalid values fall back to defaults silently
3. **No Hot Reload**: Requires restart to apply changes
4. **Limited Types**: Only primitive types supported

### Mitigations
1. Use `.env` files for local development
2. Add startup configuration validation
3. Log configuration values at startup (non-sensitive only)
4. Document all configuration options clearly

## Alternatives Considered

### 1. Pydantic Settings
**Pros**: Type validation, .env support, modern
**Cons**: New dependency, overengineered for our needs
**Decision**: Too complex for v1.1.1 patch release

### 2. Click Configuration
**Pros**: Already using Click, integrated CLI options
**Cons**: CLI args not suitable for all config, complex precedence
**Decision**: Keep CLI and config separate

### 3. ConfigParser (INI files)
**Pros**: Python stdlib, familiar format
**Cons**: File management complexity, not container-native
**Decision**: Environment variables are simpler

### 4. No Configuration System
**Pros**: Simplest possible
**Cons**: No production flexibility, poor UX
**Decision**: v1.1.1 specifically targets production readiness

## Implementation Notes

1. Configuration module loads at import time
2. Values are immutable after startup
3. Invalid values log warnings but use defaults
4. Sensitive values (tokens, keys) never logged
5. Configuration documented in deployment guide
6. Example `.env.example` file provided

## Testing Strategy

1. Unit tests mock environment variables
2. Integration tests verify default behavior
3. Configuration validation tests
4. Performance impact tests (configuration overhead)

## Migration Path

No migration required - all configuration has sensible defaults that match current behavior.

## References

- [The Twelve-Factor App - Config](https://12factor.net/config)
- [Python os.environ](https://docs.python.org/3/library/os.html#os.environ)
- [Docker Environment Variables](https://docs.docker.com/compose/environment-variables/)

## Document History

- 2025-11-25: Initial draft for v1.1.1 release planning