import { anthropicApi } from './api'; import { storage } from './storage'; const CONTENT_GENERATION_SYSTEM = `Je bent een expert leerinhoud-schrijver voor Respellion, een intern IT-bedrijf. Je schrijft leermateriaal voor medewerkers op basis van kennisonderwerpen. Schrijf altijd in het Nederlands, helder en professioneel. Geef ALTIJD geldige JSON terug, zonder markdown code-blokken.`; /** * Get the assigned topic for a user for a given week using round-robin. * hash(userId + weekNumber) % topicCount */ export function getAssignedTopic(userId, weekNumber) { const topics = storage.get('kb:topics', []); if (!topics || topics.length === 0) return null; // Simple deterministic hash const str = `${userId}:${weekNumber}`; let hash = 0; for (let i = 0; i < str.length; i++) { hash = (hash << 5) - hash + str.charCodeAt(i); hash |= 0; // Convert to 32-bit integer } const index = Math.abs(hash) % topics.length; return topics[index]; } /** * Generate a complete learning module for a topic. * Returns an object with { article, slides, podcastScript, infographic }. * Caches results in storage. */ export async function generateLearningContent(topic) { const cacheKey = `kb:content:${topic.id}`; const cached = storage.get(cacheKey); if (cached) { console.log(`[Learn] Cache hit voor topic: ${topic.id}`); return cached; } const prompt = `Genereer een compleet leermodule voor het volgende onderwerp: Label: ${topic.label} Type: ${topic.type} Beschrijving: ${topic.description} Geef ALLEEN een JSON object terug met de volgende structuur: { "article": { "title": "Artikel titel", "intro": "Korte intro van 1-2 zinnen", "sections": [ { "heading": "Sectietitel", "body": "Sectietekst van minimaal 3 zinnen." } ], "keyTakeaways": ["Lespunt 1", "Lespunt 2", "Lespunt 3"] }, "slides": [ { "title": "Diatitel", "bullets": ["Punt 1", "Punt 2", "Punt 3"], "speakerNote": "Toelichting voor de spreker." } ], "podcastScript": "Een vloeiend gesproken script van ca. 300 woorden dat de inhoud samenvat als een podcast.", "infographic": { "headline": "Een korte, krachtige zin die het onderwerp samenvat (max 8 woorden)", "tagline": "Een subkop van max 15 woorden", "stats": [ { "value": "Getal of %", "label": "Korte omschrijving", "icon": "📊" } ], "steps": [ { "number": 1, "title": "Staptitel", "description": "Korte beschrijving van 1 zin.", "icon": "🔑" } ], "quote": "Een inspirerende of kernachtige quote over het onderwerp.", "colorTheme": "teal" } } Zorg voor minimaal 3 secties in het artikel, 4 slides, 3 statistieken en 3-5 stappen in de infographic.`; const responseText = await anthropicApi.generateContent(CONTENT_GENERATION_SYSTEM, prompt); let content; try { const jsonMatch = responseText.match(/\{[\s\S]*\}/); content = JSON.parse(jsonMatch ? jsonMatch[0] : responseText); } catch (e) { throw new Error('AI kon geen geldige leerinhoud genereren.'); } // Cache the content storage.set(cacheKey, content); return content; }