feat: TTS-Settings je Sprache, Audio-Coverage entkoppelt, Veröffentlichen-Workflow

- tts_settings (voice/model/speed/... pro Sprache) + Seed de/en/sv; Route /api/tts-settings
- audios: Stimme/Parameter aus tts_settings; Coverage zählt jetzt auch draft/translated
- pairs: GET /publishability (Readiness, sortierbar nach 'am wenigsten fehlt'),
  POST /:id/publish (kaskadiert question/statements→published, validiert Bild+Audio je Sprache)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-06-02 22:02:07 +02:00
parent 9bfd5e8dba
commit 6c74aabc3f
5 changed files with 255 additions and 7 deletions

View File

@@ -572,6 +572,34 @@ async function migrate() {
FOR EACH ROW EXECUTE FUNCTION update_updated_at()
`);
// tts_settings — Stimme + Parameter pro Sprache (zentral konfigurierbar)
await query(`
CREATE TABLE IF NOT EXISTS tts_settings (
language VARCHAR(10) PRIMARY KEY,
voice_id TEXT NOT NULL,
model_id TEXT NOT NULL DEFAULT 'eleven_multilingual_v2',
speed NUMERIC(4,2) NOT NULL DEFAULT 1.0,
stability NUMERIC(4,2) NOT NULL DEFAULT 0.5,
similarity_boost NUMERIC(4,2) NOT NULL DEFAULT 0.75,
style NUMERIC(4,2) NOT NULL DEFAULT 0.0,
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
)
`);
await query(`
DROP TRIGGER IF EXISTS tts_settings_updated_at ON tts_settings;
CREATE TRIGGER tts_settings_updated_at
BEFORE UPDATE ON tts_settings
FOR EACH ROW EXECUTE FUNCTION update_updated_at()
`);
// Seed-Stimmen (nur einfügen wenn fehlt — manuelle Änderungen bleiben erhalten)
await query(`
INSERT INTO tts_settings (language, voice_id) VALUES
('de', 'rKiu7lQ4c5P3az3745s3'),
('en', 'cVd39cx0VtXNC13y5Y7z'),
('sv', 'XXCqsM8I9KhqA7jLGj1U')
ON CONFLICT (language) DO NOTHING
`).catch(() => {});
// ── Migrate old {{uuid}} placeholders → new {{label.w:uuid}} / {{label.o:uuid}} ──
await migratePlaceholders();