# ThrillWiki Configuration System

This document provides an overview of the ThrillWiki configuration system, including how settings are organized, how to configure different environments, and best practices for managing configuration.

## Architecture Overview

ThrillWiki uses a modular configuration architecture that separates concerns and makes settings easy to manage across different environments.

### Directory Structure

```
backend/config/
├── django/                 # Environment-specific settings
│   ├── base.py            # Core Django settings (imports from settings/)
│   ├── local.py           # Local development settings
│   ├── production.py      # Production settings
│   └── test.py            # Test settings
├── settings/              # Modular settings modules
│   ├── __init__.py        # Package documentation
│   ├── cache.py           # Redis caching configuration
│   ├── database.py        # Database and GeoDjango settings
│   ├── email.py           # Email backend configuration
│   ├── logging.py         # Logging formatters, handlers, loggers
│   ├── rest_framework.py  # DRF, JWT, CORS, API docs
│   ├── secrets.py         # Secret management utilities
│   ├── security.py        # Security headers and authentication
│   ├── storage.py         # Static/media files and WhiteNoise
│   ├── third_party.py     # Allauth, Celery, Cloudflare, etc.
│   └── validation.py      # Environment variable validation
└── celery.py              # Celery task queue configuration
```

### How Settings Are Loaded

1. **base.py** defines core Django settings and imports all modular settings
2. Environment-specific files (**local.py**, **production.py**, **test.py**) extend base.py
3. The active settings module is determined by `DJANGO_SETTINGS_MODULE`
4. Modular settings use **python-decouple** to read environment variables

### Environment Selection

The settings module is selected in this order:

1. `DJANGO_SETTINGS_MODULE` environment variable (explicit override)
2. Test command detection (`manage.py test` → `config.django.test`)
3. Production indicators (cloud provider environment variables)
4. `DEBUG=False` → `config.django.production`
5. Default → `config.django.local`

## Configuration Methods

### Using Environment Variables

Environment variables are the primary configuration method. Create a `.env` file from the template:

```bash
cp .env.example .env
# Edit .env with your values
```

### python-decouple

All settings modules use python-decouple for consistent environment variable handling:

```python
from decouple import config

# String with default
DEBUG = config("DEBUG", default=True, cast=bool)

# Integer with validation
PORT = config("PORT", default=8000, cast=int)

# List from comma-separated string
ALLOWED_HOSTS = config(
    "ALLOWED_HOSTS",
    default="localhost",
    cast=lambda v: [s.strip() for s in v.split(",")]
)
```

## Environment-Specific Configuration

### Local Development (`config.django.local`)

- Debug mode enabled
- Local memory cache (no Redis required)
- Console email backend
- Development middleware (nplusone, debug toolbar)
- Relaxed security settings

### Production (`config.django.production`)

- Debug mode disabled
- Redis caching required
- Strict security settings (HSTS, secure cookies)
- JSON logging for log aggregation
- Sentry integration (optional)

### Test (`config.django.test`)

- In-memory SpatiaLite database
- In-memory cache
- Fast password hashing
- Logging disabled
- Celery tasks run synchronously

## Modular Settings Reference

### database.py

- `DATABASES` - Database connection configuration
- `GDAL_LIBRARY_PATH`, `GEOS_LIBRARY_PATH` - GeoDjango libraries
- `CONN_MAX_AGE` - Connection pooling
- `DATABASE_OPTIONS` - PostgreSQL-specific settings

### cache.py

- `CACHES` - Redis cache backends (default, sessions, api)
- `SESSION_*` - Session storage settings
- `CACHE_MIDDLEWARE_*` - Cache middleware settings

### security.py

- `SECURE_*` - Security header settings
- `SESSION_COOKIE_*`, `CSRF_COOKIE_*` - Cookie security
- `AUTH_PASSWORD_VALIDATORS` - Password validation rules
- `PERMISSIONS_POLICY` - Browser feature permissions

### email.py

- `EMAIL_BACKEND` - Email sending backend
- `FORWARD_EMAIL_*` - ForwardEmail configuration
- SMTP settings for custom email servers

### rest_framework.py

- `REST_FRAMEWORK` - DRF configuration
- `CORS_*` - Cross-origin settings
- `SIMPLE_JWT` - JWT token settings
- `REST_AUTH` - dj-rest-auth settings
- `SPECTACULAR_SETTINGS` - OpenAPI documentation

### third_party.py

- `ACCOUNT_*`, `SOCIALACCOUNT_*` - Allauth settings
- `CLOUDFLARE_IMAGES` - Image CDN configuration
- `ROADTRIP_*` - Road trip service settings
- `HEALTH_CHECK` - Health check thresholds

### storage.py

- `STATIC_*`, `MEDIA_*` - File serving configuration
- `STORAGES` - Django 4.2+ storage backends
- `WHITENOISE_*` - Static file optimization
- `FILE_UPLOAD_*` - Upload security limits

### logging.py

- `LOGGING` - Complete logging configuration
- Formatters: verbose, json, simple
- Handlers: console, file, error_file, performance
- Loggers for Django, application, and third-party

## Secret Management

### Validation

Use the management command to validate configuration:

```bash
# Full validation
python manage.py validate_settings

# Strict mode (warnings become errors)
python manage.py validate_settings --strict

# JSON output
python manage.py validate_settings --json

# Secrets only
python manage.py validate_settings --secrets-only
```

### Required Secrets

These secrets must be set in all environments:

| Secret | Description |
|--------|-------------|
| `SECRET_KEY` | Django cryptographic signing key (50+ chars) |
| `DATABASE_URL` | Database connection URL |

### Secret Rotation

For production environments:

1. Enable rotation checking: `SECRET_ROTATION_ENABLED=True`
2. Track versions: `SECRET_KEY_VERSION=1`
3. Monitor expiry warnings in logs
4. Rotate secrets before expiry

See [Secret Management Guide](./secret-management.md) for detailed procedures.

## Troubleshooting

### Common Issues

**Settings module not found:**
```
ModuleNotFoundError: No module named 'config.django.local'
```
Ensure you're running commands from the `backend/` directory.

**Required environment variable missing:**
```
decouple.UndefinedValueError: SECRET_KEY not found
```
Create a `.env` file or set the environment variable.

**Database connection failed:**
```
django.db.utils.OperationalError: could not connect to server
```
Check `DATABASE_URL` format and database server status.

### Validation Errors

Run validation to identify configuration issues:

```bash
python manage.py validate_settings
```

### Debug Configuration

To debug configuration loading:

```python
# In Django shell
from django.conf import settings
print(settings.DEBUG)
print(settings.DATABASES)
```

## Best Practices

1. **Never commit secrets** - Use `.env` files or secret management services
2. **Use environment variables** - Don't hardcode configuration values
3. **Validate on startup** - Catch configuration errors early
4. **Separate environments** - Use different settings for dev/staging/production
5. **Document custom settings** - Add comments explaining non-obvious configuration
6. **Use appropriate defaults** - Secure defaults for production, convenient for development

## Related Documentation

- [Environment Variables Reference](./environment-variables.md)
- [Secret Management Guide](./secret-management.md)
- [Deployment Guide](./deployment.md)
