- .gitignore: .claude/docs, rules, commands tracken; settings.local weiter ignorieren - DOCUMENTATION.md: verbindliche Ablage functional/technical/working/issues - .claude/README.md: Agent-Einstieg; GITEA_ISSUES_INDEX aus MCP (Stand 2026-04-08) - Arbeitspapiere von docs/ nach .claude/docs/working/ verschoben - docs/MEMBERSHIP_SYSTEM.md als Stub; kanonisch technical/MEMBERSHIP_SYSTEM.md - CLAUDE.md Pflichtlektüre und Links angepasst; docs/README.md vereinfacht Made-with: Cursor
505 lines
14 KiB
Markdown
505 lines
14 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:**
|
|
```
|
|
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**
|