# 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:**
```
placeholder_registrations/
├── __init__.py              # Auto-Import aller Registrations
├── nutrition_part_a.py      # Nutrition Basis-Metriken (4 Placeholder)
├── nutrition_part_b.py      # Protein-Ziele (5 Placeholder) - TODO
├── body_metrics.py          # Körper-Metriken - TODO
├── activity_metrics.py      # Aktivitäts-Metriken - TODO
└── ...                      # Weitere Cluster
```

**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**
