feat: automatische Content-Pipeline (release → pairs → übersetzen → audio → ready)
- pictures.pipeline_* Spalten + app_settings Tabelle (Migration) - lib/placeholders.js: Placeholder-Auflösung; TTS spricht keine UUIDs mehr - lib/pairContent.js: geteilte Pair-Logik (Readiness mit Skip-Optionen) - lib/generatePairs.js: Claude-Generierung (konfigurierbare Anzahl, nur Nomen/Adjektive bei word-Pairs) + serverseitige Persistenz inkl. object_pairs - lib/pipeline.js: In-Process-Runner, idempotente Schritte, Boot-Resume - routes/pipeline.js: release/retry/overview/bundle/settings + Bild-Publish (kaskadiert Fragen/Statements/Pairs/Wörter/Objekte/Bild) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
18
src/lib/placeholders.js
Normal file
18
src/lib/placeholders.js
Normal file
@@ -0,0 +1,18 @@
|
||||
// Placeholder-Format in Satz-/Titel-Feldern: {{label.w:uuid}} (Wort) bzw. {{label.o:uuid}} (Objekt).
|
||||
// Geteilt zwischen translate.js (Token-Schutz) und TTS (Auflösung in Sprechtext).
|
||||
const PLACEHOLDER_RE = /\{\{([^.{}]+)\.(w|o):([0-9a-f-]{36})\}\}/g;
|
||||
|
||||
// Legacy-Form ohne Label: {{uuid}} — sollte migriert sein, defensiv trotzdem entfernen.
|
||||
const LEGACY_PLACEHOLDER_RE = /\{\{\s*[0-9a-f-]{36}\s*\}\}/g;
|
||||
|
||||
// Macht aus "Ist das ein {{Apfel.w:1234-…}}?" → "Ist das ein Apfel?" (für TTS/Anzeige).
|
||||
function resolvePlaceholdersToLabels(text) {
|
||||
if (!text) return '';
|
||||
return String(text)
|
||||
.replace(PLACEHOLDER_RE, (_, label) => label)
|
||||
.replace(LEGACY_PLACEHOLDER_RE, '')
|
||||
.replace(/\s{2,}/g, ' ')
|
||||
.trim();
|
||||
}
|
||||
|
||||
module.exports = { PLACEHOLDER_RE, resolvePlaceholdersToLabels };
|
||||
Reference in New Issue
Block a user