import { setLyraVoiceId, isAllowedLyraVoiceId } from "../../../db/profile"; /** * PATCH /api/profile/me/lyra-voice * * Legend-only. Setzt die ElevenLabs-Voice-ID für Lyra-TTS. * * Body: { lyraVoiceId: string | null } * null → Default-Voice (kdmDKE6EkgrWrrykO9Qt, Alexandra) * iFSsEDGbm0FiEd2IVH4w → Voice 1 * Gt7OshJCH7MuzX96wFHi → Voice 2 * * Plan-Downgrade-Verhalten: DB-Wert wird NICHT gelöscht. speak.post.ts * prüft plan zur Laufzeit — non-legend User erhalten Default-Voice. */ export default defineEventHandler(async (event) => { const user = await requireUser(event); const db = usePrisma(); const profile = await db.profile.findUnique({ where: { id: user.id }, select: { plan: true }, }); if (!profile) { throw createError({ statusCode: 404, statusMessage: "profile_not_found" }); } if ((profile.plan ?? "free").toLowerCase() !== "legend") { throw createError({ statusCode: 403, statusMessage: "legend_only" }); } const body = await readBody(event); const { lyraVoiceId } = body as { lyraVoiceId?: unknown }; if (!isAllowedLyraVoiceId(lyraVoiceId)) { throw createError({ statusCode: 400, statusMessage: "invalid_voice_id" }); } await setLyraVoiceId(user.id, lyraVoiceId); return { success: true, data: { lyraVoiceId } }; });