diff --git a/backend/scripts/create-language-courses.js b/backend/scripts/create-language-courses.js index b2bc178..d248d90 100755 --- a/backend/scripts/create-language-courses.js +++ b/backend/scripts/create-language-courses.js @@ -1,11 +1,15 @@ #!/usr/bin/env node /** - * Script zum Erstellen von Sprachkursen für verschiedene Sprachen + * Script zum Erstellen von öffentlichen Sprachkursen für verschiedene Sprachen * * Verwendung: - * node backend/scripts/create-language-courses.js + * node backend/scripts/create-language-courses.js * - * Erstellt Kurse für: Bisaya, Französisch, Spanisch, Latein, Italienisch, Portugiesisch, Tagalog + * Erstellt öffentliche Kurse für alle Kombinationen von: + * - Zielsprachen: Bisaya, Französisch, Spanisch, Latein, Italienisch, Portugiesisch, Tagalog + * - Muttersprachen: Deutsch, Englisch, Spanisch, Französisch, Italienisch, Portugiesisch + * + * Die Kurse werden automatisch einem System-Benutzer zugeordnet und sind öffentlich zugänglich. */ import { sequelize } from '../utils/sequelize.js'; @@ -13,6 +17,7 @@ import VocabCourse from '../models/community/vocab_course.js'; import VocabCourseLesson from '../models/community/vocab_course_lesson.js'; import User from '../models/community/user.js'; import crypto from 'crypto'; +import bcrypt from 'bcryptjs'; // Kursstruktur für alle Sprachen (4 Wochen, 40 Lektionen) const LESSON_TEMPLATE = [ @@ -346,15 +351,54 @@ async function createCourseForLanguage(targetLanguageId, nativeLanguageId, langu return course; } -async function createAllLanguageCourses(ownerHashedId) { - try { - // Finde User - const user = await User.findOne({ where: { hashedId: ownerHashedId } }); - if (!user) { - throw new Error(`User mit hashedId ${ownerHashedId} nicht gefunden`); - } +async function findOrCreateSystemUser() { + // Versuche zuerst einen System-Benutzer zu finden (z.B. mit username "system" oder "admin") + let systemUser = await User.findOne({ + where: { + username: 'system' + } + }); - console.log(`\n🚀 Erstelle Sprachkurse für Benutzer: ${user.id}\n`); + if (!systemUser) { + // Versuche Admin-Benutzer + systemUser = await User.findOne({ + where: { + username: 'admin' + } + }); + } + + if (!systemUser) { + // Erstelle einen System-Benutzer + console.log(' ℹ️ Erstelle System-Benutzer für öffentliche Kurse...'); + const saltRounds = 10; + const randomPassword = crypto.randomBytes(32).toString('hex'); + const hashedPassword = await bcrypt.hash(randomPassword, saltRounds); + + systemUser = await User.create({ + username: 'system', + email: 'system@your-part.de', + password: hashedPassword, + active: true, + registrationDate: new Date() + }); + + // hashedId wird automatisch vom Hook gesetzt, aber warte kurz darauf + await systemUser.reload(); + console.log(` ✅ System-Benutzer erstellt (ID: ${systemUser.id}, hashedId: ${systemUser.hashedId})`); + } else { + console.log(` ✅ System-Benutzer gefunden (ID: ${systemUser.id}, Username: ${systemUser.username})`); + } + + return systemUser; +} + +async function createAllLanguageCourses() { + try { + // Finde oder erstelle System-Benutzer + const systemUser = await findOrCreateSystemUser(); + + console.log(`\n🚀 Erstelle öffentliche Sprachkurse (Besitzer: System-Benutzer ID ${systemUser.id})\n`); const createdCourses = []; @@ -364,7 +408,7 @@ async function createAllLanguageCourses(ownerHashedId) { const languageMap = new Map(); for (const langName of allLanguages) { - const langId = await findOrCreateLanguage(langName, user.id); + const langId = await findOrCreateLanguage(langName, systemUser.id); languageMap.set(langName, langId); } @@ -374,12 +418,12 @@ async function createAllLanguageCourses(ownerHashedId) { const targetLanguageId = languageMap.get(langConfig.targetLanguageName); const nativeLanguageId = languageMap.get(langConfig.nativeLanguageName); - // Prüfe, ob Kurs bereits existiert + // Prüfe, ob Kurs bereits existiert (unabhängig vom Besitzer, wenn öffentlich) const existingCourse = await VocabCourse.findOne({ where: { languageId: targetLanguageId, nativeLanguageId: nativeLanguageId, - ownerUserId: user.id + isPublic: true } }); @@ -396,7 +440,7 @@ async function createAllLanguageCourses(ownerHashedId) { } // Erstelle Kurs - const course = await createCourseForLanguage(targetLanguageId, nativeLanguageId, langConfig, user.id); + const course = await createCourseForLanguage(targetLanguageId, nativeLanguageId, langConfig, systemUser.id); createdCourses.push({ ...langConfig, courseId: course.id, @@ -434,15 +478,8 @@ async function createAllLanguageCourses(ownerHashedId) { } // CLI-Aufruf -const ownerHashedId = process.argv[2]; - -if (!ownerHashedId) { - console.error('Verwendung: node create-language-courses.js '); - console.error('Beispiel: node create-language-courses.js abc123def456'); - process.exit(1); -} - -createAllLanguageCourses(ownerHashedId) +// Keine Parameter mehr nötig - verwendet automatisch System-Benutzer +createAllLanguageCourses() .then(() => { process.exit(0); })