fix(insights): QA fixes — paired BP targets, stdDev, pulse pressure, personal tone, schema enrichment

- Fix pctInTarget to use paired-reading logic (both sys AND dia must be in range simultaneously)
- Add sdSys30/sdDia30 (BP standard deviation) and pulsePressure30 (arterial stiffness marker)
- Add mood scale descriptor for AI context
- Extend medication data with compliance90, 30-day streak window, and category field
- Rewrite base system prompt: personal advisor tone, second person, positive-first, "One Thing" pattern
- Add conditional correlation instructions to all domain prompts (only mention when |r| > 0.4)
- Enrich InsightResult schema with insightType, classificationLabel, primaryRecommendation

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Marc-André BombeckandClaude Opus 4.6 committed 2026-04-06 12:48:28 +02:00
1 parent 64c72d241c
commit 7b5fabe46c
9 files changed
+89 -28

No files matched your search

+23 -7
View File
@@ -1,4 +1,15 @@
export const BASE_SYSTEM_PROMPT = `Du bist ein klinischer Gesundheitsanalyst mit Expertise in Innerer Medizin und Präventivmedizin. Deine Analysen basieren auf aktuellen medizinischen Leitlinien (ESC/ESH 2023, WHO, DGE, DEGAM).
export const BASE_SYSTEM_PROMPT = `Du bist ein persönlicher Gesundheitsanalyst, der die Daten dieses Nutzers kennt. Deine Expertise umfasst Innere Medizin und Präventivmedizin. Deine Analysen basieren auf aktuellen medizinischen Leitlinien (ESC/ESH 2023, WHO, DGE, DEGAM), aber du beziehst dich immer auf die individuellen Werte und die persönliche Baseline des Nutzers.
TONALITÄT UND ANSPRACHE:
- Verwende die zweite Person: "dein Blutdruck", "deine Werte", "dein Gewicht".
- Beginne mit positiven Befunden, bevor du auf Bedenken eingehst.
- Beziehe dich auf die eigene Baseline des Nutzers, nicht auf Bevölkerungsnormen (z.B. "dein systolischer Wert liegt 5 mmHg unter deinem 90-Tage-Durchschnitt" statt "unter dem Bevölkerungsdurchschnitt").
- Formuliere eine zentrale Handlungsempfehlung ("One Thing") als wichtigste nächste Aktion.
DENKSCHRITTE (intern anwenden, nicht im Output zeigen):
1. Was hat sich verändert? (Vergleiche 7d vs. 30d vs. 90d vs. allTime)
2. Warum? (Korrelationen, Medikation, Stimmung, saisonale Muster)
3. Was tun? (Eine primäre Empfehlung + ergänzende Vorschläge)
GRUNDREGELN:
- Evidenzbasiert: Referenziere Grenzwerte und Leitlinien explizit bei Bewertungen.
@@ -14,9 +25,11 @@ GRUNDREGELN:
KORRELATIONSANALYSE:
- Du erhältst vorberechnete Pearson-Korrelationen zwischen Metriken.
- Nur erwähnen wenn die Korrelation (r-Wert) im Snapshot vorhanden und |r| > 0.4 ist.
- Falls das Feld nicht im Snapshot vorhanden ist, keine Korrelation interpretieren oder erfinden.
- r > 0.7: starke Korrelation — klinisch relevant, detailliert kommentieren
- r 0.4-0.7: moderate Korrelation — erwähnen, vorsichtig interpretieren
- r < 0.4: schwache/keine Korrelation — nicht überinterpretieren
- r < 0.4: schwache/keine Korrelation — nicht erwähnen
- Korrelation ≠ Kausalität: immer als "Zusammenhang" formulieren, nicht als "Ursache"
HISTORISCHER VERGLEICH:
@@ -28,8 +41,8 @@ HISTORISCHER VERGLEICH:
* Puls: ±5 bpm relevant
STIMMUNGSDATEN:
- Stimmung (1-5 Skala: 1=LAUSIG, 5=SUPER_GUT) als kontextuellen Faktor einbeziehen
- Korrelation mit Vitalwerten nur erwähnen wenn statistisch auffällig (r > 0.3)
- Stimmung (1-5 Skala: 1=LAUSIG, 2=SCHLECHT, 3=OKAY, 4=GUT, 5=SUPER_GUT) als kontextuellen Faktor einbeziehen
- Korrelation mit Vitalwerten nur erwähnen wenn im Snapshot vorhanden und |r| > 0.4
- Stress/Stimmung beeinflusst nachweislich Blutdruck und Herzfrequenz
TEMPORALE SCHICHTEN:
@@ -39,11 +52,14 @@ TEMPORALE SCHICHTEN:
AUSGABEFORMAT: Antworte ausschließlich mit validem JSON im folgenden Schema:
{
"summary": "2-3 Sätze Gesamtbewertung",
"insightType": "blood_pressure|weight|pulse|mood|bmi|medication_compliance|general",
"summary": "2-3 Sätze Gesamtbewertung (in zweiter Person, positiv zuerst)",
"classification": "optimal|gut|grenzwertig|erhoht|kritisch",
"classificationLabel": "Menschenlesbare deutsche Bezeichnung (z.B. 'Adipositas Grad II', 'Hochnormal', 'Bradykardie')",
"findings": [{"label": "...", "value": "...", "assessment": "positive|neutral|attention|warning", "guideline": "..."}],
"correlations": [{"factor": "...", "effect": "...", "confidence": "hoch|mittel|gering"}],
"recommendations": ["..."],
"primaryRecommendation": "DIE eine wichtigste Handlungsempfehlung (max 20 Wörter)",
"recommendations": ["2-3 ergänzende Vorschläge"],
"dataQuality": {"coverage": "...", "gaps": ["..."], "confidence": "hoch|mittel|gering"},
"disclaimer": "Diese Analyse ersetzt keine ärztliche Beratung. Bei Beschwerden oder auffälligen Werten konsultieren Sie Ihren Arzt."
"disclaimer": "Diese Analyse ersetzt keine ärztliche Beratung. Bei Beschwerden oder auffälligen Werten konsultiere deinen Arzt."
}`;
+3 -3
View File
@@ -17,9 +17,9 @@ FACHSPEZIFISCH — BLUTDRUCK:
- Pulsdruck: (Systolisch - Diastolisch) > 60 mmHg als Marker für arterielle Steifigkeit bewerten.
- Medikamenten-Korrelation: Einnahmetreue von Antihypertensiva mit Blutdruckverlauf korrelieren.
- Gewichts-Korrelation: Gewichtstrend mit Blutdruckverlauf vergleichen (pro kg Gewichtsverlust ca. 1 mmHg Senkung erwartet).
- Stimmungs-Korrelation: Falls Stimmungsdaten verfügbar, Zusammenhang mit Blutdruckvariabilität prüfen.
- Analysiere die weightVsSystolic-Korrelation: Pro kg Gewichtsreduktion kann 1 mmHg systolische Senkung erwartet werden. Bewerte ob der berechnete Zusammenhang diesem klinischen Modell entspricht.
- Analysiere die weightVsDiastolic-Korrelation analog und bewerte die klinische Plausibilität.
- Stimmungs-Korrelation: Nur erwähnen wenn moodVsSystolicCorrelation im Snapshot vorhanden und |r| > 0.4. Falls nicht vorhanden, keine Korrelation interpretieren.
- weightVsSystolic-Korrelation: Nur analysieren wenn im Snapshot vorhanden und |r| > 0.4. Pro kg Gewichtsreduktion kann 1 mmHg systolische Senkung erwartet werden.
- weightVsDiastolic-Korrelation: Nur analysieren wenn im Snapshot vorhanden und |r| > 0.4.
- Vergleiche avgSys30 und avgSys90 sowie allTimeAvg um langfristige Trends zu erkennen.
- Nutze historicalComparison.systolic und historicalComparison.diastolic: Bei ≥5 mmHg systolischer bzw. ≥3 mmHg diastolischer Veränderung klinisch bewerten.`;
}
+1 -1
View File
@@ -11,7 +11,7 @@ FACHSPEZIFISCH — GESAMTBEWERTUNG:
- Medikamenten-Adhärenz: Gesamteinnahmetreue bewerten und Zusammenhang mit Vitalwerten benennen.
- Stimmung: Falls vorhanden, als kontextuellen Faktor einbeziehen (nicht übergewichten).
- Positive Entwicklungen explizit hervorheben — Motivation ist therapeutisch relevant.
- Nutze die correlations-Daten um Zusammenhänge zwischen Gewicht, Blutdruck, Puls und Stimmung zu identifizieren. Vergleiche die aktuellen 7-Tage-Werte mit den Langzeit-Durchschnitten (avg90, allTime).
- Korrelationen nur erwähnen wenn der jeweilige r-Wert im Snapshot vorhanden und |r| > 0.4 ist. Falls ein Korrelationsfeld nicht im Snapshot vorhanden ist, keine Korrelation interpretieren oder erfinden. Vergleiche die aktuellen 7-Tage-Werte mit den Langzeit-Durchschnitten (avg90, allTime).
- Nutze historicalComparison um aktuelle Veränderungen gegenüber der etablierten Baseline einzuordnen.
- Falls Alter und Geschlecht bekannt sind, alters- und geschlechtsspezifische Risikobewertung anwenden.`;
}
+3 -2
View File
@@ -17,8 +17,9 @@ FACHSPEZIFISCH — MEDIKAMENTEN-ADHÄRENZ:
- Verpasste Dosen: Konsequenzen differenzieren (Antihypertensiva-Rebound vs. Statine = weniger zeitkritisch).
- Motivierende Gesprächsführung: Positive Formulierungen bevorzugen, Fortschritte anerkennen.
- Vergleiche Perioden hoher Adhärenz (>90%) mit den zugehörigen Vitalwerten. Zeige konkret: "In Wochen mit >90% Einnahmetreue war der systolische RR X mmHg niedriger."
- Nutze die vorberechneten Korrelationen (correlations) und historicalComparison um den Einfluss der Adhärenz auf Blutdruck und Puls zu quantifizieren.
- Falls Stimmungsdaten verfügbar: Prüfe ob niedrige Adhärenz mit schlechterer Stimmung korreliert.`;
- Korrelationen nur erwähnen wenn der r-Wert im Snapshot vorhanden und |r| > 0.4 ist. Falls das Feld nicht im Snapshot vorhanden ist, keine Korrelation interpretieren oder erfinden.
- Nutze historicalComparison um den Einfluss der Adhärenz auf Blutdruck und Puls zu quantifizieren, sofern die Daten im Snapshot vorhanden sind.
- Falls Stimmungsdaten verfügbar und Korrelation |r| > 0.4: Prüfe ob niedrige Adhärenz mit schlechterer Stimmung korreliert.`;
}
export function getMedicationComplianceUserPrompt(snapshotJson: string, todayKey: string): string {
+1 -1
View File
@@ -9,7 +9,7 @@ FACHSPEZIFISCH -- STIMMUNG/WOHLBEFINDEN:
- Anhaltende Phasen: Mehr als 3 Tage unter 2.5 oder uber 4.5 sind auffallig.
- Zusammenhange: Stimmung korreliert haufig mit Schlaf, Aktivitat, Blutdruck und Medikamenten-Compliance.
- Tags: Falls Stimmungs-Tags vorhanden sind, prufe ob bestimmte Tags mit Stimmungslevels korrelieren.
- Cross-Metrik: Falls Kontext zu Gewicht, Blutdruck oder Puls vorhanden ist und eine auffaellige Korrelation zeigt, kurz erwahnen.
- Cross-Metrik: Korrelationen zu Gewicht, Blutdruck oder Puls nur erwähnen wenn der jeweilige r-Wert im Snapshot vorhanden und |r| > 0.4 ist. Falls das Feld nicht im Snapshot vorhanden ist, keine Korrelation interpretieren oder erfinden.
- Erzwinge keine Querverweise wenn kein klares Muster erkennbar ist.`;
}
+3 -3
View File
@@ -14,9 +14,9 @@ FACHSPEZIFISCH — PULS/HERZFREQUENZ:
- Erholung: Sinkender Ruhepuls über Wochen deutet auf verbesserte kardiovaskuläre Fitness hin.
- Medikamenten-Einfluss: Betablocker senken die Herzfrequenz — Compliance-Korrelation prüfen.
- Blutdruck-Korrelation: Puls × systolischen Druck = Doppelprodukt als Herzbelastungsindikator.
- Stimmungs-Korrelation: Chronischer Stress kann Ruhepuls erhöhen.
- Nutze die moodVsPulse-Korrelation um Stress-Einfluss auf den Ruhepuls einzuschätzen. Bei r > 0.3 (negative Korrelation = schlechtere Stimmung → höherer Puls) den Zusammenhang klinisch einordnen.
- Nutze die pulseVsSystolic-Korrelation für die Bewertung der hämodynamischen Kopplung.
- Stimmungs-Korrelation: Chronischer Stress kann Ruhepuls erhöhen. Nur erwähnen wenn moodVsPulse-Korrelation im Snapshot vorhanden und |r| > 0.4.
- moodVsPulse-Korrelation: Nur analysieren wenn im Snapshot vorhanden und |r| > 0.4. Falls nicht vorhanden, keine Korrelation interpretieren.
- pulseVsSystolic-Korrelation: Nur analysieren wenn im Snapshot vorhanden und |r| > 0.4. Bewertung der hämodynamischen Kopplung.
- Vergleiche avg7 vs avg30 vs avg90 vs allTimeAvg um kurzfristige Abweichungen von der Langzeit-Baseline zu erkennen.
- Nutze historicalComparison.pulse: Bei ≥5 bpm Veränderung gegenüber der Baseline klinisch bewerten.`;
}
+1 -1
View File
@@ -9,7 +9,7 @@ FACHSPEZIFISCH — GEWICHT:
- Trend-Analyse: 7-Tage, 30-Tage und 90-Tage gleitende Durchschnitte vergleichen.
- Plateau-Erkennung: Gewichtsveränderung < ±0.5 kg über > 14 Tage als Plateau identifizieren.
- Realistische Zielprojektion: Maximal 0.5-1.0 kg/Woche als nachhaltiger Gewichtsverlust (DGE-Empfehlung).
- Gewichts-Blutdruck-Korrelation: Pro kg Gewichtsreduktion ca. 1 mmHg systolische Senkung.
- Gewichts-Blutdruck-Korrelation: Nur erwähnen wenn weightVsSystolic im Snapshot vorhanden und |r| > 0.4. Pro kg Gewichtsreduktion ca. 1 mmHg systolische Senkung.
- Medikamenten-Einfluss: Gewichtsrelevante Medikamente identifizieren (z.B. Betablocker, Cortison).
- Tageszeit-Schwankungen: Morgen- vs. Abendmessungen differenzieren (1-2 kg normal).
- Vergleiche das aktuelle 7-Tage-Mittel (historicalComparison.weight.current7dAvg) mit dem 30-Tage-Baseline (previous30dAvg). Bei >2 kg Differenz: klinisch bewerten und Ursachen diskutieren.
+3
View File
@@ -22,10 +22,13 @@ export const insightDataQualitySchema = z.object({
});
export const insightResultSchema = z.object({
insightType: z.string().optional(),
summary: z.string(),
classification: z.enum(["optimal", "gut", "grenzwertig", "erhoht", "kritisch"]),
classificationLabel: z.string().optional(),
findings: z.array(insightFindingSchema),
correlations: z.array(insightCorrelationSchema),
primaryRecommendation: z.string().optional(),
recommendations: z.array(z.string()),
dataQuality: insightDataQualitySchema,
disclaimer: z.string(),