#!/usr/bin/env node /** * Erstellt den Phase-1-Deutschkurs für Bisaya-Lernende. * * Verwendung: * node backend/scripts/create-german-for-bisaya-course.js */ import crypto from 'crypto'; import { Op } from 'sequelize'; import { sequelize } from '../utils/sequelize.js'; 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 { GERMAN_FOR_BISAYA_PHASE1_DIDACTICS, GERMAN_FOR_BISAYA_PHASE1_LESSONS } from './german-for-bisaya-phase1.js'; import { GERMAN_FOR_BISAYA_PHASE3_DIDACTICS, GERMAN_FOR_BISAYA_PHASE3_LESSONS } from './german-for-bisaya-phase3-extension.js'; import { GERMAN_FOR_BISAYA_PHASE4_DIDACTICS, GERMAN_FOR_BISAYA_PHASE4_LESSONS } from './german-for-bisaya-phase4-extension.js'; import { GERMAN_FOR_BISAYA_PHASE5_DIDACTICS, GERMAN_FOR_BISAYA_PHASE5_LESSONS } from './german-for-bisaya-phase5-extension.js'; import { getGermanForBisayaLessonPedagogy } from './german-for-bisaya-phase2-pedagogy.js'; const ALL_GERMAN_FOR_BISAYA_LESSONS = [ ...GERMAN_FOR_BISAYA_PHASE1_LESSONS, ...GERMAN_FOR_BISAYA_PHASE3_LESSONS, ...GERMAN_FOR_BISAYA_PHASE4_LESSONS, ...GERMAN_FOR_BISAYA_PHASE5_LESSONS ]; const ALL_GERMAN_FOR_BISAYA_DIDACTICS = { ...GERMAN_FOR_BISAYA_PHASE1_DIDACTICS, ...GERMAN_FOR_BISAYA_PHASE3_DIDACTICS, ...GERMAN_FOR_BISAYA_PHASE4_DIDACTICS, ...GERMAN_FOR_BISAYA_PHASE5_DIDACTICS }; async function getLanguageId(languageName) { const [language] = await sequelize.query( `SELECT id FROM community.vocab_language WHERE name = :name LIMIT 1`, { replacements: { name: languageName }, type: sequelize.QueryTypes.SELECT } ); if (!language) { throw new Error(`Sprache "${languageName}" nicht gefunden`); } return Number(language.id); } async function getOwnerByHashedId(ownerHashedId) { const user = await User.findOne({ where: { hashedId: ownerHashedId } }); if (!user) { throw new Error(`Benutzer mit hashedId "${ownerHashedId}" nicht gefunden`); } return user; } async function createGermanForBisayaCourse(ownerHashedId) { await sequelize.authenticate(); const owner = await getOwnerByHashedId(ownerHashedId); const germanLanguageId = await getLanguageId('Deutsch'); const bisayaLanguageId = await getLanguageId('Bisaya'); const existingCourse = await VocabCourse.findOne({ where: { ownerUserId: owner.id, languageId: germanLanguageId, nativeLanguageId: bisayaLanguageId, title: { [Op.like]: 'Deutsch für Bisaya-Lernende%' } } }); if (existingCourse) { console.log(`Kurs bereits vorhanden: ${existingCourse.title} (ID: ${existingCourse.id})`); return existingCourse; } const shareCode = crypto.randomBytes(8).toString('hex'); const course = await VocabCourse.create({ ownerUserId: owner.id, title: 'Deutsch für Bisaya-Lernende - Alltag & Stabilisierung', description: '15 Wochen Deutsch-Lernpfad aus Sicht von Bisaya-Lernenden mit Alltag, Fehlertraining, Intensivwiederholung und Stabilisierung.', languageId: germanLanguageId, nativeLanguageId: bisayaLanguageId, difficultyLevel: 1, isPublic: false, shareCode }); for (const lessonData of ALL_GERMAN_FOR_BISAYA_LESSONS) { const didactics = ALL_GERMAN_FOR_BISAYA_DIDACTICS[lessonData.title] || {}; const pedagogy = getGermanForBisayaLessonPedagogy(lessonData.num, lessonData.type); await VocabCourseLesson.create({ courseId: course.id, chapterId: null, lessonNumber: lessonData.num, title: lessonData.title, description: lessonData.desc, weekNumber: lessonData.week, dayNumber: lessonData.day, lessonType: lessonData.type, didacticMode: pedagogy.didacticMode, phaseLabel: pedagogy.phaseLabel, blockNumber: pedagogy.blockNumber, difficultyWeight: pedagogy.difficultyWeight, newUnitTarget: pedagogy.newUnitTarget, reviewWeight: pedagogy.reviewWeight, isIntensiveReview: pedagogy.isIntensiveReview, culturalNotes: lessonData.cultural, learningGoals: didactics.learningGoals || null, corePatterns: didactics.corePatterns || null, grammarFocus: didactics.grammarFocus || null, speakingPrompts: didactics.speakingPrompts || null, practicalTasks: didactics.practicalTasks || null, targetMinutes: lessonData.targetMin, targetScorePercent: lessonData.targetScore, requiresReview: lessonData.review }); } console.log(`Kurs erstellt: ${course.title} (ID: ${course.id})`); console.log(`Lektionen erstellt: ${ALL_GERMAN_FOR_BISAYA_LESSONS.length}`); return course; } if (import.meta.url === `file://${process.argv[1]}`) { const ownerHashedId = process.argv[2]; if (!ownerHashedId) { console.error('Verwendung: node backend/scripts/create-german-for-bisaya-course.js '); process.exit(1); } createGermanForBisayaCourse(ownerHashedId) .then(() => process.exit(0)) .catch((error) => { console.error(error); process.exit(1); }); }