feat: global placeholder export with values (Settings page)
All checks were successful
Deploy Development / deploy (push) Successful in 45s
Build Test / lint-backend (push) Successful in 0s
Build Test / build-frontend (push) Successful in 13s

Zentraler Export aller verfügbaren Platzhalter mit aktuellen Werten.

Backend:
- GET /api/prompts/placeholders/export-values
  - Returns all placeholders organized by category
  - Includes resolved values for current profile
  - Includes metadata (description, example)
  - Flat list + categorized structure

Frontend SettingsPage:
- Button "📊 Platzhalter exportieren"
- Downloads: placeholders-{profile}-{date}.json
- Shows all 38+ placeholders with current values
- Useful for:
  - Understanding available data
  - Debugging prompt templates
  - Verifying placeholder resolution

Frontend api.js:
- exportPlaceholderValues()

Export Format:
{
  "export_date": "2026-03-26T...",
  "profile_id": "...",
  "count": 38,
  "all_placeholders": { "name": "Lars", ... },
  "placeholders_by_category": {
    "Profil": [...],
    "Körper": [...],
    ...
  }
}

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Lars 2026-03-26 10:05:11 +01:00
parent 7f94a41965
commit 555ff62b56
3 changed files with 78 additions and 0 deletions

View File

@ -217,6 +217,54 @@ def list_placeholders(session: dict=Depends(require_auth)):
return get_placeholder_catalog(profile_id)
@router.get("/placeholders/export-values")
def export_placeholder_values(session: dict = Depends(require_auth)):
"""
Export all available placeholders with their current resolved values.
Returns JSON export suitable for download with all placeholders
resolved for the current user's profile.
"""
from datetime import datetime
profile_id = session['profile_id']
# Get all resolved placeholder values
resolved_values = get_placeholder_example_values(profile_id)
# Clean up keys (remove {{ }})
cleaned_values = {
key.replace('{{', '').replace('}}', ''): value
for key, value in resolved_values.items()
}
# Get catalog for metadata
catalog = get_placeholder_catalog(profile_id)
# Organize by category with metadata
export_data = {
'export_date': datetime.now().isoformat(),
'profile_id': profile_id,
'placeholders_by_category': {}
}
for category, items in catalog.items():
export_data['placeholders_by_category'][category] = []
for item in items:
key = item['key'].replace('{{', '').replace('}}', '')
export_data['placeholders_by_category'][category].append({
'key': item['key'],
'description': item['description'],
'value': cleaned_values.get(key, 'nicht verfügbar'),
'example': item.get('example')
})
# Also include flat list for easy access
export_data['all_placeholders'] = cleaned_values
export_data['count'] = len(cleaned_values)
return export_data
# ── KI-Assisted Prompt Engineering ───────────────────────────────────────────
async def call_openrouter(prompt: str, max_tokens: int = 1500) -> str:

View File

@ -251,6 +251,23 @@ export default function SettingsPage() {
setEditingId(null)
}
const handleExportPlaceholders = async () => {
try {
const data = await api.exportPlaceholderValues()
const blob = new Blob([JSON.stringify(data, null, 2)], { type: 'application/json' })
const url = URL.createObjectURL(blob)
const a = document.createElement('a')
a.href = url
a.download = `placeholders-${activeProfile?.name || 'profile'}-${new Date().toISOString().split('T')[0]}.json`
document.body.appendChild(a)
a.click()
document.body.removeChild(a)
URL.revokeObjectURL(url)
} catch (e) {
alert('Fehler beim Export: ' + e.message)
}
}
return (
<div>
<h1 className="page-title">Einstellungen</h1>
@ -409,6 +426,16 @@ export default function SettingsPage() {
<span className="badge-button-description">maschinenlesbar, alles in einer Datei</span>
</div>
</button>
<button className="btn btn-full"
onClick={handleExportPlaceholders}
style={{ background: 'var(--surface2)', border: '1px solid var(--border)' }}>
<div className="badge-button-layout">
<div className="badge-button-header">
<span><BarChart3 size={14}/> Platzhalter exportieren</span>
</div>
<span className="badge-button-description">alle verfügbaren Platzhalter mit aktuellen Werten</span>
</div>
</button>
</>}
</div>
<p style={{fontSize:11,color:'var(--text3)',marginTop:8}}>

View File

@ -326,4 +326,7 @@ export const api = {
if (overwrite) params.append('overwrite', 'true')
return req(`/prompts/import?${params}`, json(data))
},
// Placeholder Export
exportPlaceholderValues: () => req('/prompts/placeholders/export-values'),
}