- .gitignore: .claude/docs, rules, commands tracken; settings.local weiter ignorieren - DOCUMENTATION.md: verbindliche Ablage functional/technical/working/issues - .claude/README.md: Agent-Einstieg; GITEA_ISSUES_INDEX aus MCP (Stand 2026-04-08) - Arbeitspapiere von docs/ nach .claude/docs/working/ verschoben - docs/MEMBERSHIP_SYSTEM.md als Stub; kanonisch technical/MEMBERSHIP_SYSTEM.md - CLAUDE.md Pflichtlektüre und Links angepasst; docs/README.md vereinfacht Made-with: Cursor
5.8 KiB
5.8 KiB
Training Profile Resolver (Layer 1) — technisches Scaffold
Stand: 2026-04-06
Zweck: Erweiterbare technische Basis für spätere trainingsprofil-basierte Auswertungen, ohne freie Formel-/Skript-Engine und ohne Kopplung an KI oder Charts.
1. Einordnung in Layer 1
| Aspekt | Beschreibung |
|---|---|
| Ort | backend/data_layer/training_profile/ |
| Rolle | Reine Orchestrierung: Templates → registrierte Built-in-Algorithmen → strukturiertes Ergebnis inkl. Focus-Area-Beiträge |
| Single Source of Truth | Berechnungslogik der Algorithmen lebt in Python-Modulen; Templates wählen nur Algorithmus-ID + Parameter + Dimensionen + FA-Mapping |
| Rückwärtskompatibel | Keine Änderungen an bestehenden Data-Layer-Metriken, Placeholdern oder Chart-Routern |
2. Modulübersicht
| Pfad | Inhalt |
|---|---|
models.py |
CalculationTemplate, DimensionSpec, FocusAreaMapping, TrainingBaseProfile, TrainingEvaluationResult, AlgorithmRunResult |
resolver.py |
resolve_training_evaluation(), resolve_for_base_profile() |
algorithms/registry.py |
register_algorithm, get_algorithm, list_algorithm_ids |
algorithms/builtin/threshold_band.py |
Beispiel: Schwellen-Bänder → Score 0–1 |
algorithms/builtin/linear_range.py |
Beispiel: lineare Abbildung [min,max] → [0,1] |
templates/registry.py |
Beispiel-Templates (deklarativ, in-code) |
profiles/registry.py |
Beispiel-Trainings-Basisprofile (Default-Template, optionale Dimensions-Whitelist) |
3. Built-in-Algorithmen
- Algorithmen sind fest im Code implementiert und über eine ID referenzierbar.
- Neue Algorithmen: Funktion mit Signatur
(*, inputs, params) -> AlgorithmRunResultundregister_algorithm(id, fn)(Start-up-Registrierung inregistry.pyoder Import eines Moduls, das registriert). - Nicht vorgesehen: Nutzerdefinierte Ausdrücke, DSL,
eval, externe Skripte.
Implementiert (Beispiele):
threshold_band—params.value_key,params.bands(Liste mitmax/score)linear_range—params.value_key,min_value,max_value, optionalinvert
4. Templates (deklarativ)
Ein CalculationTemplate besteht aus:
id,version,labeldimensions: Liste vonDimensionSpecmit:key— Dimensionsnamealgorithm_id— referenziert registrierten Algorithmusinputs— erwartete Schlüssel im flachenactivity_inputs-Dict des Aufrufersparams— JSON-serialisierbare Parameter für den Algorithmusmaps_to— Tupel(focus_area_key, weight)— gewichteter Anteil der normalisierten Dimension am jeweiligen Focus Area
Aggregation: Pro Dimension wird normalized_score * weight pro Focus Area addiert (focus_area_contributions).
5. Trainings-Basisprofile (Scaffold)
TrainingBaseProfile:
key,labeldefault_template_id— verweist auf einCalculationTemplate- optional
allowed_dimension_keys— nur diese Dimensionen aus dem Template werden ausgeführt (Filter)
Aktuell nur In-Code-Registry; später denkbar: DB-Verknüpfung Trainingstyp → Profil-Key.
6. Ergebnisstruktur (TrainingEvaluationResult)
template_id,template_version,base_profile_keydimension_results[]— pro Dimension: Scores, fehlende Inputs, Evidencefocus_area_contributions—dict[str, float](Focus-Area-Key → aggregierter Beitrag)confidence—high|medium|low|insufficient(heuristisch aus fehlenden Pflicht-Inputs)evidence— Metadaten (z. B. Anzahl Dimensionen, Input-Keys)- optional
trace— beiinclude_trace=Truefür Debugging
to_serializable() liefert ein JSON-taugliches Dict für APIs/Persistenz.
7. Öffentliche API (Import)
from data_layer.training_profile import (
resolve_training_evaluation,
resolve_for_base_profile,
TrainingEvaluationResult,
CalculationTemplate,
)
Registries:
from data_layer.training_profile.templates.registry import get_calculation_template
from data_layer.training_profile.profiles.registry import get_training_base_profile
from data_layer.training_profile.algorithms.registry import get_algorithm, list_algorithm_ids
8. Erweiterungspunkte (für spätere Produktlogik)
- Neue Algorithmen — neue Datei unter
algorithms/builtin/, inregistry.pyregistrieren. - Templates — weitere
CalculationTemplate-Instanzen intemplates/registry.pyoder später aus DB laden (Loader baut dieselben Dataclasses). - Profile — weitere
TrainingBaseProfile-Einträge; Anbindung antraining_types/ Aktivität. - Confidence/Evidence — feinere Regeln (Datenqualität, Mindestkriterien) im Resolver oder in den Algorithmen.
- Normalisierung der FA-Beiträge — optional globale Skalierung/Cap (aktuell rein additive Gewichtung).
9. Was absichtlich offen ist
- Finale Domänenregeln (welche Dimensionen für welchen Sport)
- Vollständige Liste Basisprofile und Templates
- Persistenz von Evaluationsergebnissen
- Integration in Placeholder-Resolver, Charts, Admin-UI
- Validierung gegen
focus_area_definitions(DB-Keys)
10. Kritische Einschätzung
| Bereich | Bewertung |
|---|---|
| Registry + Algorithmus-Schnittstelle | Robust, testbar, erweiterbar |
| Template-Modelle (frozen dataclasses) | Stabil, typsicher, serialisierbar |
| Beispiel-Algorithmen | Minimal, nur zur Demonstration der Pipeline |
| Confidence | Heuristik — für Produktion noch abzustimmen |
| Focus-Area-Gewichte | Additiv, nicht normiert — Domänenentscheidung für später |
11. Tests
backend/tests/test_training_profile_resolver.py — Registry, Resolver, Profil-Filter, Serialisierung, unbekannter Algorithmus.
Ausführen (aus backend/):
python -m pytest tests/test_training_profile_resolver.py -v