2026-04-11 20:46:17 +02:00
|
|
|
|
"""
|
|
|
|
|
|
Placeholder registration: nutrition_score
|
|
|
|
|
|
|
|
|
|
|
|
Focus-gewichteter Ernährungs-Meta-Score (separates Modul, um nutrition_part_c schlank zu halten).
|
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
|
|
from placeholder_registry import (
|
|
|
|
|
|
PlaceholderMetadata,
|
|
|
|
|
|
MissingValuePolicy,
|
|
|
|
|
|
EvidenceType,
|
|
|
|
|
|
OutputType,
|
|
|
|
|
|
PlaceholderType,
|
|
|
|
|
|
register_placeholder,
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
nutrition_score_metadata = PlaceholderMetadata(
|
|
|
|
|
|
key="nutrition_score",
|
|
|
|
|
|
category="Ernährung",
|
|
|
|
|
|
description="Ernährungs-Score (0–100), gewichtet nach Focus Areas",
|
|
|
|
|
|
resolver_module="backend/placeholder_resolver.py",
|
|
|
|
|
|
resolver_function="_safe_int",
|
|
|
|
|
|
data_layer_module="backend/data_layer/nutrition_metrics.py",
|
|
|
|
|
|
data_layer_function="calculate_nutrition_score",
|
|
|
|
|
|
source_tables=[
|
|
|
|
|
|
"nutrition_log",
|
|
|
|
|
|
"weight_log",
|
|
|
|
|
|
"user_focus_area_weights",
|
|
|
|
|
|
"focus_area_definitions",
|
|
|
|
|
|
],
|
|
|
|
|
|
semantic_contract=(
|
|
|
|
|
|
"Gewichteter Score 0–100 aus Komponenten, die nur einfließen, wenn der Nutzer "
|
|
|
|
|
|
"passende Ernährungs-Focus-Gewichte gesetzt hat (z. B. protein_intake, "
|
|
|
|
|
|
"calorie_balance, macro_consistency). Nutzt u. a. Protein-Adequacy, "
|
|
|
|
|
|
"Makro-Konsistenz, Kalorien-Adhärenz (über Energiebilanz) und Makro-Balance."
|
|
|
|
|
|
),
|
|
|
|
|
|
business_meaning=(
|
|
|
|
|
|
"Verdichteter KPI für Prompts: passt die dokumentierte Ernährung zur "
|
|
|
|
|
|
"gewichteten strategischen Priorität des Nutzers?"
|
|
|
|
|
|
),
|
|
|
|
|
|
unit="score (0-100)",
|
|
|
|
|
|
time_window="composite (7d / 28d je Komponente)",
|
|
|
|
|
|
output_type=OutputType.NUMERIC,
|
|
|
|
|
|
placeholder_type=PlaceholderType.SCORE,
|
|
|
|
|
|
format_hint="Ganzzahl; bei fehlender Ernährungs-Gewichtung oft nicht verfügbar",
|
|
|
|
|
|
example_output="72",
|
|
|
|
|
|
minimum_data_requirements=(
|
|
|
|
|
|
"Mindestens eine Ernährungs-Focus-Komponente mit Gewicht > 0; "
|
|
|
|
|
|
"sowie je nach Komponente ausreichende nutrition_log-/weight_log-Abdeckung."
|
|
|
|
|
|
),
|
|
|
|
|
|
quality_filter_policy=None,
|
|
|
|
|
|
confidence_logic=(
|
|
|
|
|
|
"Kein separates Confidence-Feld im Resolver; fehlende Komponenten werden "
|
|
|
|
|
|
"aus der Gewichtung ausgeschlossen. total_nutrition_weight == 0 ergibt keinen Score."
|
|
|
|
|
|
),
|
|
|
|
|
|
missing_value_policy=MissingValuePolicy(
|
|
|
|
|
|
available=False,
|
|
|
|
|
|
value_raw=None,
|
|
|
|
|
|
missing_reason="not_applicable",
|
|
|
|
|
|
legacy_display="nicht verfügbar",
|
|
|
|
|
|
),
|
|
|
|
|
|
known_limitations=(
|
|
|
|
|
|
"Abhängig von user_focus_area_weights; ohne Ernährungs-Fokus liefert die "
|
2026-04-11 21:11:05 +02:00
|
|
|
|
"Funktion None. Kalorien-Adhärenz nutzt 7d-Energiebilanz vs. profiles.goal_mode "
|
|
|
|
|
|
"(weight_loss / strength+recomposition / sonst maintenance). "
|
|
|
|
|
|
"_score_macro_balance nutzt zeilenbasierte 28d-Abfrage (langfristig an "
|
2026-04-11 20:46:17 +02:00
|
|
|
|
"Tagesaggregation angleichen)."
|
|
|
|
|
|
),
|
|
|
|
|
|
layer_1_decision="Data Layer (nutrition_metrics.calculate_nutrition_score)",
|
|
|
|
|
|
layer_2a_decision="Placeholder Resolver (_safe_int)",
|
|
|
|
|
|
layer_2b_reuse_possible=True,
|
|
|
|
|
|
architecture_alignment="Phase 0c: Berechnung in nutrition_metrics",
|
|
|
|
|
|
issue_53_alignment="Layer 1 als Quelle; Komponenten nutzen weitere Layer-1-Funktionen",
|
|
|
|
|
|
evidence={},
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
nutrition_score_metadata.set_evidence("key", EvidenceType.CODE_DERIVED)
|
|
|
|
|
|
nutrition_score_metadata.set_evidence("category", EvidenceType.CODE_DERIVED)
|
|
|
|
|
|
nutrition_score_metadata.set_evidence("description", EvidenceType.MIXED)
|
|
|
|
|
|
nutrition_score_metadata.set_evidence("resolver_module", EvidenceType.CODE_DERIVED)
|
|
|
|
|
|
nutrition_score_metadata.set_evidence("resolver_function", EvidenceType.CODE_DERIVED)
|
|
|
|
|
|
nutrition_score_metadata.set_evidence("data_layer_module", EvidenceType.CODE_DERIVED)
|
|
|
|
|
|
nutrition_score_metadata.set_evidence("data_layer_function", EvidenceType.CODE_DERIVED)
|
|
|
|
|
|
nutrition_score_metadata.set_evidence("source_tables", EvidenceType.CODE_DERIVED)
|
|
|
|
|
|
nutrition_score_metadata.set_evidence("semantic_contract", EvidenceType.CODE_DERIVED)
|
|
|
|
|
|
nutrition_score_metadata.set_evidence("business_meaning", EvidenceType.DRAFT_DERIVED)
|
|
|
|
|
|
nutrition_score_metadata.set_evidence("unit", EvidenceType.CODE_DERIVED)
|
|
|
|
|
|
nutrition_score_metadata.set_evidence("time_window", EvidenceType.CODE_DERIVED)
|
|
|
|
|
|
nutrition_score_metadata.set_evidence("output_type", EvidenceType.CODE_DERIVED)
|
|
|
|
|
|
nutrition_score_metadata.set_evidence("placeholder_type", EvidenceType.CODE_DERIVED)
|
|
|
|
|
|
nutrition_score_metadata.set_evidence("format_hint", EvidenceType.CODE_DERIVED)
|
|
|
|
|
|
nutrition_score_metadata.set_evidence("example_output", EvidenceType.CODE_DERIVED)
|
|
|
|
|
|
nutrition_score_metadata.set_evidence("minimum_data_requirements", EvidenceType.MIXED)
|
|
|
|
|
|
nutrition_score_metadata.set_evidence("confidence_logic", EvidenceType.CODE_DERIVED)
|
|
|
|
|
|
nutrition_score_metadata.set_evidence("missing_value_policy", EvidenceType.CODE_DERIVED)
|
|
|
|
|
|
nutrition_score_metadata.set_evidence("known_limitations", EvidenceType.MIXED)
|
|
|
|
|
|
nutrition_score_metadata.set_evidence("layer_1_decision", EvidenceType.CODE_DERIVED)
|
|
|
|
|
|
nutrition_score_metadata.set_evidence("layer_2a_decision", EvidenceType.CODE_DERIVED)
|
|
|
|
|
|
nutrition_score_metadata.set_evidence("layer_2b_reuse_possible", EvidenceType.TO_VERIFY)
|
|
|
|
|
|
nutrition_score_metadata.set_evidence("architecture_alignment", EvidenceType.CODE_DERIVED)
|
|
|
|
|
|
nutrition_score_metadata.set_evidence("issue_53_alignment", EvidenceType.MIXED)
|
|
|
|
|
|
|
|
|
|
|
|
register_placeholder(nutrition_score_metadata)
|