import { usePrisma } from "../../utils/prisma"; /** * GET /api/coach/history * Lädt den gespeicherten Chat-Verlauf (nur Pro/Legend). * Gibt das neueste CoachSession-Dokument zurück. */ export default defineEventHandler(async (event) => { const user = await requireUser(event); console.log("[coach/history] userId:", user.id); const db = usePrisma(); const profile = await db.profile.findUnique({ where: { id: user.id }, select: { plan: true }, }); console.log("[coach/history] plan:", profile?.plan); if (!profile || !["pro", "legend"].includes(profile.plan)) { return { messages: [] }; } const session = await db.coachSession.findFirst({ where: { userId: user.id }, orderBy: { createdAt: "desc" }, }); console.log( "[coach/history] session found:", !!session, "msgs:", Array.isArray(session?.content) ? (session.content as any[]).length : 0, ); if (!session) { return { messages: [] }; } // Defensiver Filter: Alt-Sessions können vor dem sosMode-Fix mit SOS-Resten // kontaminiert sein (SOS_BOOT, [INTERN:]/[SYSTEM-HINT]-Prompts, rohe // JSON-/[[CHIPS]]-Antworten). Solche Nachrichten gehören NIE in den Coach-Chat // → beim Laden rausfiltern, damit bestehende Verläufe automatisch heilen. const raw = (session.content as Array<{ role: string; content: string }>) ?? []; const isInternal = (m: { role: string; content: string }) => { const c = (m?.content ?? "").trimStart(); if ( c.startsWith("[SOS-MODUS") || c.startsWith("[INTERN:") || c.startsWith("[SYSTEM-HINT]") ) { return true; } // Rohe Lyra-JSON-Antwort (Game-Kommentar / Share-Draft) oder Chips-Marker if (m?.role === "assistant") { if (c.includes("[[CHIPS]]:")) return true; if (/^\{[\s\S]*"message"\s*:/.test(c)) return true; } return false; }; return { messages: raw.filter((m) => !isInternal(m)), }; });