Enhance language course creation script to support public courses
- Updated the script to create public language courses for various target and native languages without requiring an ownerHashedId. - Implemented a function to find or create a system user for course ownership, ensuring automatic user assignment. - Improved documentation to clarify the script's usage and the types of courses created.
This commit is contained in:
@@ -1,11 +1,15 @@
|
|||||||
#!/usr/bin/env node
|
#!/usr/bin/env node
|
||||||
/**
|
/**
|
||||||
* Script zum Erstellen von Sprachkursen für verschiedene Sprachen
|
* Script zum Erstellen von öffentlichen Sprachkursen für verschiedene Sprachen
|
||||||
*
|
*
|
||||||
* Verwendung:
|
* Verwendung:
|
||||||
* node backend/scripts/create-language-courses.js <ownerHashedId>
|
* 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';
|
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 VocabCourseLesson from '../models/community/vocab_course_lesson.js';
|
||||||
import User from '../models/community/user.js';
|
import User from '../models/community/user.js';
|
||||||
import crypto from 'crypto';
|
import crypto from 'crypto';
|
||||||
|
import bcrypt from 'bcryptjs';
|
||||||
|
|
||||||
// Kursstruktur für alle Sprachen (4 Wochen, 40 Lektionen)
|
// Kursstruktur für alle Sprachen (4 Wochen, 40 Lektionen)
|
||||||
const LESSON_TEMPLATE = [
|
const LESSON_TEMPLATE = [
|
||||||
@@ -346,15 +351,54 @@ async function createCourseForLanguage(targetLanguageId, nativeLanguageId, langu
|
|||||||
return course;
|
return course;
|
||||||
}
|
}
|
||||||
|
|
||||||
async function createAllLanguageCourses(ownerHashedId) {
|
async function findOrCreateSystemUser() {
|
||||||
try {
|
// Versuche zuerst einen System-Benutzer zu finden (z.B. mit username "system" oder "admin")
|
||||||
// Finde User
|
let systemUser = await User.findOne({
|
||||||
const user = await User.findOne({ where: { hashedId: ownerHashedId } });
|
where: {
|
||||||
if (!user) {
|
username: 'system'
|
||||||
throw new Error(`User mit hashedId ${ownerHashedId} nicht gefunden`);
|
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
|
||||||
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 = [];
|
const createdCourses = [];
|
||||||
|
|
||||||
@@ -364,7 +408,7 @@ async function createAllLanguageCourses(ownerHashedId) {
|
|||||||
const languageMap = new Map();
|
const languageMap = new Map();
|
||||||
|
|
||||||
for (const langName of allLanguages) {
|
for (const langName of allLanguages) {
|
||||||
const langId = await findOrCreateLanguage(langName, user.id);
|
const langId = await findOrCreateLanguage(langName, systemUser.id);
|
||||||
languageMap.set(langName, langId);
|
languageMap.set(langName, langId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -374,12 +418,12 @@ async function createAllLanguageCourses(ownerHashedId) {
|
|||||||
const targetLanguageId = languageMap.get(langConfig.targetLanguageName);
|
const targetLanguageId = languageMap.get(langConfig.targetLanguageName);
|
||||||
const nativeLanguageId = languageMap.get(langConfig.nativeLanguageName);
|
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({
|
const existingCourse = await VocabCourse.findOne({
|
||||||
where: {
|
where: {
|
||||||
languageId: targetLanguageId,
|
languageId: targetLanguageId,
|
||||||
nativeLanguageId: nativeLanguageId,
|
nativeLanguageId: nativeLanguageId,
|
||||||
ownerUserId: user.id
|
isPublic: true
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -396,7 +440,7 @@ async function createAllLanguageCourses(ownerHashedId) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Erstelle Kurs
|
// Erstelle Kurs
|
||||||
const course = await createCourseForLanguage(targetLanguageId, nativeLanguageId, langConfig, user.id);
|
const course = await createCourseForLanguage(targetLanguageId, nativeLanguageId, langConfig, systemUser.id);
|
||||||
createdCourses.push({
|
createdCourses.push({
|
||||||
...langConfig,
|
...langConfig,
|
||||||
courseId: course.id,
|
courseId: course.id,
|
||||||
@@ -434,15 +478,8 @@ async function createAllLanguageCourses(ownerHashedId) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// CLI-Aufruf
|
// CLI-Aufruf
|
||||||
const ownerHashedId = process.argv[2];
|
// Keine Parameter mehr nötig - verwendet automatisch System-Benutzer
|
||||||
|
createAllLanguageCourses()
|
||||||
if (!ownerHashedId) {
|
|
||||||
console.error('Verwendung: node create-language-courses.js <ownerHashedId>');
|
|
||||||
console.error('Beispiel: node create-language-courses.js abc123def456');
|
|
||||||
process.exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
createAllLanguageCourses(ownerHashedId)
|
|
||||||
.then(() => {
|
.then(() => {
|
||||||
process.exit(0);
|
process.exit(0);
|
||||||
})
|
})
|
||||||
|
|||||||
Reference in New Issue
Block a user