mitai-jinkendo/.claude/docs/technical/PLACEHOLDER_REGISTRY_FRAMEWORK.md
Lars 052ba195cc
All checks were successful
Deploy Development / deploy (push) Successful in 54s
Build Test / pytest-backend (push) Successful in 4s
Build Test / lint-backend (push) Successful in 1s
Build Test / build-frontend (push) Successful in 15s
feat: Update placeholder metadata and nutrition metrics
- Adjusted the total number of placeholders from 116 to 114 across various documentation and code files to reflect the current state of the system.
- Enhanced TDEE calculation logic in `nutrition_metrics.py` to prioritize Mifflin–St Jeor BMR with PAL when demographic data is available, with a fallback to a weight-based estimate.
- Updated placeholder registrations to ensure consistency with the new metadata structure and improved data handling.
- Revised documentation to clarify the authoritative source of placeholder metadata and the implications of the changes on existing functionalities.

These updates improve the accuracy and consistency of the placeholder system and enhance the nutritional assessment capabilities within the application.
2026-04-11 21:11:05 +02:00

499 lines
13 KiB
Markdown

# Placeholder Registry Framework - Verbindliche Dokumentation
**Status:** VERBINDLICH (ab 2026-04-02)
**Version:** 1.0
**Geltungsbereich:** Alle Placeholder/Metrics im System
---
## 1. Zweck
Das **Placeholder Registry Framework** ist die zentrale, verbindliche Metadaten-Verwaltung für alle Placeholder und Metrics im System.
**Kernprinzip:** Single Source of Truth
**Ziele:**
1. Einheitliche Metadaten-Struktur für alle Placeholder
2. Vermeidung von Duplikation und Inkonsistenzen
3. Zentrale Verwaltung für alle Konsumenten
4. Evidence-basierte Transparenz
5. Erweiterbarkeit und Wartbarkeit
---
## 2. Verbindlichkeit
### 2.1 Pflicht zur Nutzung
**ALLE neuen Placeholder/Metrics MÜSSEN über das Registry Framework registriert werden.**
Keine Ausnahmen ohne explizite technische Begründung und Freigabe.
### 2.2 Betroffene Systeme
Folgende Systeme MÜSSEN die Registry als Single Source of Truth nutzen:
1. **Backend Prompt-Injektion** (Layer 2a)
- Placeholder-Resolver
- Prompt-Template-Engine
2. **GUI Auswahllisten**
- Placeholder-Picker
- Kategorie-Filter
- Metadata-Anzeige
3. **Extended Export**
- `/api/prompts/placeholders/export-values-extended`
- Catalog-Generierung
- ZIP-Export
4. **Validierung** (zukünftig)
- Metadata-Completeness-Checks
- Evidence-Quality-Assurance
- Compliance-Reports
5. **Diagramm-Zuordnung** (zukünftig)
- Chart-Metadata-Mapping
- Layer-2b-Integration
### 2.3 Verbotene Praktiken
**VERBOTEN:**
- Hardcoded Metadaten außerhalb der Registry
- Duplizierte Metadaten-Definitionen
- Placeholder ohne Registry-Registrierung
- Direkte Manipulation von Metadaten im Export-Code
- Inkonsistente Metadaten zwischen Systemen
---
## 3. Framework-Architektur
### 3.1 Kernkomponenten
**Modul:** `backend/placeholder_registry.py`
**Klassen:**
- `PlaceholderMetadata` - Metadata-Dataclass (22 Pflichtfelder)
- `MissingValuePolicy` - Strukturierte Missing-Value-Behandlung
- `PlaceholderRegistry` - Zentrale Registry (Singleton)
- `EvidenceType` - Enum für Evidenz-Tagging
- `OutputType` - Enum für Output-Typen
- `PlaceholderType` - Enum für Placeholder-Typen
**Singleton-Instanz:**
```python
from placeholder_registry import get_registry
registry = get_registry()
```
### 3.2 Registrierungs-Package
**Package:** `backend/placeholder_registrations/`
**Struktur:** Vollständige Cluster-Module (u. a. Ernährung, Körper, Aktivität, Schlaf,
Vitalwerte, Profil/Zeitraum, Phase-0b-Ziele, Korrelationen); siehe `__init__.py` für die
Import-Liste. **Anzahl:** 114 Platzhalter, identisch zu `PLACEHOLDER_MAP` in
`placeholder_resolver.py`.
**Auto-Registration:**
- Import des Package triggert automatische Registrierung aller Placeholder
- Keine manuelle Registrierung erforderlich
### 3.3 Export-Integration
**Modul:** `backend/placeholder_registry_export.py`
**Funktionen:**
- `get_registry_metadata_for_export()` - Metadata aus Registry
- `merge_registry_with_legacy_export()` - Backward-Compatibility
- `get_enhanced_export_with_registry()` - Vollständiger Export
**Endpoint-Integration:**
```python
# backend/routers/prompts.py
import placeholder_registrations # Auto-registers
from placeholder_registry_export import get_registry_metadata_for_export
registry_data = get_registry_metadata_for_export(profile_id)
export_data['registry_metadata'] = registry_data
```
---
## 4. Metadata-Schema
### 4.1 Pflichtfelder (22 Felder)
**Core Identification (3):**
- `key` - Placeholder-Schlüssel (z.B. "kcal_avg")
- `category` - Kategorie (z.B. "Ernährung")
- `description` - Kurzbeschreibung
**Technical (6):**
- `resolver_module` - Modul-Pfad des Resolvers
- `resolver_function` - Funktionsname des Resolvers
- `data_layer_module` - Data Layer Modul (optional)
- `data_layer_function` - Data Layer Funktion (optional)
- `source_tables` - Liste der Quelltabellen
- `_resolver_func` - Runtime-Resolver (nicht exportiert)
**Semantic (8):**
- `semantic_contract` - Semantische Definition
- `business_meaning` - Fachliche Bedeutung
- `unit` - Einheit (z.B. "kcal/day")
- `time_window` - Zeitfenster (z.B. "30d")
- `output_type` - Output-Typ (Enum)
- `placeholder_type` - Placeholder-Typ (Enum)
- `format_hint` - Format-Information
- `example_output` - Beispiel-Ausgabe
**Quality (5):**
- `minimum_data_requirements` - Mindestanforderungen (optional)
- `quality_filter_policy` - Qualitätsfilter (optional)
- `confidence_logic` - Confidence-Berechnung (optional)
- `missing_value_policy` - Missing-Value-Handling
- `known_limitations` - Bekannte Einschränkungen (optional)
**Architecture (5):**
- `layer_1_decision` - Layer-1-Zuordnung (optional)
- `layer_2a_decision` - Layer-2a-Zuordnung (optional)
- `layer_2b_reuse_possible` - Chart-Reuse möglich (optional)
- `architecture_alignment` - Architektur-Konformität (optional)
- `issue_53_alignment` - Issue #53 Konformität (optional)
**Evidence Tracking (1):**
- `evidence` - Dict mapping Feldname → EvidenceType
### 4.2 Evidence-Typen
**Enum:** `EvidenceType`
**Werte:**
- `CODE_DERIVED` - Aus Code belegt (z.B. aus Import-Statement, SQL-Query)
- `DRAFT_DERIVED` - Aus Canonical Requirements Draft übernommen
- `MIXED` - Teilweise Code, teilweise Draft/abgeleitet
- `UNRESOLVED` - Nicht explizit dokumentiert, offen
- `TO_VERIFY` - Behauptung, muss noch verifiziert werden
**Verwendung:**
```python
metadata.set_evidence("unit", EvidenceType.CODE_DERIVED)
metadata.set_evidence("semantic_contract", EvidenceType.DRAFT_DERIVED)
metadata.set_evidence("layer_2b_reuse_possible", EvidenceType.TO_VERIFY)
```
---
## 5. Registrierungs-Workflow
### 5.1 Neuen Placeholder registrieren
**Schritt 1: Metadata-Objekt erstellen**
```python
# backend/placeholder_registrations/my_cluster.py
from placeholder_registry import (
PlaceholderMetadata,
MissingValuePolicy,
EvidenceType,
OutputType,
PlaceholderType,
register_placeholder
)
metadata = PlaceholderMetadata(
key="my_placeholder",
category="Meine Kategorie",
description="Kurzbeschreibung",
# Technical (CODE_DERIVED)
resolver_module="backend/placeholder_resolver.py",
resolver_function="get_my_placeholder",
data_layer_module="backend/data_layer/my_metrics.py",
data_layer_function="get_my_data",
source_tables=["my_table"],
# Semantic
semantic_contract="Was liefert dieser Placeholder?",
business_meaning="Fachliche Bedeutung",
unit="einheit",
time_window="30d",
output_type=OutputType.NUMERIC,
placeholder_type=PlaceholderType.INTERPRETED,
format_hint="Ganzzahl",
example_output="42",
# Quality
confidence_logic="Wie wird Verlässlichkeit berechnet?",
missing_value_policy=MissingValuePolicy(
available=False,
value_raw=None,
missing_reason="insufficient_data",
legacy_display="nicht genug Daten"
),
known_limitations="Einschränkungen dokumentieren",
# Architecture
layer_1_decision="Data Layer (my_metrics.get_my_data)",
layer_2a_decision="Placeholder Resolver (formatting only)",
architecture_alignment="Phase 0c conform"
)
```
**Schritt 2: Evidence setzen**
```python
# Code-derived Felder
metadata.set_evidence("resolver_module", EvidenceType.CODE_DERIVED)
metadata.set_evidence("resolver_function", EvidenceType.CODE_DERIVED)
metadata.set_evidence("data_layer_module", EvidenceType.CODE_DERIVED)
metadata.set_evidence("source_tables", EvidenceType.CODE_DERIVED)
metadata.set_evidence("unit", EvidenceType.CODE_DERIVED)
metadata.set_evidence("time_window", EvidenceType.CODE_DERIVED)
# Draft-derived Felder
metadata.set_evidence("semantic_contract", EvidenceType.DRAFT_DERIVED)
metadata.set_evidence("business_meaning", EvidenceType.DRAFT_DERIVED)
metadata.set_evidence("known_limitations", EvidenceType.DRAFT_DERIVED)
# Unresolved Felder
metadata.set_evidence("minimum_data_requirements", EvidenceType.UNRESOLVED)
```
**Schritt 3: Registrieren**
```python
register_placeholder(metadata)
```
**Schritt 4: Auto-Import sicherstellen**
```python
# backend/placeholder_registrations/__init__.py
from . import my_cluster
__all__ = ['nutrition_part_a', 'my_cluster']
```
### 5.2 Resolver-Funktion bereitstellen (optional)
Wenn der Placeholder runtime-resolved werden soll:
```python
from placeholder_resolver import get_my_placeholder
register_placeholder(
metadata,
resolver_func=lambda pid: get_my_placeholder(pid)
)
```
---
## 6. API-Nutzung
### 6.1 Metadata abrufen
```python
from placeholder_registry import get_registry
registry = get_registry()
# Einzelner Placeholder
meta = registry.get("kcal_avg")
print(meta.unit) # "kcal/day"
print(meta.time_window) # "30d"
# Alle Placeholder
all_metadata = registry.get_all() # Dict[str, PlaceholderMetadata]
# Nach Kategorie
ernaehrung = registry.get_by_category("Ernährung") # List[PlaceholderMetadata]
```
### 6.2 Export
```python
# Für Extended Export
export_data = registry.get_all_for_export() # List[Dict]
# Mit Runtime-Werten
from placeholder_registry_export import get_registry_metadata_for_export
registry_data = get_registry_metadata_for_export(profile_id)
# Returns: {flat, by_category, evidence_report, validation_report}
```
### 6.3 Validierung
```python
# Alle Placeholder validieren
issues = registry.validate_all() # Dict[str, List[str]]
if issues:
for key, problems in issues.items():
print(f"{key}: {problems}")
```
### 6.4 QA / Evidence-Tracking
```python
# Placeholder mit unresolved Fields finden
unresolved = registry.get_by_evidence_type(EvidenceType.UNRESOLVED)
# Returns: Dict[placeholder_key, List[field_names]]
# Placeholder die verifiziert werden müssen
to_verify = registry.get_by_evidence_type(EvidenceType.TO_VERIFY)
```
---
## 7. Best Practices
### 7.1 Evidence-Tagging
**DO:**
- Jedes Feld mit Evidence-Tag versehen
- `CODE_DERIVED` nur wenn direkt aus Code ableitbar
- `TO_VERIFY` für Behauptungen, die noch geprüft werden müssen
- `UNRESOLVED` für fehlende/unklare Informationen
**DON'T:**
- Felder ohne Evidence lassen
- Evidence halluzinieren (wenn nicht belegt, `UNRESOLVED` nutzen)
- `CODE_DERIVED` für Draft-Informationen nutzen
### 7.2 Metadata-Vollständigkeit
**Minimum Required:**
- `key`, `category`, `description`
- `resolver_module`, `resolver_function`
- `semantic_contract`
- `unit`, `time_window`
- `output_type`, `placeholder_type`
**Optional but Recommended:**
- `data_layer_module`, `data_layer_function`
- `source_tables`
- `confidence_logic`, `missing_value_policy`
- `layer_1_decision`, `layer_2a_decision`
### 7.3 Modularisierung
**Registrations nach Cluster gruppieren:**
- `nutrition_part_a.py` - Nutrition Basis (4 Placeholder)
- `nutrition_part_b.py` - Nutrition Protein (5 Placeholder)
- `body_metrics.py` - Körper-Metriken (N Placeholder)
**Nicht:**
- Alle Placeholder in eine riesige Datei
- Placeholder ohne thematische Gruppierung
### 7.4 Backward-Compatibility
**Export-Endpoint MUSS:**
- Legacy-Export beibehalten (`export_data['legacy']`)
- Graceful degradation bei Registry-Fehler
- Registry-Metadata als separate Sektion (`export_data['registry_metadata']`)
---
## 8. Migration bestehender Placeholder
### 8.1 Priorität
**Part A (erledigt):** Nutrition Basis (kcal_avg, protein_avg, carb_avg, fat_avg)
**Nächste Priorität:**
1. Part B - Nutrition Protein (5 Placeholder)
2. Part C - Nutrition Balance (4 Placeholder)
3. Part D - Nutrition Meta (1 Placeholder)
4. Body Metrics (ca. 15 Placeholder)
5. Activity Metrics (ca. 20 Placeholder)
### 8.2 Migration-Workflow
**Für jeden Placeholder:**
1. Code inspizieren (Resolver, Data Layer, SQL)
2. Evidence ableiten (was ist code-derived, was draft-derived?)
3. Metadata-Objekt erstellen
4. Registrieren
5. Export testen
6. Werte-Identität bestätigen
**Keine Logikänderung während Migration!**
---
## 9. Compliance & Enforcement
### 9.1 Code-Review-Checkliste
**Für neue Placeholder:**
- [ ] Registry-Registrierung vorhanden?
- [ ] Evidence-Tags gesetzt?
- [ ] Metadata-Vollständigkeit (minimum required)?
- [ ] Auto-Import in `__init__.py`?
- [ ] Export getestet?
### 9.2 CI/CD-Integration (zukünftig)
**Geplante Checks:**
- Alle Placeholder in PLACEHOLDER_MAP sind in Registry registriert
- Keine Placeholder ohne Evidence-Tags
- Keine doppelten Registrierungen
- Metadata-Vollständigkeit für production-ready Placeholder
---
## 10. Support & Weiterentwicklung
### 10.1 Fragen & Issues
**Bei Unklarheiten:**
1. Diese Dokumentation prüfen
2. Bestehende Registrations als Vorlage nutzen (`nutrition_part_a.py`)
3. Code-Review anfragen
### 10.2 Framework-Erweiterungen
**Geplante Features:**
- GUI-Integration (Placeholder-Picker mit Registry-Metadata)
- Validation-Dashboard (QA-Monitoring)
- Evidence-Report-Endpoint (Metadata-Qualität)
- Resolver-Test-Framework (Automatisierte Werteänderungs-Detektion)
- Chart-Metadata-Mapping (Layer-2b-Integration)
### 10.3 Versions-History
**v1.0 (2026-04-02):**
- Initial Release
- Part A Implementation (4 Nutrition Placeholders)
- Core Framework + Export-Integration
---
## 11. Referenzen
**Code:**
- `backend/placeholder_registry.py` - Core Framework
- `backend/placeholder_registrations/nutrition_part_a.py` - Part A Implementation
- `backend/placeholder_registry_export.py` - Export-Integration
- `backend/routers/prompts.py` - Export-Endpoint
**Dokumentation:**
- `.claude/task/rework_0b_placeholder/NUTRITION_PART_A_CHANGE_PLAN.md`
- `.claude/task/rework_0b_placeholder/NUTRITION_PART_A_IMPLEMENTATION_REPORT.md`
**Beispiel-Export:**
```bash
curl "https://dev.mitai.jinkendo.de/api/prompts/placeholders/export-values-extended?token=XXX"
```
---
**Ende Verbindliche Dokumentation**