- Added details for Issue #53 regarding the audit of activity placeholders between Layer 1 and Layer 2a in `CLAUDE.md` and `README.md`. - Updated the `ACTIVITY_SESSION_METRICS_EAV_AGENT_GUIDE.md` to reflect the new registry checks and dynamic session metrics handling. - Revised the `placeholder_resolver.py` and `activity_metrics.py` to clarify the registration of activity metrics and session insights, ensuring consistency in the handling of dynamic keys and metrics. - Improved descriptions and semantic contracts in `activity_session_insights.py` to better outline the structure and limitations of session data.
71 lines
4.7 KiB
Markdown
71 lines
4.7 KiB
Markdown
# Aktivität: Layer-2a-Platzhalter — Audit Schritt 1 (Issue #53)
|
||
|
||
**Stand:** 2026-04-16
|
||
**Bezug:** [Issue #53 — Multi-Layer Architecture](../../../docs/issues/issue-53-phase-0c-multi-layer-architecture.md): Layer 1 = strukturierte Daten, Layer 2a = KI-Formatierung (keine parallele Domänen-Logik im Resolver).
|
||
|
||
**Ziel dieses Dokuments:** Jeder Aktivitäts-Platzhalter hat genau eine **Layer‑1‑Quelle** (`data_layer/activity_metrics.py`); `placeholder_resolver.py` formatiert oder serialisiert nur noch.
|
||
|
||
---
|
||
|
||
## 1. Ergebnisübersicht
|
||
|
||
| Kategorie | Anzahl | Resolver-SQL für Aktivität? |
|
||
|-----------|--------|------------------------------|
|
||
| Gebündelt in `PLACEHOLDER_MAP` (Training/Aktivität) | 20 | **Nein** |
|
||
| Abweichungen / offene Punkte | 0 | — |
|
||
|
||
**Hinweis:** `{{rest_days_count}}` steht in der Karte unter „Schlaf & Erholung“ und nutzt `recovery_metrics.get_rest_days_data` — nicht in dieser Tabelle.
|
||
|
||
---
|
||
|
||
## 2. Platzhalter → Layer 1 → Layer 2a
|
||
|
||
| Key | Layer 1 (`activity_metrics`) | Layer 2a (`placeholder_resolver`) | Bemerkung |
|
||
|-----|------------------------------|-------------------------------------|-----------|
|
||
| `activity_summary` | `get_activity_summary_data` | `get_activity_summary` | String-Zusammenfassung |
|
||
| `activity_detail` | `get_activity_detail_data` (+ `enrich_sessions_with_metrics`) | `get_activity_detail` | Dynamische `session_metrics[]` pro Zeile (Profil/EAV) |
|
||
| `trainingstyp_verteilung` | `get_training_type_distribution_data` | `get_trainingstyp_verteilung` | Ausgabe: Top-3-Text (kein JSON); Registry 2026-04 an Ist angeglichen |
|
||
| `training_minutes_week` | `calculate_training_minutes_week` | `_safe_int` | |
|
||
| `training_frequency_7d` | `calculate_training_frequency_7d` | `_safe_int` | |
|
||
| `quality_sessions_pct` | `calculate_quality_sessions_pct` | `_safe_int` | |
|
||
| `proxy_internal_load_7d` | `calculate_proxy_internal_load_7d` | `_safe_int` | |
|
||
| `monotony_score` | `calculate_monotony_score` | `_safe_float` | |
|
||
| `strain_score` | `calculate_strain_score` | `_safe_int` | |
|
||
| `rest_day_compliance` | `calculate_rest_day_compliance` | `_safe_int` | |
|
||
| `ability_balance_strength` | `calculate_ability_balance_strength` | `_safe_int` | abilities in `activity_log` |
|
||
| `ability_balance_endurance` | `calculate_ability_balance_endurance` | `_safe_int` | |
|
||
| `ability_balance_mental` | `calculate_ability_balance_mental` | `_safe_int` | |
|
||
| `ability_balance_coordination` | `calculate_ability_balance_coordination` | `_safe_int` | |
|
||
| `ability_balance_mobility` | `calculate_ability_balance_mobility` | `_safe_int` | |
|
||
| `vo2max_trend_28d` | `calculate_vo2max_trend_28d` | `_safe_float` | |
|
||
| `activity_score` | `calculate_activity_score` | `_safe_int` | |
|
||
| `training_frequency_by_type_md` | `get_training_frequency_by_type_data` | `get_training_frequency_by_type_md` | Markdown-Tabelle |
|
||
| `training_inter_session_gap_md` | `get_training_inter_session_gap_data` | `get_training_inter_session_gap_md` | Markdown-Text |
|
||
| `training_sessions_recent_json` | `get_training_sessions_recent_weeks_data` (+ `enrich_sessions_with_metrics`) | `_safe_json('training_sessions_recent_json')` | JSON inkl. `session_metrics[]` pro Session |
|
||
|
||
---
|
||
|
||
## 3. Schichten-Disziplin (Checkliste)
|
||
|
||
- [x] Kein `SELECT` auf `activity_log` / `activity_session_metrics` in den **Layer‑2a**-Funktionen oben — nur Aufrufe in Layer 1 bzw. `_safe_*`-Wrapper.
|
||
- [x] `get_activity_detail` / `get_training_sessions_recent_json` liefern EAV nur über **bereits gemergte** `session_metrics` (Merge-Kanon: `activity_log` vor EAV).
|
||
- [x] Registry-Metadaten: `data_layer_module` / `data_layer_function` pro Key in `placeholder_registrations/activity_metrics.py` und `activity_session_insights.py`.
|
||
- [x] Korrektur Registry: `activity_summary.resolver_function` = `get_activity_summary` (war veraltet: `_format_activity_summary`).
|
||
|
||
---
|
||
|
||
## 4. Nächste Schritte (Roadmap)
|
||
|
||
2. ~~**Registry-Texte:** `semantic_contract` / `known_limitations` für dynamische `session_metrics` (tcp/ttp) und Merge-Kanon — **erledigt** (`activity_detail`, `training_sessions_recent_json`); dazu **`trainingstyp_verteilung`**-Metadaten von veraltetem „JSON/Resolver-SQL“ auf Ist (**Layer 1 + Top-3-Text**) korrigiert.~~
|
||
3. **History / Layer 2b:** EAV-Zeitreihen nicht über Platzhalter, sondern dedizierte Layer‑1-/Chart-Pfade.
|
||
4. **Optional:** Gitea-Issue „Activity Layer 2a“ bei Änderungen an `activity_metrics` pflegen.
|
||
|
||
---
|
||
|
||
## 5. Referenzen
|
||
|
||
- `backend/placeholder_resolver.py` — `PLACEHOLDER_MAP` (Training/Aktivität)
|
||
- `backend/placeholder_registrations/activity_metrics.py`
|
||
- `backend/placeholder_registrations/activity_session_insights.py`
|
||
- `ACTIVITY_PRODUCTION_ARCHITECTURE_AND_PHASES.md` §2.1a (Navigation Read vs. Berechnen)
|