mitai-jinkendo/.claude/docs/technical/functional_concept_composite_data.md
Lars fa3e66fb31
All checks were successful
Deploy Development / deploy (push) Successful in 51s
Build Test / pytest-backend (push) Successful in 4s
Build Test / lint-backend (push) Successful in 0s
Build Test / build-frontend (push) Successful in 18s
feat: Update activity documentation and enhance API responses with session metrics
- 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.
2026-04-17 12:55:12 +02:00

30 KiB
Raw Blame History

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 = composite
  • value = jsonb

Die Herausforderung besteht darin, Composite-Werte so einzuführen, dass:

  1. die Architektur einfach bleibt
  2. die Schichtentrennung nicht verletzt wird
  3. das System sportartenübergreifend nutzbar bleibt
  4. spätere Auswertungslogik nicht bereits in die Persistenz gepresst wird
  5. 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 != composite
  • value ist scalar
  • unit als separate Spalte oder Feld

Composite

  • datatype = composite
  • value ist jsonb
  • jsonb folgt 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:

  1. group_set
  2. distribution_set
  3. sequence_set
  4. model_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

  • v
  • kind
  • domain
  • items

7.3 Optionale, aber empfohlene Felder

  • basis
  • meta.source
  • meta.definition_ref
  • meta.quality

7.4 Semantik der Felder

v

Schema-Version des gespeicherten JSON-Objekts.

kind

Technischer Composite-Container.
Erlaubte Werte:

  • group_set
  • distribution_set
  • sequence_set
  • model_set

domain

Fachlicher Bezugsraum der Daten, zum Beispiel:

  • heart_rate
  • power
  • speed
  • recovery
  • intervals
  • technique
  • critical_power

basis

Optionale Bezugsgröße, zum Beispiel:

  • time
  • distance
  • repetitions
  • work
  • count
  • score

items

Liste der eigentlichen Teilwerte oder Segmente.

meta.source

Ursprung des Composite-Werts, z. B.:

  • reported
  • imported
  • detected
  • derived_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.:

  • raw
  • validated
  • estimated
  • reported
  • derived

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

  • key
  • value

8.5 Optionale Item-Felder

  • unit
  • label
  • note

8.6 Regeln

  • key muss innerhalb eines Objekts eindeutig sein
  • value darf scalar oder null sein
  • keine fachliche Interpretation im Objekt selbst

8.7 Nicht speichern in group_set

Nicht in group_set speichern:

  • readiness_index
  • recovery_flag
  • trend_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

  • key
  • value

9.5 Empfohlene Item-Felder

  • unit
  • lower
  • upper
  • range_unit

9.6 Regeln

  • key muss eindeutig sein
  • items sollen logisch sortierbar sein
  • lower und upper sind optional, aber bei bandbasierten Sets empfohlen
  • basis definiert, worauf sich value bezieht, 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:
    • label
    • key
  • mindestens eines von:
    • duration
    • start und end

10.6 Optionale Item-Felder

  • unit
  • start
  • end
  • value
  • note

10.7 Regeln

  • seq muss 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_count
  • switch_rate_per_min
  • transition_entropy
  • density_index
  • plan_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

  • key
  • value

11.5 Optionale Item-Felder

  • unit
  • ci_low
  • ci_high
  • error
  • note

11.6 Regeln

  • key eindeutig
  • 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
  • kind prü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:

  • ScalarValueDTO
  • GroupSetDTO
  • DistributionSetDTO
  • SequenceSetDTO
  • ModelSetDTO

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
  • v muss unterstützt sein
  • kind muss bekannt sein
  • domain darf nicht leer sein
  • items muss Array sein

group_set

  • jeder Eintrag braucht key
  • key eindeutig

distribution_set

  • jeder Eintrag braucht key
  • key eindeutig
  • value numerisch oder null
  • lower <= upper, wenn beide gesetzt sind

sequence_set

  • jeder Eintrag braucht seq
  • seq eindeutig
  • seq sortierbar
  • zeitliche Felder konsistent

model_set

  • jeder Eintrag braucht key
  • key eindeutig

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

  1. BandDistribution
  2. TransitionProfile
  3. IntervalBlockProfile
  4. EventActionProfile
  5. CouplingEfficiencyProfile
  6. ModelParameterProfile
  7. TechniqueCycleProfile
  8. ReadinessRecoveryProfile

15.2 Mapping von Speicherformen auf Layer-2a-Archetypen

distribution_set

kann projiziert werden auf:

  • BandDistribution

sequence_set

kann projiziert werden auf:

  • TransitionProfile
  • IntervalBlockProfile
  • EventActionProfile

group_set

kann projiziert werden auf:

  • TechniqueCycleProfile
  • ReadinessRecoveryProfile
  • 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 = composite
  • value = jsonb
  • unit = null oder 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:

  • id
  • athlete_id
  • session_id
  • source_system
  • measured_at
  • datatype
  • subtype oder kind als Hilfsspalte
  • domain als Hilfsspalte
  • created_at
  • updated_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 v zu 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_hrmax
  • hr_zone_model_5_hrr
  • power_zone_model_7_ftp
  • morning_readiness_protocol_v1
  • critical_power_2_parameter
  • boxing_round_structure_3x3
  • karate_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_zone
    • high_intensity_time_s
    • intensity_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_count
    • work_recovery_ratio
    • interval_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_state
  • recovery_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:

  1. Der neue Fall lässt sich mit den vier Basis-Typen nicht sinnvoll ausdrücken
  2. Eine Abbildung wäre nur durch unsaubere oder missbräuchliche Nutzung möglich
  3. 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_set modelliert werden?
  • Kann es als distribution_set modelliert werden?
  • Kann es als sequence_set modelliert werden?
  • Kann es als model_set modelliert 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 -> GroupSetDTO
  • CompositeRecord -> DistributionSetDTO
  • CompositeRecord -> SequenceSetDTO
  • CompositeRecord -> ModelSetDTO

24.4 Projection Services in Layer 2

Beispiele:

  • BandDistributionProjectionService
  • TransitionProfileService
  • IntervalAnalysisService
  • ReadinessProjectionService
  • CouplingAnalysisService
  • TechniqueProjectionService

24.5 KI-Mapping in Layer 2b

Beispiele:

  • AiPlaceholderBuilder
  • AiFactsBuilder
  • AiNarrativeInputBuilder

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
  • kind und domain indexierbar 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

  1. Unterstützung für datatype = composite
  2. vier kind-Typen:
    • group_set
    • distribution_set
    • sequence_set
    • model_set
  3. Layer-1-Validatoren und Parser
  4. kanonische DTOs pro kind
  5. 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:

  1. ein Composite-Value mit jsonb gespeichert werden kann
  2. Layer 1 den Typ sicher validieren und lesen kann
  3. die Persistenz keine fachlichen Layer-2-Interpretationen erzwingt
  4. HF-Zonen als distribution_set abbildbar sind
  5. Intervallblöcke als sequence_set abbildbar sind
  6. Readiness-Bundles als group_set abbildbar sind
  7. Modellparameter als model_set abbildbar sind
  8. Layer 2a daraus fachliche Projektionen erzeugen kann
  9. Layer 2b daraus KI-Platzhalter erzeugen kann
  10. 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.