- Added new updates for Phase A and Phase B in `CLAUDE.md`, detailing the completion of Phase A and the introduction of enriched session metrics in the API response for `GET /api/activity`. - Enhanced the README to include references to new documentation files for scalar canon and composite metrics implementation. - Updated `ACTIVITY_PRODUCTION_ARCHITECTURE_AND_PHASES.md` to reflect the current status of phases and added navigation rules for data access. - Improved `ACTIVITY_SESSION_METRICS_EAV_AGENT_GUIDE.md` with links to new implementation concepts for composite metrics. - Refactored the activity router to integrate enriched session metrics into the activity list responses, ensuring a more comprehensive data presentation.
30 KiB
Konzeptpapier: Speicherung und Bereitstellung von Scalar- und Composite-Sportdaten
Status
Arbeitsstand auf Basis der fachlichen und architektonischen Diskussion.
Dieses Dokument dient als Rahmenwerk für einen Coding Agent und beschreibt die Zielarchitektur, die Abgrenzung der Schichten sowie die empfohlene technische Struktur für Scalar- und Composite-Werte.
1. Ziel und Einordnung
Das System soll zu beliebigen Sportarten Daten speichern und für unterschiedliche nachgelagerte Zwecke bereitstellen, insbesondere:
- Diagramme
- Kennzahlen
- Scores
- regelbasierte Bewertungen
- KI-Platzhalter und KI-Kontextdaten
Das System ist bereits mehrschichtig aufgebaut. Diese Schichtung ist fachlich und technisch sinnvoll und soll ausdrücklich erhalten bleiben.
Bestehende Schichten
- Persistenz / Datenbank
- reiner Wertespeicher
- Speicherung von Scalars und Composites
- Layer 1
- Lesen der Daten
- technische Aufbereitung
- minimale Normalisierung
- Validierung
- Layer 2a
- fachliche Aufbereitung für Diagramme, Kennzahlen, Regeln, Auswertungen
- Layer 2b
- fachliche Aufbereitung für KI-Platzhalter, KI-Zusammenfassungen, KI-Argumente
Zentrale Erkenntnis
Die Persistenz darf nicht mit fachlichen Interpretationen aus Layer 2 überladen werden.
Das bedeutet konkret:
- Die Datenbank speichert Fakten und strukturierte Werte
- Layer 1 stellt kanonische, technische Leseobjekte bereit
- Layer 2 erzeugt daraus fachliche Bedeutung
2. Problemstellung
Bisher werden überwiegend Scalar-Werte gespeichert:
- Datentyp
- Ausprägung (
value) - Einheit
Nun sollen zusätzlich Composite-Werte gespeichert werden.
Aktuell ist der gewünschte Ansatz:
- derselbe Value Store
datatype = compositevalue = jsonb
Die Herausforderung besteht darin, Composite-Werte so einzuführen, dass:
- die Architektur einfach bleibt
- die Schichtentrennung nicht verletzt wird
- das System sportartenübergreifend nutzbar bleibt
- spätere Auswertungslogik nicht bereits in die Persistenz gepresst wird
- die Lösung für Diagramme, Kennzahlen und KI gleichermaßen nutzbar ist
3. Architektonische Leitentscheidung
3.1 Grundsatz
Composite-Werte werden als strukturierte Fakten gespeichert, nicht als fachlich fertig interpretierte Analyseobjekte.
Das bedeutet:
- Die Datenbank kennt nur wenige technische Composite-Container
- Fachliche Archetypen entstehen erst in Layer 2
- Layer 1 vermittelt zwischen Persistenz und fachlicher Verarbeitung
3.2 Was bewusst vermieden wird
Nicht in die Persistenz gehören als Teil des Basis-Composite:
- Scores
- fachliche Bewertungen
- Trainingsqualitätsurteile
- KI-Texte
- narrative Einordnungen
- Interpretationen wie „intervallartig“, „polarisiert“, „gut regeneriert“
- abgeleitete Kennzahlen wie
switch_rate,transition_entropy,readiness_index,plan_match_score
Diese Dinge sind sekundäre Ableitungen und gehören in Layer 2.
4. Fachliche Kernaussage des Konzepts
Die frühere Diskussion über viele fachliche Composite-Archetypen war fachlich sinnvoll, aber für die Persistenz zu komplex.
Deshalb wird das Modell in zwei Ebenen getrennt:
Ebene A: technische Speicherformen
Diese werden in der Datenbank als jsonb gespeichert.
Ebene B: fachliche Analyse-Archetypen
Diese werden in Layer 2 aus den technischen Speicherformen abgeleitet.
Damit gilt:
- wenige Speicherformen
- viele fachliche Projektionen
Das ist die zentrale Designentscheidung dieses Dokuments.
5. Zielbild
5.1 Persistenzebene
Einheitlicher Value Store für:
- Scalars
- Composites
Scalar
datatype != compositevalueist scalarunitals separate Spalte oder Feld
Composite
datatype = compositevalueistjsonbjsonbfolgt einem kleinen, stabilen Basisschema
5.2 Layer 1
Layer 1 liefert für Composite-Werte:
- validierte Daten
- minimal normalisierte Daten
- kanonische Leseobjekte
- keine fachlichen Scores oder Bewertungen
5.3 Layer 2a
Layer 2a erzeugt aus Layer-1-Daten:
- Diagrammserien
- Kennzahlen
- Übergangsmetriken
- Intervallstrukturen
- Auswertungsobjekte
- sportartspezifische Projektionen
5.4 Layer 2b
Layer 2b erzeugt aus Layer-1- oder Layer-2a-Daten:
- KI-Platzhalter
- KI-Faktenlisten
- zusammengefasste Trainingsmerkmale
- explizite, strukturierte Aussagen für Prompts
6. Technische Speicherformen für Composite-Werte
Statt vieler spezieller Composite-Typen werden nur vier technische Container eingeführt:
group_setdistribution_setsequence_setmodel_set
Diese vier Typen reichen als Speicherebene aus.
7. Der gemeinsame Basiskern jedes Composite-Objekts
Jedes Composite-JSONB soll auf einem kleinen gemeinsamen Kern basieren.
7.1 Basisschema
```json
{
"v": 1,
"kind": "group_set",
"domain": "recovery",
"basis": null,
"items": [],
"meta": {
"source": "reported",
"definition_ref": null,
"quality": null
}
}
```
7.2 Pflichtfelder
vkinddomainitems
7.3 Optionale, aber empfohlene Felder
basismeta.sourcemeta.definition_refmeta.quality
7.4 Semantik der Felder
v
Schema-Version des gespeicherten JSON-Objekts.
kind
Technischer Composite-Container.
Erlaubte Werte:
group_setdistribution_setsequence_setmodel_set
domain
Fachlicher Bezugsraum der Daten, zum Beispiel:
heart_ratepowerspeedrecoveryintervalstechniquecritical_power
basis
Optionale Bezugsgröße, zum Beispiel:
timedistancerepetitionsworkcountscore
items
Liste der eigentlichen Teilwerte oder Segmente.
meta.source
Ursprung des Composite-Werts, z. B.:
reportedimporteddetectedderived_l1
meta.definition_ref
Referenz auf eine externe oder interne Definition, etwa:
- HF-Zonenmodell
- Power-Zonenmodell
- Intervall-Template
- Testprotokoll
- Schwellenmodell
meta.quality
Optionale Qualitätskennzeichnung, z. B.:
rawvalidatedestimatedreportedderived
8. Composite-Typ 1: group_set
8.1 Zweck
Speicherung einer kleinen Menge benannter Teilwerte ohne zwingende Reihenfolge und ohne Bandgrenzen.
8.2 Typische Einsatzfälle
- HRV-Bundle
- Wellness-/Readiness-Bundle
- Technik-Bundle
- Submetriken eines Tests
- kleine Sammlungen korrelierter Werte
8.3 Struktur
```json
{
"v": 1,
"kind": "group_set",
"domain": "recovery",
"items": [
{ "key": "rmssd", "value": 42.1, "unit": "ms" },
{ "key": "resting_hr", "value": 54, "unit": "bpm" },
{ "key": "sleep_score", "value": 78, "unit": "score" }
],
"meta": {
"source": "reported",
"definition_ref": "morning_readiness_protocol_v1",
"quality": "validated"
}
}
```
8.4 Pflichtfelder pro Item
keyvalue
8.5 Optionale Item-Felder
unitlabelnote
8.6 Regeln
keymuss innerhalb eines Objekts eindeutig seinvaluedarf scalar odernullsein- keine fachliche Interpretation im Objekt selbst
8.7 Nicht speichern in group_set
Nicht in group_set speichern:
readiness_indexrecovery_flagtrend_direction- generierte Scores
Diese gehören in Layer 2.
9. Composite-Typ 2: distribution_set
9.1 Zweck
Speicherung einer Verteilung über Bänder, Klassen oder Bereiche.
9.2 Typische Einsatzfälle
- Herzfrequenzzonen
- Power-Zonen
- Geschwindigkeitszonen
- Pace-Bänder
- Kadenz-Zonen
- Beschleunigungsbänder
- Sprunghöhenklassen
9.3 Struktur
```json
{
"v": 1,
"kind": "distribution_set",
"domain": "heart_rate",
"basis": "time",
"items": [
{
"key": "z1",
"value": 420,
"unit": "s",
"lower": 50,
"upper": 60,
"range_unit": "%hr_max"
},
{
"key": "z2",
"value": 780,
"unit": "s",
"lower": 60,
"upper": 70,
"range_unit": "%hr_max"
},
{
"key": "z3",
"value": 360,
"unit": "s",
"lower": 70,
"upper": 80,
"range_unit": "%hr_max"
}
],
"meta": {
"source": "reported",
"definition_ref": "hr_zone_model_5_hrmax",
"quality": "validated"
}
}
```
9.4 Pflichtfelder pro Item
keyvalue
9.5 Empfohlene Item-Felder
unitlowerupperrange_unit
9.6 Regeln
keymuss eindeutig seinitemssollen logisch sortierbar seinlowerunduppersind optional, aber bei bandbasierten Sets empfohlenbasisdefiniert, worauf sichvaluebezieht, etwa Zeit, Distanz, Wiederholungen
9.7 Nicht speichern in distribution_set
Nicht in distribution_set speichern:
- Wechselhäufigkeit
- mittlere Verweildauer
- Polarized Index
- Pyramidal Index
- Intervallklassifikation
Das sind Auswertungsergebnisse aus Layer 2.
10. Composite-Typ 3: sequence_set
10.1 Zweck
Speicherung geordneter Sequenzen, Segmente, Zustandsfolgen oder Intervallblöcke.
10.2 Typische Einsatzfälle
- Work-/Recovery-Blöcke
- erkannte HF-Zonen-Segmente
- Pace-Wechsel
- Satz-/Rundenabfolgen
- Drill-Sequenzen
- Ereignisfolgen
10.3 Struktur: Intervallblöcke
```json
{
"v": 1,
"kind": "sequence_set",
"domain": "intervals",
"basis": "time",
"items": [
{ "seq": 1, "label": "work", "start": 0, "duration": 180, "unit": "s" },
{ "seq": 2, "label": "recovery", "start": 180, "duration": 90, "unit": "s" },
{ "seq": 3, "label": "work", "start": 270, "duration": 180, "unit": "s" }
],
"meta": {
"source": "detected",
"definition_ref": "interval_template_optional",
"quality": "derived_l1"
}
}
```
10.4 Struktur: Zustandssegmente
```json
{
"v": 1,
"kind": "sequence_set",
"domain": "heart_rate_zone_state",
"basis": "time",
"items": [
{ "seq": 1, "label": "z2", "start": 0, "duration": 300, "unit": "s" },
{ "seq": 2, "label": "z4", "start": 300, "duration": 90, "unit": "s" },
{ "seq": 3, "label": "z2", "start": 390, "duration": 120, "unit": "s" }
],
"meta": {
"source": "detected",
"definition_ref": "hr_zone_model_5_hrmax"
}
}
```
10.5 Pflichtfelder pro Item
seq- mindestens eines von:
labelkey
- mindestens eines von:
durationstartundend
10.6 Optionale Item-Felder
unitstartendvaluenote
10.7 Regeln
seqmuss eindeutig und aufsteigend sein- Segmente müssen logisch geordnet sein
- bei zeitbasierten Segmenten sollen Start/Dauer-Ende konsistent sein
- keine fachlich interpretierten Kennzahlen im Objekt
10.8 Nicht speichern in sequence_set
Nicht in sequence_set speichern:
switch_countswitch_rate_per_mintransition_entropydensity_indexplan_match_score
Diese Metriken entstehen erst in Layer 2.
11. Composite-Typ 4: model_set
11.1 Zweck
Speicherung kleiner, strukturierter Parametersätze eines Modells.
11.2 Typische Einsatzfälle
- Critical Power / W′
- Critical Speed
- Last-Geschwindigkeits-Profil
- Schwellenmodelle
- Testmodellparameter
11.3 Struktur
```json
{
"v": 1,
"kind": "model_set",
"domain": "critical_power",
"items": [
{ "key": "cp", "value": 286, "unit": "W" },
{ "key": "w_prime", "value": 16800, "unit": "J" },
{ "key": "r_squared", "value": 0.98, "unit": "ratio" }
],
"meta": {
"source": "derived_l1",
"definition_ref": "critical_power_2_parameter",
"quality": "validated"
}
}
```
11.4 Pflichtfelder pro Item
keyvalue
11.5 Optionale Item-Felder
unitci_lowci_higherrornote
11.6 Regeln
keyeindeutig- Modellname und Herleitung über
meta.definition_ref - Modellinterpretation nicht im Objekt selbst speichern
11.7 Nicht speichern in model_set
Nicht in model_set speichern:
- Trainingsdiagnosen
- Handlungsempfehlungen
- automatische Coachingtexte
12. Warum genau diese vier Typen
Diese vier Typen decken den größten Teil realistisch auftretender Composite-Fälle ab, ohne die Persistenz fachlich zu überfrachten.
group_set
Für kleine Bündel benannter Werte
distribution_set
Für Verteilungen über Klassen oder Bänder
sequence_set
Für geordnete Folgen, Segmente und Intervallstrukturen
model_set
Für modellbasierte Parametersätze
Weitere Speichertypen sollen nur eingeführt werden, wenn ein neuer Fall mit diesen vier Typen nicht sinnvoll oder nur mit klaren Verformungen modellierbar ist.
13. Was ausdrücklich nicht Teil der Persistenz-Basisschicht ist
Die Persistenzschicht speichert keine fachlichen Endprodukte.
Nicht Bestandteil der Basis-Composite-Struktur sind:
- Visualisierungsvorgaben
- Diagrammfarblogik
- Scoring-Ergebnisse
- Kennzahlen aus Übergangsanalysen
- narrative KI-Bausteine
- Trainingsklassifikationen
- Empfehlungen
- Bewertungen
- Interpretationen
- sportartspezifische Schlussfolgerungen
14. Layer-1-Konzept
14.1 Zweck von Layer 1
Layer 1 ist die technische Aufbereitungsschicht zwischen Persistenz und Fachlogik.
Layer 1 darf:
- Composite-JSON validieren
- Schema-Version prüfen
kindprüfen- Items lesen
- Einheiten normalisieren
- Basisreferenzen auflösen
- technische DTOs erzeugen
- leichte Plausibilitätsprüfungen durchführen
Layer 1 darf nicht:
- Scores berechnen
- fachliche Bewertungen erzeugen
- Intervallqualität beurteilen
- KI-Platzhalter formulieren
- Trainingscharakter interpretieren
14.2 Layer-1-Output
Layer 1 erzeugt kanonische interne Datenobjekte, zum Beispiel:
ScalarValueDTOGroupSetDTODistributionSetDTOSequenceSetDTOModelSetDTO
14.3 Beispielhafte DTOs
```ts
type ScalarValueDTO = {
id: string
datatype: string
value: number | string | boolean | null
unit?: string | null
}
type GroupItemDTO = {
key: string
value: unknown
unit?: string | null
}
type GroupSetDTO = {
id: string
domain: string
items: GroupItemDTO[]
meta?: Record<string, unknown>
}
type DistributionItemDTO = {
key: string
value: number | null
unit?: string | null
lower?: number | null
upper?: number | null
rangeUnit?: string | null
}
type DistributionSetDTO = {
id: string
domain: string
basis?: string | null
items: DistributionItemDTO[]
meta?: Record<string, unknown>
}
type SequenceItemDTO = {
seq: number
label?: string | null
start?: number | null
end?: number | null
duration?: number | null
unit?: string | null
value?: unknown
}
type SequenceSetDTO = {
id: string
domain: string
basis?: string | null
items: SequenceItemDTO[]
meta?: Record<string, unknown>
}
type ModelItemDTO = {
key: string
value: unknown
unit?: string | null
}
type ModelSetDTO = {
id: string
domain: string
items: ModelItemDTO[]
meta?: Record<string, unknown>
}
```
14.4 Layer-1-Validierungsregeln
Allgemein
- JSON muss parsebar sein
vmuss unterstützt seinkindmuss bekannt seindomaindarf nicht leer seinitemsmuss Array sein
group_set
- jeder Eintrag braucht
key keyeindeutig
distribution_set
- jeder Eintrag braucht
key keyeindeutigvaluenumerisch odernulllower <= upper, wenn beide gesetzt sind
sequence_set
- jeder Eintrag braucht
seq seqeindeutigseqsortierbar- zeitliche Felder konsistent
model_set
- jeder Eintrag braucht
key keyeindeutig
14.5 Layer-1-Normalisierungen
Layer 1 darf minimale Normalisierung durchführen:
- Sekunden, Minuten, Stunden intern vereinheitlichen
- Meter/Kilometer intern vereinheitlichen
- Prozentwerte intern konsistent repräsentieren
- Feldnamen aus Legacy-Importen normalisieren
Wichtig:
Diese Normalisierung ist technisch, nicht fachlich interpretierend.
15. Layer-2a-Konzept: fachliche Analyse- und Diagrammprojektionen
Layer 2a konsumiert Daten aus Layer 1 und erzeugt daraus fachliche Sichtweisen.
Die früher diskutierten fachlichen Archetypen leben hier, nicht in der Persistenz.
15.1 Fachliche Archetypen in Layer 2a
BandDistributionTransitionProfileIntervalBlockProfileEventActionProfileCouplingEfficiencyProfileModelParameterProfileTechniqueCycleProfileReadinessRecoveryProfile
15.2 Mapping von Speicherformen auf Layer-2a-Archetypen
distribution_set
kann projiziert werden auf:
BandDistribution
sequence_set
kann projiziert werden auf:
TransitionProfileIntervalBlockProfileEventActionProfile
group_set
kann projiziert werden auf:
TechniqueCycleProfileReadinessRecoveryProfile- Teile eines
EventActionProfile
model_set
kann projiziert werden auf:
ModelParameterProfile
Kombination mehrerer Werte
kann projiziert werden auf:
CouplingEfficiencyProfile
15.3 Beispiel: TransitionProfile aus sequence_set
Aus einer Zustandssequenz wie:
- z2 -> 300s
- z4 -> 90s
- z2 -> 120s
- z5 -> 60s
kann Layer 2a berechnen:
- Anzahl Wechsel
- Wechselrate
- mittlere Verweildauer pro Zustand
- längste Verweildauer
- Zustandsübergänge
- Intervallcharakter
Diese Werte werden nicht im Basis-Composite gespeichert, sondern von Layer 2a berechnet.
15.4 Beispiel: BandDistribution aus distribution_set
Aus HF-Zonen-Zeiten kann Layer 2a erzeugen:
- Diagrammserien
- Prozentanteile
- Schwerpunktzone
- Exposition oberhalb einer Schwelle
- Intensitätsverteilung
Auch dies entsteht erst in Layer 2a.
16. Layer-2b-Konzept: KI-Projektionen
Layer 2b soll keine Rohwerte direkt in Prompts kippen, sondern fachlich brauchbare Platzhalter erzeugen.
16.1 Grundsatz
Layer 2b konsumiert bevorzugt:
- Layer-1-Daten für einfache Fakten
- Layer-2a-Daten für fachlich verdichtete Aussagen
16.2 Ziel von Layer 2b
Erzeugung strukturierter KI-Bausteine wie:
- „Zeit in hoher Intensität“
- „Intervallstruktur erkannt“
- „Belastungsdichte hoch“
- „geringe Variabilität“
- „Readiness reduziert“
- „Technikmetriken auffällig“
- „intern-externe Lastkopplung stabil“
16.3 Beispielhafte KI-Platzhalter
```json
{
"high_intensity_time_s": 480,
"interval_structure_detected": true,
"switch_count": 12,
"dominant_hr_zone": "z2",
"readiness_state": "normal",
"technique_variability_flag": "elevated"
}
```
Wichtig:
Auch diese Objekte sind keine Persistenz-Basisobjekte, sondern bereitgestellte Kontexte für KI.
17. Composite-Speicherung im bestehenden Value Store
17.1 Annahme über den aktuellen Store
Der bestehende Store speichert Werte als Datensätze mit:
- Datentyp
- Value
- Einheit
- weiteren Metadaten
17.2 Empfohlene Nutzung
Scalar
unverändert speichern
Composite
als Datensatz mit:
datatype = compositevalue = jsonbunit = nulloder optional leer, sofern Einheit innerhalb der Items gespeichert wird
17.3 Empfohlene Zusatzmetadaten außerhalb von value
Soweit euer bestehendes Modell das unterstützt, sind diese Felder außerhalb des JSONB sinnvoll:
idathlete_idsession_idsource_systemmeasured_atdatatypesubtypeoderkindals Hilfsspaltedomainals Hilfsspaltecreated_atupdated_at
Empfehlung
kind und domain sollten nach Möglichkeit zusätzlich indexierbar sein, selbst wenn sie primär im JSONB liegen.
18. JSONB-Schema-Regeln
18.1 Schema-Versionierung
Jedes Composite trägt v.
Regel:
- neue inkompatible Strukturen erhöhen
v - Layer 1 unterstützt definierte Versionen
- unbekannte Versionen werden abgelehnt oder in Fallback-Modus versetzt
18.2 Rückwärtskompatibilität
Wenn möglich:
- neue optionale Felder hinzufügen, ohne
vzu erhöhen - nur strukturelle Brüche führen zu neuer Version
18.3 Dokumentgröße
Composite-Objekte sollen fachlich zusammenhängend, aber nicht unnötig groß sein.
Regel:
- ein Composite speichert einen atomaren strukturierten Sachverhalt
- keine beliebig großen Sammelobjekte
- keine Vermischung mehrerer unabhängiger Analyseebenen
19. Definitionen, Referenzen und Kataloge
Die Basis-Composite-Objekte können Definitionen referenzieren, sollen diese aber nicht voll duplizieren.
19.1 Beispiele für definition_ref
hr_zone_model_5_hrmaxhr_zone_model_5_hrrpower_zone_model_7_ftpmorning_readiness_protocol_v1critical_power_2_parameterboxing_round_structure_3x3karate_interval_template_v2
19.2 Nutzen von definition_ref
Damit kann Layer 2:
- bandbezogene Logik verstehen
- Diagrammbeschriftungen korrekt erzeugen
- Schwellenmodelle zuordnen
- KI-Kontext korrekt ableiten
Wichtig:
definition_ref verweist auf eine Definition, ersetzt diese aber nicht.
20. Abgeleitete Werte zurückspeichern
20.1 Grundsatz
Falls Layer-2-Ergebnisse persistiert werden sollen, sollen sie nicht in das Basis-Composite zurückgeschrieben werden.
Stattdessen werden sie als eigene abgeleitete Werte gespeichert.
20.2 Begründung
So werden vermieden:
- doppelte Wahrheit
- inkonsistente alte Berechnungsergebnisse
- Vermischung von Fakt und Interpretation
- schwierige Rebuilds
20.3 Empfohlenes Muster
Ein abgeleiteter Wert bekommt:
- eigenen Datensatz
- Herkunftskennzeichnung
- Regel-/Berechnungsversion
- Referenz auf Quellwerte
20.4 Beispiel
```json
{
"origin": "derived",
"layer": "2a",
"rule": "transition_profile_v2",
"source_ids": ["value_4711", "value_4712", "value_4713"]
}
```
21. Beispielhafte Ende-zu-Ende-Flows
21.1 Flow A: Herzfrequenzzonen
Persistenz
distribution_set mit Zonenzeiten
Layer 1
DistributionSetDTO
Layer 2a
- Prozentanteile
- Diagrammwerte
- dominante Zone
- Zeit oberhalb bestimmter Zonen
- Intensitätsprofil
Layer 2b
- KI-Platzhalter wie:
dominant_hr_zonehigh_intensity_time_sintensity_distribution_type
21.2 Flow B: Intervalltraining
Persistenz
sequence_set mit Work-/Recovery-Segmenten
Layer 1
SequenceSetDTO
Layer 2a
- Anzahl Blöcke
- Work-Recovery-Verhältnis
- mittlere Blockdauer
- Dichte
- Compliance
- Intervallcharakter
Layer 2b
- KI-Platzhalter wie:
interval_block_countwork_recovery_ratiointerval_density_state
21.3 Flow C: Readiness
Persistenz
group_set mit RMSSD, Ruhepuls, Schlafscore
Layer 1
GroupSetDTO
Layer 2a
- Baseline-Abweichung
- Trend
- Zustandsklassifikation
Layer 2b
readiness_staterecovery_attention_flag
21.4 Flow D: Critical Power
Persistenz
model_set mit cp, w_prime, r_squared
Layer 1
ModelSetDTO
Layer 2a
- Modellgüte
- Vergleich zum Verlauf
- Zonen-/Schwellenableitung
Layer 2b
- KI-konforme Modellzusammenfassung
22. Regeln zur Entscheidung: Scalar oder Composite
22.1 Scalar verwenden, wenn
- genau ein Wert gespeichert wird
- keine strukturierte Untergliederung nötig ist
- keine zusammenhängende Teilwertgruppe existiert
Beispiele:
- Durchschnittspuls
- Maximalpuls
- Distanz
- Dauer
- Durchschnittsleistung
22.2 Composite verwenden, wenn
- mehrere Teilwerte logisch zusammengehören
- die Teilwerte nur gemeinsam sinnvoll interpretierbar sind
- Reihenfolge, Verteilung oder Modellstruktur relevant ist
Beispiele:
- HF-Zonen
- Intervallblöcke
- Readiness-Bundle
- Critical-Power-Parameter
22.3 Nicht jedes Mehrfachfeld ist automatisch Composite
Wenn mehrere Werte unabhängig voneinander existieren und auch einzeln sinnvoll sind, sollen sie weiterhin als Scalars gespeichert werden.
Composite nur dann verwenden, wenn die Gruppe selbst eine eigenständige semantische Einheit ist.
23. Regeln zur Einführung neuer Composite-Formate
Ein neues Composite-Format darf nur eingeführt werden, wenn mindestens eine der folgenden Bedingungen erfüllt ist:
- Der neue Fall lässt sich mit den vier Basis-Typen nicht sinnvoll ausdrücken
- Eine Abbildung wäre nur durch unsaubere oder missbräuchliche Nutzung möglich
- Die Lesbarkeit und Wartbarkeit würden mit den vorhandenen Typen stark leiden
Vor Einführung eines neuen Typs ist zu prüfen:
- Kann es als
group_setmodelliert werden? - Kann es als
distribution_setmodelliert werden? - Kann es als
sequence_setmodelliert werden? - Kann es als
model_setmodelliert werden?
Nur wenn alle vier Antworten fachlich und technisch nicht tragfähig sind, soll ein neuer Speichertyp diskutiert werden.
24. Implementierungsrichtlinien
24.1 Parser
Implementiere einen zentralen Composite-Parser:
- Eingang: Value-Record mit
datatype = composite - Ausgabe: konkretes Layer-1-DTO je
kind
24.2 Validator
Implementiere einen zentralen Validator:
- allgemeine Prüfung
- kind-spezifische Prüfung
- strukturierte Fehlermeldungen
24.3 Mapper
Implementiere Mapper:
CompositeRecord -> GroupSetDTOCompositeRecord -> DistributionSetDTOCompositeRecord -> SequenceSetDTOCompositeRecord -> ModelSetDTO
24.4 Projection Services in Layer 2
Beispiele:
BandDistributionProjectionServiceTransitionProfileServiceIntervalAnalysisServiceReadinessProjectionServiceCouplingAnalysisServiceTechniqueProjectionService
24.5 KI-Mapping in Layer 2b
Beispiele:
AiPlaceholderBuilderAiFactsBuilderAiNarrativeInputBuilder
25. Fehler- und Fallback-Strategie
25.1 Ungültiges Composite
Wenn ein Composite ungültig ist:
- Layer 1 liefert strukturierten Fehler
- der Datensatz wird nicht als fachlich gültig weitergereicht
- optional kann ein „raw passthrough“ für Debugging existieren
25.2 Unbekannte Version
Wenn v unbekannt ist:
- Datensatz markieren
- nicht stillschweigend interpretieren
- optional Migration oder Fallback-Parser nutzen
25.3 Teilweise fehlende Felder
Wenn optionale Felder fehlen:
- lesen, sofern Kernschema gültig bleibt
- fehlende Informationen in Layer 2 berücksichtigen
- keine stillschweigende Erfindung fachlicher Werte
26. Performance- und Wartungsaspekte
26.1 Grundsatz
Die Persistenz soll flexibel, aber strukturiert bleiben.
26.2 Empfehlungen
- kleine, atomare Composite-Objekte
- keine übergroßen Sammelcontainer
kindunddomainindexierbar halten- Definitionen referenzieren statt duplizieren
- fachliche Projektionen nicht als Pflichtbestandteil der Persistenz speichern
26.3 Vorteil dieser Struktur
- geringe Kopplung
- stabile Persistenz
- evolvierbare Fachlogik
- gute Eignung für mehrere Sportarten
- gute Wiederverwendbarkeit in Layer 2a und 2b
27. Migrationsstrategie
Falls bereits Composite-Ansätze existieren, wird folgendes Vorgehen empfohlen:
Phase 1
- Einführung der vier
kind-Typen - Aufbau von Validator und Parser
- Speicherung neuer Composites nach neuem Muster
Phase 2
- Layer-1-DTOs einführen
- bestehende Reader umstellen
Phase 3
- Layer-2a-Projektionen implementieren
- Diagramme und Kennzahlen umstellen
Phase 4
- Layer-2b-KI-Platzhalter auf neue Projektionen aufsetzen
Phase 5
- bestehende Altformate optional migrieren oder kompatibel lesen
28. Nicht-Ziele dieses Dokuments
Dieses Dokument definiert bewusst nicht:
- konkrete UI-Diagrammgestaltung
- konkrete Score-Formeln
- sportartspezifische Bewertungslogiken
- konkrete KI-Prompttexte
- konkrete Datenbanktabellenmigrationen im Detail
- konkrete API-Endpunkte
Diese Punkte sind nachgelagerte Spezifikationen.
29. Offene Erweiterungspunkte
Die Architektur lässt folgende spätere Erweiterungen zu, ohne die Persistenzbasis zu brechen:
- zusätzliche
definition_ref-Kataloge - sportartspezifische Layer-2-Projektionen
- neue KI-Platzhaltertypen
- zusätzliche Qualitäts- und Provenienzfelder
- Rückspeicherung abgeleiteter Werte als eigene Datensätze
- spezielle Event-Detektion in Layer 2a
30. Endgültige Entscheidung
Die Persistenzschicht speichert:
- Scalars
- vier einfache technische Composite-Typen
Layer 1 übernimmt:
- Lesen
- Validieren
- minimale Normalisierung
- DTO-Bildung
Layer 2a übernimmt:
- fachliche Analyse
- Diagrammaufbereitung
- Kennzahlen
- Profile
- Scores
- Interpretationen
Layer 2b übernimmt:
- KI-Platzhalter
- KI-Fakten
- KI-Zusammenfassungen
- KI-taugliche Verdichtungen
31. Kurzfassung für einen Coding Agent
Ziel
Erweitere den bestehenden Value Store um Composite-Werte auf jsonb-Basis, ohne fachliche Analyse-Logik in die Persistenz zu verlagern.
Implementiere
- Unterstützung für
datatype = composite - vier
kind-Typen:group_setdistribution_setsequence_setmodel_set
- Layer-1-Validatoren und Parser
- kanonische DTOs pro
kind - klare Trennung:
- Persistenz = strukturierte Fakten
- Layer 1 = technische Aufbereitung
- Layer 2a = fachliche Projektionen
- Layer 2b = KI-Projektionen
Vermeide
- Scores im Basis-Composite
- Interpretationen im Basis-Composite
- Diagramm- oder KI-Logik in der Persistenz
- zu viele spezialisierte Composite-Speichertypen
32. Akzeptanzkriterien
Die Umsetzung gilt als fachlich passend, wenn:
- ein Composite-Value mit
jsonbgespeichert werden kann - Layer 1 den Typ sicher validieren und lesen kann
- die Persistenz keine fachlichen Layer-2-Interpretationen erzwingt
- HF-Zonen als
distribution_setabbildbar sind - Intervallblöcke als
sequence_setabbildbar sind - Readiness-Bundles als
group_setabbildbar sind - Modellparameter als
model_setabbildbar sind - Layer 2a daraus fachliche Projektionen erzeugen kann
- Layer 2b daraus KI-Platzhalter erzeugen kann
- neue Sportarten ohne neue Persistenzarchitektur integrierbar sind
33. Schlussformel
Die Leitentscheidung dieses Konzepts lautet:
Die Datenbank speichert Struktur.
Layer 1 liefert kanonische technische Objekte.
Layer 2 erzeugt fachliche Bedeutung.
KI konsumiert diese Bedeutung, nicht die rohe Persistenzstruktur.
Damit bleibt das System einfach genug für die Implementierung und offen genug für spätere sportartspezifische Erweiterungen.