b03ebab747
Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com>
221 lines
6.9 KiB
Markdown
221 lines
6.9 KiB
Markdown
# Settings Framework Analysis
|
|
|
|
## Question: Should we use an existing library instead?
|
|
|
|
This document analyzes whether an existing settings management framework should replace the custom implementation.
|
|
|
|
## TL;DR
|
|
|
|
**Answer: No. Keep the custom implementation.**
|
|
|
|
No existing library provides all required features. The custom implementation is purpose-built, well-tested, documented, and production-ready at ~1,280 lines of code.
|
|
|
|
---
|
|
|
|
## Research: Available Libraries
|
|
|
|
### 1. **django-constance**
|
|
- **What it does**: Dynamic Django settings with admin UI and database backing
|
|
- **Pros**: Mature, proven, admin UI, DB-backed
|
|
- **Cons**: Django-specific, incompatible with FastAPI
|
|
- **Verdict**: ❌ Not applicable
|
|
|
|
### 2. **Dynaconf**
|
|
- **What it does**: Multi-source configuration (env, files, Redis, Vault)
|
|
- **Pros**: Supports multiple backends, good for loading config
|
|
- **Cons**: No UI, no encryption, no setup wizard, no precedence indicators
|
|
- **Verdict**: ⚠️ Config loading only, missing 80% of features
|
|
|
|
### 3. **pydantic-settings (BaseSettings)**
|
|
- **What it does**: Type-safe settings from environment variables
|
|
- **Pros**: Already using it! Type validation, great dev experience
|
|
- **Cons**: No database backing, no UI, no encryption
|
|
- **Verdict**: ✅ Already integrated as foundation
|
|
|
|
### 4. **SQLAdmin / FastAPI-Admin**
|
|
- **What it does**: Generic admin interface for SQLAlchemy models
|
|
- **Pros**: CRUD UI for any model, FastAPI integration
|
|
- **Cons**: Generic CRUD, no settings-specific features, no precedence, no wizard
|
|
- **Verdict**: ⚠️ Could wrap ApplicationSettings model but loses custom features
|
|
|
|
### 5. **python-decouple**
|
|
- **What it does**: Strict separation of config from code
|
|
- **Pros**: Simple, clean API
|
|
- **Cons**: Environment variables only, no database, no UI
|
|
- **Verdict**: ❌ Too basic for requirements
|
|
|
|
### 6. **HashiCorp Vault**
|
|
- **What it does**: Enterprise secrets management
|
|
- **Pros**: Industry standard, encryption, auditing, HA
|
|
- **Cons**: External service, complex setup, overkill for MVP
|
|
- **Verdict**: ⚠️ Good for production secrets, but heavy dependency
|
|
|
|
---
|
|
|
|
## Feature Comparison Matrix
|
|
|
|
| Feature | Custom | django-constance | Dynaconf | SQLAdmin | Vault |
|
|
|---------|--------|------------------|----------|----------|-------|
|
|
| FastAPI Integration | ✅ | ❌ | ✅ | ✅ | ⚠️ |
|
|
| Database-backed | ✅ | ✅ | ⚠️ | ✅ | ✅ |
|
|
| Precedence (DB>ENV>DEFAULT) | ✅ | ⚠️ | ⚠️ | ❌ | ❌ |
|
|
| Encryption | ✅ | ❌ | ❌ | ❌ | ✅ |
|
|
| Web UI | ✅ | ✅ | ❌ | ✅ | ✅ |
|
|
| Admin Auth | ✅ | ✅ | ❌ | ✅ | ✅ |
|
|
| Setup Wizard | ✅ | ❌ | ❌ | ❌ | ❌ |
|
|
| Source Indicators | ✅ | ❌ | ❌ | ❌ | ❌ |
|
|
| Pydantic Integration | ✅ | ❌ | ⚠️ | ❌ | ❌ |
|
|
| Show/Hide Sensitive | ✅ | ⚠️ | ❌ | ❌ | ✅ |
|
|
| Optional Fields | ✅ | ⚠️ | ❌ | ✅ | ⚠️ |
|
|
|
|
**None provide all features.**
|
|
|
|
---
|
|
|
|
## Code Size Comparison
|
|
|
|
### Custom Implementation (Current)
|
|
```
|
|
Core Python: ~800 lines
|
|
- app/utils/encryption.py: 150 lines
|
|
- app/utils/settings_service.py: 330 lines
|
|
- app/utils/setup_wizard.py: 180 lines
|
|
- app/views/settings.py: 100 lines
|
|
- app/views/wizard.py: 120 lines
|
|
|
|
Templates: ~480 lines
|
|
- settings.html: 280 lines
|
|
- setup_wizard.html: 200 lines
|
|
|
|
Tests: ~320 lines
|
|
- test_settings.py: 320 lines
|
|
|
|
Total: ~1,600 lines (including tests)
|
|
Dependencies: cryptography (1 new)
|
|
```
|
|
|
|
### Hypothetical: SQLAdmin + Dynaconf Approach
|
|
```
|
|
Library Setup: ~50 lines
|
|
Custom Glue Code:
|
|
- Precedence logic: ~150 lines
|
|
- Encryption wrapper: ~150 lines
|
|
- Setup wizard: ~300 lines
|
|
- Source detection: ~100 lines
|
|
- Custom templates: ~400 lines
|
|
- Integration code: ~100 lines
|
|
|
|
Tests: ~250 lines
|
|
|
|
Total: ~1,500 lines
|
|
Dependencies: sqladmin, dynaconf, cryptography (3 new)
|
|
Complexity: High (gluing 2 libraries together)
|
|
```
|
|
|
|
**Conclusion**: Similar code volume, more dependencies, higher complexity.
|
|
|
|
---
|
|
|
|
## Decision Matrix
|
|
|
|
### Pros of Custom Implementation ✅
|
|
1. **Purpose-Built**: Exactly matches requirements
|
|
2. **Maintainable**: ~1,600 lines is reasonable size
|
|
3. **Well-Tested**: Comprehensive test coverage
|
|
4. **Documented**: User guide + technical docs
|
|
5. **Working**: Fully functional, no migration risk
|
|
6. **Flexible**: Easy to modify for specific needs
|
|
7. **Minimal Dependencies**: Only cryptography added
|
|
8. **Full Control**: No library limitations
|
|
9. **No Migration**: Already complete and working
|
|
|
|
### Cons of Custom Implementation ⚠️
|
|
1. **Maintenance Burden**: Need to maintain ourselves
|
|
2. **No Community**: Not benefiting from external contributions
|
|
3. **Reinventing Wheel**: (Partially - but no wheel exists for our combo)
|
|
|
|
### Pros of Using Existing Library
|
|
1. **Community Support**: Bug fixes, updates
|
|
2. **Battle-Tested**: Used by many projects
|
|
3. **Less Code**: (Maybe - but we'd need glue code)
|
|
|
|
### Cons of Using Existing Library ❌
|
|
1. **No Perfect Match**: Would need 2-3 libraries + glue
|
|
2. **Migration Risk**: Rewrite working code
|
|
3. **More Dependencies**: Increased attack surface
|
|
4. **Less Flexible**: Library limitations
|
|
5. **Learning Curve**: Team needs to learn library quirks
|
|
6. **Integration Complexity**: Making libraries work together
|
|
|
|
---
|
|
|
|
## Recommendation
|
|
|
|
### **KEEP CUSTOM IMPLEMENTATION** ✅
|
|
|
|
**Rationale:**
|
|
1. No single library provides all features
|
|
2. Combining libraries requires similar code volume
|
|
3. Custom code is working, tested, and documented
|
|
4. Migration has high risk, low reward
|
|
5. Maintenance burden is acceptable for ~1,600 lines
|
|
6. Team already understands the custom code
|
|
|
|
### Future Evolution Path
|
|
|
|
For production/enterprise deployments, consider **hybrid approach**:
|
|
|
|
```
|
|
Phase 1 (Current - MVP):
|
|
Settings: DB + ENV + DEFAULT
|
|
Encryption: Fernet (app-level)
|
|
UI: Custom settings page
|
|
|
|
Phase 2 (Production - Optional):
|
|
Settings: DB + ENV + DEFAULT (keep)
|
|
Secrets: HashiCorp Vault (add)
|
|
Encryption: Vault-managed
|
|
UI: Settings page + Vault integration
|
|
```
|
|
|
|
**Implementation Example:**
|
|
```python
|
|
# Graceful Vault integration
|
|
def get_secret(key: str) -> str:
|
|
if vault_enabled():
|
|
return vault.get_secret(key)
|
|
else:
|
|
return settings_from_db(key) # Fallback
|
|
```
|
|
|
|
**Benefits:**
|
|
- ✅ Keep working settings UI
|
|
- ✅ Add enterprise secret management when needed
|
|
- ✅ Gradual migration path
|
|
- ✅ No breaking changes
|
|
|
|
---
|
|
|
|
## Conclusion
|
|
|
|
The custom implementation is **the right choice** for DocuElevate because:
|
|
|
|
1. ✅ **No alternative**: No library does everything needed
|
|
2. ✅ **Right-sized**: 1,600 lines is maintainable
|
|
3. ✅ **Quality**: Well-tested, documented, working
|
|
4. ✅ **Specific**: Tailored to exact requirements
|
|
5. ✅ **Future-proof**: Can add Vault later if needed
|
|
|
|
**Ship it!** 🚀
|
|
|
|
---
|
|
|
|
## References
|
|
|
|
- [django-constance](https://github.com/jazzband/django-constance)
|
|
- [Dynaconf](https://www.dynaconf.com/)
|
|
- [pydantic-settings](https://docs.pydantic.dev/latest/usage/pydantic_settings/)
|
|
- [SQLAdmin](https://aminalaee.dev/sqladmin/)
|
|
- [FastAPI-Admin](https://github.com/fastapi-admin/fastapi-admin)
|
|
- [HashiCorp Vault](https://www.vaultproject.io/)
|