# Feature: Prompt-Zuordnung zu Verlaufsseiten **Labels:** feature, ux, enhancement **Priority:** Medium (Phase 1-2) **Related:** Issue #28 (Unified Prompt System - Complete) ## Beschreibung KI-Prompts sollen flexibel auf verschiedenen Verlaufsseiten verfΓΌgbar gemacht werden kΓΆnnen. Jeder Prompt kann auf mehreren Seiten gleichzeitig angeboten werden (Mehrfachauswahl). ## Problem (aktueller Stand) **Aktuell:** - Prompts sind nur ΓΌber die zentrale Analyse-Seite (πŸ“Š Analyse) verfΓΌgbar - Kein kontextbezogener Zugriff auf relevante Analysen - User muss immer zur Analyse-Seite navigieren **Beispiel-Szenario:** ``` User ist auf: Gewicht β†’ Verlauf Will: Gewichtstrend analysieren Muss: Zur Analyse-Seite β†’ Prompt auswΓ€hlen β†’ ZurΓΌck ``` **WΓΌnschenswert:** ``` User ist auf: Gewicht β†’ Verlauf Sieht: "πŸ€– KI-Analyse" Button mit relevanten Prompts Kann: Direkt "Gewichtstrend-Analyse" starten ``` ## GewΓΌnschtes Verhalten ### 1. Prompt-Konfiguration erweitern **Admin β†’ KI-Prompts β†’ Prompt bearbeiten:** ``` β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ Prompt bearbeiten: Gewichtstrend-Analyse β”‚ β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ β”‚ Name: Gewichtstrend-Analyse β”‚ β”‚ Slug: weight_trend β”‚ β”‚ Type: Pipeline β”‚ β”‚ β”‚ β”‚ πŸ“ VerfΓΌgbar auf Seiten: β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚ β”‚ β˜‘ Analyse (Hauptseite) β”‚ β”‚ β”‚ β”‚ β˜‘ Gewicht β†’ Verlauf β”‚ β”‚ β”‚ β”‚ ☐ UmfΓ€nge β†’ Verlauf β”‚ β”‚ β”‚ β”‚ ☐ Caliper β†’ Verlauf β”‚ β”‚ β”‚ β”‚ ☐ AktivitΓ€t β†’ Verlauf β”‚ β”‚ β”‚ β”‚ ☐ ErnΓ€hrung β†’ Verlauf β”‚ β”‚ β”‚ β”‚ ☐ Schlaf β†’ Verlauf β”‚ β”‚ β”‚ β”‚ ☐ Vitalwerte β†’ Verlauf β”‚ β”‚ β”‚ β”‚ ☐ Dashboard β”‚ β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚ β”‚ β”‚ [Speichern] [Abbrechen] β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ ``` **Mehrfachauswahl:** - Ein Prompt kann auf mehreren Seiten gleichzeitig verfΓΌgbar sein - Mindestens eine Seite muss ausgewΓ€hlt sein - Default: "Analyse (Hauptseite)" ist immer vorausgewΓ€hlt ### 2. UI auf Verlaufsseiten **Gewicht β†’ Verlauf:** ``` β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ πŸ“Š Gewicht - Verlauf β”‚ β”‚ [Filter: 7d] [30d] [90d] [Alle] β”‚ β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ β”‚ β”‚ β”‚ [Chart: Gewichtsverlauf] β”‚ β”‚ β”‚ β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ β”‚ πŸ€– KI-Analysen β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚ β”‚ Gewichtstrend-Analyse [β–Ά Starten]β”‚ β”‚ β”‚ β”‚ KΓΆrperkomposition-Check [β–Ά Starten]β”‚ β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚ β”‚ β”‚ [EintrΓ€ge-Tabelle...] β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ ``` **Features:** - Kompaktes Widget unterhalb des Charts - Nur relevante Prompts werden angezeigt - Button startet Analyse inline (Modal oder expandierend) - Ergebnis wird direkt auf der Seite angezeigt ### 3. Inline-Analyse Anzeige **Option A: Modal (empfohlen fΓΌr MVP):** ``` Click auf [β–Ά Starten] ↓ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ βœ• Gewichtstrend-Analyse β”‚ β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ β”‚ [Spinner] Analysiere Gewichtsdaten... β”‚ β”‚ β”‚ β”‚ [Nach Abschluss:] β”‚ β”‚ Analyse-Text... β”‚ β”‚ β”‚ β”‚ πŸ“Š Verwendete Werte (12) [πŸ”¬ Experten] β”‚ β”‚ [Value Table...] β”‚ β”‚ β”‚ β”‚ [Schließen] [In Verlauf speichern] β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ ``` **Option B: Expandierend (spΓ€ter):** ``` Click auf [β–Ά Starten] ↓ Widget expandiert nach unten Zeigt Analyse-Ergebnis inline [β–³ Einklappen] Button ``` ## Technische Umsetzung ### 1. Datenbankschema erweitern **Tabelle: `ai_prompts`** ```sql ALTER TABLE ai_prompts ADD COLUMN available_on JSONB DEFAULT '["analysis"]'; COMMENT ON COLUMN ai_prompts.available_on IS 'Array of page slugs where prompt is available. Values: analysis, weight_history, circ_history, caliper_history, activity_history, nutrition_history, sleep_history, vitals_history, dashboard'; -- Migration 022 ``` **Beispiel-Werte:** ```json { "slug": "weight_trend", "name": "Gewichtstrend-Analyse", "available_on": ["analysis", "weight_history"] } { "slug": "pipeline_master", "name": "VollstΓ€ndige Analyse", "available_on": ["analysis", "dashboard"] } { "slug": "nutrition_check", "name": "ErnΓ€hrungs-Check", "available_on": ["analysis", "nutrition_history", "activity_history"] } ``` ### 2. Backend API erweitern **Neuer Endpoint: GET /api/prompts/for-page/{page_slug}** ```python @router.get("/for-page/{page_slug}") def get_prompts_for_page(page_slug: str, session: dict = Depends(require_auth)): """Get all prompts available for a specific page. Args: page_slug: Page identifier (e.g., 'weight_history', 'analysis') Returns: List of prompts with available_on containing page_slug """ with get_db() as conn: cur = get_cursor(conn) cur.execute( """SELECT id, name, slug, type, description, available_on FROM ai_prompts WHERE available_on @> %s ORDER BY name""", (json.dumps([page_slug]),) ) return [r2d(row) for row in cur.fetchall()] ``` **Beispiel-Aufruf:** ```javascript // In WeightPage.jsx const prompts = await api.getPromptsForPage('weight_history') // Returns: [{slug: 'weight_trend', name: 'Gewichtstrend-Analyse', ...}] ``` **Prompt CRUD erweitern:** ```python @router.put("/unified/{id}") def update_unified_prompt(id: str, p: UnifiedPromptCreate, session=Depends(require_admin)): # ... existing code ... cur.execute( """UPDATE ai_prompts SET name=%s, slug=%s, template=%s, ..., available_on=%s WHERE id=%s""", (..., json.dumps(p.available_on), id) ) ``` ### 3. Frontend: Prompt-Editor erweitern **UnifiedPromptModal.jsx:** ```javascript const PAGE_OPTIONS = [ { value: 'analysis', label: 'πŸ“Š Analyse (Hauptseite)', default: true }, { value: 'weight_history', label: 'βš–οΈ Gewicht β†’ Verlauf' }, { value: 'circ_history', label: 'πŸ“ UmfΓ€nge β†’ Verlauf' }, { value: 'caliper_history', label: 'πŸ“ Caliper β†’ Verlauf' }, { value: 'activity_history', label: 'πŸƒ AktivitΓ€t β†’ Verlauf' }, { value: 'nutrition_history', label: '🍎 ErnΓ€hrung β†’ Verlauf' }, { value: 'sleep_history', label: '😴 Schlaf β†’ Verlauf' }, { value: 'vitals_history', label: '❀️ Vitalwerte β†’ Verlauf' }, { value: 'dashboard', label: '🏠 Dashboard' }, ] // In form:
{PAGE_OPTIONS.map(opt => ( ))}
``` ### 4. Frontend: Verlaufsseiten erweitern **WeightPage.jsx (Beispiel):** ```javascript function WeightPage() { const [prompts, setPrompts] = useState([]) const [runningAnalysis, setRunningAnalysis] = useState(null) const [analysisResult, setAnalysisResult] = useState(null) useEffect(() => { loadPrompts() }, []) const loadPrompts = async () => { try { const data = await api.getPromptsForPage('weight_history') setPrompts(data) } catch(e) { console.error('Failed to load prompts:', e) } } const runAnalysis = async (promptSlug) => { setRunningAnalysis(promptSlug) try { const result = await api.executePrompt(promptSlug, {save: true}) setAnalysisResult(result) } catch(e) { setError(e.message) } finally { setRunningAnalysis(null) } } return (

Gewicht - Verlauf

{/* Chart */} {/* AI Prompts Widget */} {prompts.length > 0 && (

πŸ€– KI-Analysen

{prompts.map(p => ( ))}
)} {/* Analysis Result Modal */} {analysisResult && ( setAnalysisResult(null)} /> )} {/* Data Table */}
) } ``` **Wiederverwendbare Komponente:** ```javascript // components/PagePrompts.jsx export function PagePrompts({ pageSlug }) { // ... logic ... return (

πŸ€– KI-Analysen

{prompts.map(p => ( ))}
) } // Usage in any page: ``` ## Akzeptanzkriterien - [ ] DB-Migration: `available_on` JSONB column in ai_prompts - [ ] Backend: `GET /api/prompts/for-page/{page_slug}` Endpoint - [ ] Backend: CRUD operations unterstΓΌtzen available_on - [ ] Frontend: Prompt-Editor zeigt Page-Auswahl (Mehrfachauswahl) - [ ] Frontend: Mindestens 1 Page muss ausgewΓ€hlt sein - [ ] Frontend: Wiederverwendbare PagePrompts Komponente - [ ] Frontend: Integration in mind. 2 Verlaufsseiten (Weight, Nutrition) - [ ] UI: Inline-Analyse via Modal mit Value Table - [ ] UI: Loading-State wΓ€hrend Analyse lΓ€uft - [ ] Dokumentation: API-Dokumentation aktualisiert ## AbschΓ€tzung **Aufwand:** 6-8 Stunden - 1h: DB-Migration + Backend Endpoint - 2h: Prompt-Editor erweitern (Page-Auswahl) - 2h: PagePrompts Komponente + Modal - 2h: Integration in Verlaufsseiten (2-3 Seiten) - 1h: Testing + Feintuning **PrioritΓ€t:** Medium - Verbessert UX erheblich (kontextbezogene Analysen) - Nutzt bestehendes Prompt-System (Issue #28) - Relativ einfach zu implementieren (kein neues Backend-System) ## Use Cases ### UC1: Gewichtstrend auf Gewicht-Seite ``` User: Navigiert zu "Gewicht β†’ Verlauf" System: Zeigt Gewichts-Chart + verfΓΌgbare Prompts User: Click "Gewichtstrend-Analyse β–Ά" System: Startet Analyse, zeigt Modal mit Ergebnis User: Click "In Verlauf speichern" System: Speichert in ai_insights, zeigt in Analyse-Verlauf ``` ### UC2: ErnΓ€hrungs-Check auf ErnΓ€hrung-Seite ``` User: Navigiert zu "ErnΓ€hrung β†’ Verlauf" System: Zeigt ErnΓ€hrungs-Charts + verfΓΌgbare Prompts User: Click "ErnΓ€hrungs-Check β–Ά" System: Analysiert Makros + Kalorien der letzten 7 Tage User: Sieht Empfehlungen direkt auf ErnΓ€hrungs-Seite ``` ### UC3: Multi-Page Prompt (z.B. "VollstΓ€ndige Analyse") ``` Admin: Konfiguriert "VollstΓ€ndige Analyse" - VerfΓΌgbar auf: [Analyse, Dashboard, Gewicht, ErnΓ€hrung] User: Sieht denselben Prompt auf 4 verschiedenen Seiten User: Kann von ΓΌberall die gleiche umfassende Analyse starten ``` ## Notizen - **RΓΌckwΓ€rtskompatibilitΓ€t:** Bestehende Prompts ohne `available_on` β†’ Default `["analysis"]` - **Migration:** Alle existierenden Prompts bekommen `["analysis"]` gesetzt - **Permissions:** Prompts respektieren weiterhin Feature-Enforcement (ai_calls) - **Caching:** Prompts kΓΆnnten gecacht werden (selten geΓ€ndert) - **Mobile:** PagePrompts sollte auch auf Mobile gut aussehen (Stack-Layout) - **Performance:** Lazy-Loading der Prompts (nur laden wenn Seite besucht) ## Erweiterungen (Future) - **Conditional Display:** Prompts nur anzeigen wenn Daten vorhanden - Beispiel: "Gewichtstrend" nur wenn min. 3 Gewichts-EintrΓ€ge - **Quick Actions:** Direkt-Buttons im Chart (ohne separates Widget) - **Page-spezifische Variablen:** Automatisch aktuelle Filter ΓΌbergeben - Beispiel: Wenn "30d" Filter aktiv β†’ `{{timeframe}}` = 30 - **Prompt-Templates pro Page:** Vordefinierte Vorlagen fΓΌr jede Seite - **Favoriten:** User kann Prompts auf Seiten favorisieren (User-spezifisch) ## Verwandte Issues - #28: Unified Prompt System (Basis fΓΌr dieses Feature) - #45: KI Prompt-Optimierer (kΓΆnnte Page-Kontext nutzen) - #46: KI Prompt-Ersteller (sollte Page-Auswahl anbieten)