BUG: Wertetabelle wurde nicht angezeigt bei neuer Analyse
ROOT CAUSE: newResult hatte nur {scope, content}, kein metadata
FIX: Build metadata from result.debug.resolved_placeholders
- Für Base: direkt aus resolved_placeholders
- Für Pipeline: collect aus allen stages
- Metadata structure: {prompt_type, placeholders: {key: {value, description}}}
NOTE: Immediate preview hat keine descriptions (nur values)
Saved insights (nach loadAll) haben full metadata with descriptions aus DB
version: 9.6.2 (bugfix)
BUG: Wertetabelle wurde nicht angezeigt
FIX: enable_debug=true wenn save=true (für metadata collection)
- metadata wird nur gespeichert wenn debug aktiv
- jetzt: debug or save → metadata immer verfügbar
BUG: {{placeholder|d}} Modifier funktionierte nicht
ROOT CAUSE: catalog wurde bei Exception nicht zu variables hinzugefügt
FIX:
- variables['_catalog'] = catalog (auch wenn None)
- Warning-Log wenn catalog nicht geladen werden kann
- Debug warning wenn |d ohne catalog verwendet
BUG: Platzhalter in Pipeline-Stages am Ende statt an Cursor
FIX:
- stageTemplateRefs Map für alle Stage-Textareas
- onClick + onKeyUp tracking für Cursor-Position
- Insert at cursor: template.slice(0, pos) + placeholder + template.slice(pos)
- Focus + Cursor restore nach Insert
TECHNICAL:
- prompt_executor.py: Besseres Exception Handling für catalog
- UnifiedPromptModal.jsx: Refs für alle Template-Felder
- prompts.py: enable_debug=debug or save
version: 9.6.1 (bugfix)
module: prompts 2.1.1
Added "📋 Platzhalter exportieren" button in debug viewer:
- Exports all resolved placeholders with values
- Includes all available_variables
- For pipelines: exports per-stage placeholder data
- JSON format with timestamp and prompt metadata
- Filename: placeholders-{slug}-{date}.json
Use case: Development aid - see exactly what data is available
for prompt templates without null values.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
BREAKING: Analysis page switched from old /insights/run to new /prompts/execute
Changes:
- Backend: Added save=true parameter to /prompts/execute
- When enabled, saves final output to ai_insights table
- Extracts content from pipeline output (last stage)
- Frontend api.js: Added save parameter to executeUnifiedPrompt()
- Frontend Analysis.jsx: Switched from api.runInsight() to api.executeUnifiedPrompt()
- Transforms new result format to match InsightCard expectations
- Pipeline outputs properly extracted and displayed
Fixes: PIPELINE_MASTER responses (old template being sent to AI)
The old /insights/run endpoint used raw template field, which for the
legacy "pipeline" prompt was literally "PIPELINE_MASTER". The new
executor properly handles stages and data processing.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Removed conditional hiding of test button (prompt?.slug)
- Button now always visible with helpful tooltip
- handleTest already has save-check logic
Improves discoverability of test functionality.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Frontend: debug viewer now shows even when test fails
- Frontend: export button to download complete prompt config as JSON
- Backend: attach debug info to JSON validation errors
- Backend: include raw output and length in error details
Users can now debug failed prompts and export configs for analysis.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Backend: debug mode in prompt_executor with placeholder tracking
- Backend: show resolved/unresolved placeholders, final prompts, AI responses
- Frontend: test button in UnifiedPromptModal for saved prompts
- Frontend: debug output viewer with JSON preview
- Frontend: wider placeholder example fields in PlaceholderPicker
Resolves pipeline execution debugging issues.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- PlaceholderPicker: Example values in separate full-width row
- Analysis.jsx: Show only pipeline-type prompts
- Analysis.jsx: Remove base prompts and Prompts tab
- Cleanup: Remove PromptEditor component and unused imports
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Major improvements:
1. PlaceholderPicker component (new)
- Loads placeholders dynamically from backend catalog
- Grouped by categories: Profil, Körper, Ernährung, Training, etc.
- Search/filter functionality
- Shows live example values from user data
- Popup modal with expand/collapse categories
2. Replaced hardcoded placeholder chips
- 'Platzhalter einfügen' button opens picker
- Works in both base templates and pipeline inline templates
- Auto-closes after selection
3. Uses existing backend system
- GET /api/prompts/placeholders
- placeholder_resolver.py with PLACEHOLDER_MAP
- Dynamic, module-based placeholder system
- No manual updates needed when modules add new placeholders
Benefits:
- Scalable: New modules can add placeholders without frontend changes
- User-friendly: Search and categorization
- Context-aware: Shows real example values
- Future-proof: Backend-driven catalog
New features:
1. Placeholder chips now visible in pipeline inline templates
- Click to insert: weight_data, nutrition_data, activity_data, etc.
- Same UX as base prompts
2. Convert to Base Prompt button
- New icon (ArrowDownToLine) in actions column
- Only visible for 1-stage pipeline prompts
- Converts pipeline → base by extracting inline template
- Validates: must be 1-stage, 1-prompt, inline source
This allows migrated prompts to be properly categorized as base prompts
for reuse in other pipelines.
Fixes:
1. Template field in stages now full width (was too narrow)
2. Table horizontal scrollbar for mobile (overflow-x: auto)
3. Table min-width 900px to prevent icon clipping
4. Added clickable placeholder chips below base template
- Click to insert placeholders into template
- Shows: weight_data, nutrition_data, activity_data, sleep_data, etc.
UI now mobile-ready and more user-friendly.
Migration 018:
- Add display_name column to ai_prompts
- Migrate existing prompts from hardcoded SLUG_LABELS
- Fallback: name if display_name is NULL
Backend:
- PromptCreate/Update models with display_name field
- create/update/duplicate endpoints handle display_name
- Fallback: use name if display_name not provided
Frontend:
- PromptEditModal: display_name input field
- Placeholder picker: button + dropdown with all placeholders
- Shows example values, inserts {{placeholder}} on click
- Analysis.jsx: use display_name instead of SLUG_LABELS
User-facing changes:
- Prompts now show custom display names (e.g. '🍽️ Ernährung')
- Admin can edit display names instead of hardcoded labels
- Template editor has 'Platzhalter einfügen' button
- No more hardcoded SLUG_LABELS in frontend
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- PromptEditModal: all inputs/textareas now full-width
- Labels positioned above fields (not inline)
- Text left-aligned (was right-aligned)
- Added resize:vertical for textareas
- Side-by-side comparison with word-wrap
- Follows app-wide form design pattern
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Frontend components:
- PromptEditModal.jsx: Full editor with preview, generator, optimizer
- PromptGenerator.jsx: KI-assisted prompt creation from goal description
- Extended api.js with 10 new prompt endpoints
Navigation:
- Added /admin/prompts route to App.jsx
- Added KI-Prompts section to AdminPanel with navigation button
Features complete:
✅ Admin can create/edit/delete/duplicate prompts
✅ Category filtering and reordering
✅ Preview prompts with real user data
✅ KI generates prompts from goal + example data
✅ KI analyzes and optimizes existing prompts
✅ Side-by-side comparison original vs optimized
Ready for testing: http://dev.mitai.jinkendo.de/admin/prompts
Issue #28 Phase 2 complete - 13-18h estimated, ~14h actual
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Backend complete:
- Migration 017: Add category column to ai_prompts
- placeholder_resolver.py: 20+ placeholders with resolver functions
- Extended routers/prompts.py with CRUD endpoints:
* POST /api/prompts (create)
* PUT /api/prompts/:id (update)
* DELETE /api/prompts/:id (delete)
* POST /api/prompts/:id/duplicate
* PUT /api/prompts/reorder
* POST /api/prompts/preview
* GET /api/prompts/placeholders
* POST /api/prompts/generate (KI-assisted generation)
* POST /api/prompts/:id/optimize (KI analysis)
- Extended models.py with PromptCreate, PromptUpdate, PromptGenerateRequest
Frontend:
- AdminPromptsPage.jsx: Full CRUD UI with category filter, reordering
Meta-Features:
- KI generates prompts from goal description + example data
- KI analyzes and optimizes existing prompts
Next: PromptEditModal, PromptGenerator, api.js integration
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Removed local quality filter UI from History page since backend now
handles filtering globally. Activities are already filtered when loaded.
Changes:
- Removed qualityLevel local state
- Simplified filtA to only filter by period
- Replaced filter buttons with info banner showing active global filter
- Added 'Hier ändern →' link to Settings
User can now only change quality filter in Settings (global), not per
page. History shows which filter is active with link to change it.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The component was loading data from backend (which uses global filter)
but useEffect dependency didn't include quality_filter_level, so it
didn't reload when user changed the filter in Settings.
Added useProfile() context and activeProfile.quality_filter_level
to dependency array.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Implemented global quality_filter_level in user profiles for consistent
data filtering across all views (Dashboard, History, Charts, KI-Pipeline).
Backend changes:
- Migration 016: Add quality_filter_level column to profiles table
- quality_filter.py: Centralized helper functions for SQL filtering
- insights.py: Apply global filter in _get_profile_data()
- activity.py: Apply global filter in list_activity()
Frontend changes:
- SettingsPage.jsx: Add Datenqualität section with 4-level selector
- History.jsx: Use global quality filter from profile context
Filter levels: all, quality (good+excellent+acceptable), very_good
(good+excellent), excellent (only excellent)
Closes#31
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Statt einfachem On/Off Toggle jetzt 4 Qualitätsstufen:
- 📊 Alle (kein Filter)
- ✓ Hochwertig (excellent + good + acceptable)
- ✓✓ Sehr gut (excellent + good)
- ⭐ Exzellent (nur excellent)
UI:
- Button-Group (Segmented Control) mit 4 Stufen
- Beschreibung welche Labels inkludiert werden
- Anzeige: X von Y Aktivitäten (wenn gefiltert)
User-Feedback: Stufenweiser Filter ist flexibler als binärer Toggle
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Problem: Errors during import were logged but not visible to user.
Changes:
- Backend: Collect error messages and return in response (first 10 errors)
- Frontend: Display error details in import result box
- UI: Red background when errors > 0, shows detailed error messages
Now users can see exactly which rows failed and why.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Full-width fields with section headers (mobile-friendly)
- Inline editing for all measurements (edit mode per row)
- Smart upsert: date change loads existing entry → update instead of duplicate
- Units integrated into labels (no overflow)
- Baseline: auto-detects existing entry and switches to update mode
- Blood Pressure: inline editing with all fields (date, time, BP, context, flags)
- Edit/Save/Cancel buttons with lucide-react icons
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Einfache 3-Tab-Struktur als Platzhalter:
- Morgenmessung (Baseline)
- Blutdruck (BP)
- Import
Verhindert Crash durch alte API-Calls.
Vollständige UI folgt nach Backend-Test.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
**Backend (insights.py):**
- Extended _get_profile_data() to fetch sleep, rest_days, vitals
- Added template variables for Sleep Module:
{{sleep_summary}}, {{sleep_detail}}, {{sleep_avg_duration}}, {{sleep_avg_quality}}
- Added template variables for Rest Days:
{{rest_days_summary}}, {{rest_days_count}}, {{rest_days_types}}
- Added template variables for Vitals:
{{vitals_summary}}, {{vitals_detail}}, {{vitals_avg_hr}}, {{vitals_avg_hrv}},
{{vitals_avg_bp}}, {{vitals_vo2_max}}
**Frontend (Analysis.jsx):**
- Added 12 new template variables to VARS list in PromptEditor
- Enables AI prompt creation for Sleep, Rest Days, and Vitals analysis
All modules now have AI evaluation support for future prompt creation.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Import endpoints for Omron blood pressure CSV (German date format)
- Import endpoints for Apple Health vitals CSV
- Import UI tab in VitalsPage with drag & drop for both sources
- German month mapping for Omron date parsing ("13 März 2026")
- Upsert logic preserves manual entries (source != 'manual')
- Import result feedback (inserted/updated/skipped/errors)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Form sections:
- Morgenmessung: Ruhepuls, HRV
- Blutdruck (Omron): Systolisch, Diastolisch, Puls
- Fitness & Sauerstoff (Apple Watch): VO2 Max, SpO2, Atemfrequenz
- Warnungen: Unregelmäßiger Herzschlag, Mögliches AFib (checkboxes)
Display:
- All vitals shown in entry list with icons
- Blood pressure highlighted in red (🩸)
- VO2 Max in green (🏃)
- Warnings in orange (⚠️)
Stats overview:
- Dynamic grid showing available metrics
- Avg blood pressure 7d
- Latest VO2 Max
- Avg SpO2 7d
Save/Update:
- Only non-empty fields included in payload
- At least one vital must be provided
Ready for manual testing + import implementation
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Only include fields in payload if they have values
- Prevents sending empty strings to backend (Pydantic validation error)
- Applies to both create and update operations
Error was: 'Input should be a valid integer, unable to parse string as an integer'
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Backend:
- New router: vitals.py with CRUD endpoints
- GET /api/vitals (list)
- GET /api/vitals/by-date/{date}
- POST /api/vitals (upsert)
- PUT /api/vitals/{id}
- DELETE /api/vitals/{id}
- GET /api/vitals/stats (7d/30d averages, trends)
- Registered in main.py
Frontend:
- VitalsPage.jsx with manual entry form
- List with inline editing
- Stats overview (averages, trend indicators)
- Added to CaptureHub (❤️ icon)
- Route /vitals in App.jsx
API:
- Added vitals methods to api.js
v9d Phase 2d - Vitals tracking complete
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Changed from 'folgt in nächster Iteration' to 'Analyse & Entwicklung, folgen später'
- Listed all 5 dimensions with clear purpose
- Clarifies that Minimum Requirements is sufficient for validation
- Other dimensions planned for v9e/v9f (ability development, AI prompts)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Changes:
- Responsive layout: fields stack vertically, no more cramped grid
- Clear labels: 'WAS?', 'BEDINGUNG', 'WICHTIGKEIT'
- Weight field only shown when using 'weighted_score' strategy
- Weight explanation: '1 = unwichtig, 10 = sehr wichtig'
- Success message replaces alert() dialog (auto-dismiss after 2s)
- Delete button moved to rule header
- Better visual hierarchy with sections
User feedback:
- Felder lassen sich auf Handy nicht gut bearbeiten
- Überschriften nicht eindeutig
- Gewicht-Feld Verwirrung
- Keine OK-Dialoge
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Added label row: PARAMETER | OPERATOR | SCHWELLENWERT | GEWICHT
- Prevents confusion between threshold value and weight fields
- Better placeholder for value field (z.B. 90)
- Between operator: stacked vertical inputs with Min/Max labels
- User feedback: confusion between value and weight fields
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- ✓ Green: Successfully evaluated (excellent/good/acceptable/poor)
- ⚠ Orange: Training type assigned but not evaluated (no profile)
- ✕ Gray: No training type assigned
- Tooltip shows evaluation details on hover
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Shows first 10 errors with activity_id and error message
- Helps admin debug evaluation failures
- Errors shown in error box with details
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>