|
| 1 | +# Decorator-Based API Implementation Plan |
| 2 | + |
| 3 | +## Ziel |
| 4 | +Implementierung einer decorator-basierten API für flask-inputfilter, die vollständig rückwärtskompatibel zur bestehenden imperativen API ist und beide Ansätze in einer Klasse kombinierbar macht. |
| 5 | + |
| 6 | +## Vorher/Nachher Vergleich |
| 7 | + |
| 8 | +### Aktuell (Imperativ) |
| 9 | +```python |
| 10 | +class UserInputFilter(InputFilter): |
| 11 | + def __init__(self): |
| 12 | + super().__init__() |
| 13 | + self.add('name', required=True, validators=[IsStringValidator()]) |
| 14 | + self.add('age', required=True, validators=[IsIntegerValidator()]) |
| 15 | + self.add('email', required=True, validators=[IsStringValidator()]) |
| 16 | +``` |
| 17 | + |
| 18 | +### Neu (Deklarativ + Gemischt) |
| 19 | +```python |
| 20 | +class UserInputFilter(InputFilter): |
| 21 | + # Decorator-basierte Felder |
| 22 | + name: str = field(required=True, validators=[IsStringValidator()]) |
| 23 | + age: int = field(required=True, validators=[IsIntegerValidator()]) |
| 24 | + |
| 25 | + # Global Validators/Filters |
| 26 | + _global_validators = [SomeGlobalValidator()] |
| 27 | + _global_filters = [StringTrimFilter()] |
| 28 | + |
| 29 | + # Conditions |
| 30 | + _conditions = [ExactlyOneOfCondition(['phone', 'email'])] |
| 31 | + |
| 32 | + # Weiterhin imperative API möglich |
| 33 | + def __init__(self): |
| 34 | + super().__init__() |
| 35 | + if self.needs_dynamic_field(): |
| 36 | + self.add('dynamic_field', required=False) |
| 37 | +``` |
| 38 | + |
| 39 | +## Implementierungsschritte |
| 40 | + |
| 41 | +### Phase 1: Descriptor-System |
| 42 | +- [ ] **FieldDescriptor** (`flask_inputfilter/decorators/field_descriptor.py`) |
| 43 | + - Hauptklasse für field() decorator |
| 44 | + - Unterstützt alle Parameter: required, default, fallback, filters, validators, steps, external_api, copy |
| 45 | + |
| 46 | +- [ ] **ConditionDescriptor** (`flask_inputfilter/decorators/condition_descriptor.py`) |
| 47 | + - Für Conditions auf Klassenebene |
| 48 | + |
| 49 | +- [ ] **GlobalValidatorDescriptor** (`flask_inputfilter/decorators/global_validator_descriptor.py`) |
| 50 | + - Für `_global_validators` Klassen-Attribut |
| 51 | + |
| 52 | +- [ ] **GlobalFilterDescriptor** (`flask_inputfilter/decorators/global_filter_descriptor.py`) |
| 53 | + - Für `_global_filters` Klassen-Attribut |
| 54 | + |
| 55 | +### Phase 2: Factory Functions |
| 56 | +- [ ] **Factory-Funktionen** (`flask_inputfilter/decorators/__init__.py`) |
| 57 | + ```python |
| 58 | + def field(**kwargs) -> FieldDescriptor |
| 59 | + def condition(cond) -> ConditionDescriptor |
| 60 | + def global_validator(validator) -> GlobalValidatorDescriptor |
| 61 | + def global_filter(filter) -> GlobalFilterDescriptor |
| 62 | + ``` |
| 63 | + |
| 64 | +### Phase 3: Metaclass |
| 65 | +- [ ] **InputFilterMeta** (`flask_inputfilter/meta.py`) |
| 66 | + - Scannt Klassen-Attribute nach Descriptors |
| 67 | + - Sammelt `_conditions`, `_global_validators`, `_global_filters` |
| 68 | + - Registriert sie in der Klasse für später |
| 69 | + |
| 70 | +### Phase 4: InputFilter Integration |
| 71 | +- [ ] **InputFilter erweitern** (`flask_inputfilter/input_filter.py`) |
| 72 | + - Erbt von LegacyMethodsMixin + existierender Funktionalität |
| 73 | + - Nutzt InputFilterMeta als Metaclass |
| 74 | + - `_register_decorator_fields()` Methode für automatische Registration |
| 75 | + |
| 76 | +### Phase 5: Testing |
| 77 | +- [ ] **Umfangreiche Test-Suite** |
| 78 | + - Positive Tests für alle Decorator-Features |
| 79 | + - Negative Tests für Fehlerfälle |
| 80 | + - Mixed API Tests (decorator + imperativ) |
| 81 | + - Inheritance Tests |
| 82 | + - Performance Tests |
| 83 | + - Flask Integration Tests |
| 84 | + - Edge Cases |
| 85 | + |
| 86 | +### Phase 6: Dokumentation |
| 87 | +- [ ] **API Dokumentation aktualisieren** |
| 88 | +- [ ] **Migration Guide erstellen** |
| 89 | +- [ ] **Beispiele erweitern** |
| 90 | + |
| 91 | +## Technische Details |
| 92 | + |
| 93 | +### Dateistruktur |
| 94 | +``` |
| 95 | +flask_inputfilter/ |
| 96 | +├── mixins/ |
| 97 | +│ ├── __init__.py |
| 98 | +│ ├── legacy_methods_mixin.py # add_*, replace, remove |
| 99 | +│ └── data_mixin.py # existierend |
| 100 | +├── decorators/ |
| 101 | +│ ├── __init__.py # Factory-Funktionen |
| 102 | +│ ├── field_descriptor.py |
| 103 | +│ ├── condition_descriptor.py |
| 104 | +│ ├── global_validator_descriptor.py |
| 105 | +│ └── global_filter_descriptor.py |
| 106 | +├── meta.py # InputFilterMeta |
| 107 | +└── input_filter.py # Erweiterte Hauptklasse |
| 108 | + |
| 109 | +tests/ |
| 110 | +├── test_decorator_input_filter.py # Haupt-Tests |
| 111 | +├── test_descriptors.py # Descriptor-Tests |
| 112 | +├── test_mixed_api.py # Mixed API Tests |
| 113 | +└── test_performance.py # Performance-Vergleiche |
| 114 | +``` |
| 115 | + |
| 116 | +### Kompatibilität |
| 117 | +- **100% Rückwärtskompatibel**: Alle existierenden InputFilter funktionieren unverändert |
| 118 | +- **Gradueller Übergang**: Felder können schrittweise von imperativ zu deklarativ migriert werden |
| 119 | +- **Type Safety**: Type Hints bleiben erhalten und werden von IDEs unterstützt |
| 120 | + |
| 121 | +### Testabdeckung Ziele |
| 122 | +- **>95% Code Coverage** für alle neuen Komponenten |
| 123 | +- **Negative Tests** für alle Fehlerszenarien |
| 124 | +- **Integration Tests** mit Flask |
| 125 | +- **Performance Benchmarks** vs. imperative API |
| 126 | +- **Memory Usage Tests** für Descriptor-Overhead |
| 127 | + |
| 128 | +## Erfolgskriterien |
| 129 | +1. ✅ Alle existierenden Tests laufen weiterhin durch |
| 130 | +2. ✅ Neue decorator-basierte API funktioniert vollständig |
| 131 | +3. ✅ Mixed API (decorator + imperativ) funktioniert korrekt |
| 132 | +4. ✅ Type Hints funktionieren in IDEs |
| 133 | +5. ✅ Performance-Impact <5% gegenüber imperativer API |
| 134 | +6. ✅ Test Coverage >95% für neue Features |
| 135 | +7. ✅ Dokumentation und Beispiele sind vollständig |
| 136 | + |
| 137 | +## Risiken & Mitigation |
| 138 | +- **Metaclass-Konflikte**: Sorgfältige Tests mit anderen Libraries |
| 139 | +- **Performance-Impact**: Benchmarking und Optimierung |
| 140 | +- **Type System Konflikte**: Tests mit mypy/pylint |
| 141 | +- **Breaking Changes**: Extensive Backward-Compatibility Tests |
0 commit comments