const express = require('express'); const cors = require('cors'); const fs = require('fs'); const path = require('path'); const app = express(); const PORT = process.env.PORT || 3000; const CASES_DIR = path.join(__dirname, 'cases'); // Middleware app.use(cors()); app.use(express.json()); app.use(express.static('public')); // Lade alle Aufgaben aus dem cases-Ordner function loadTasks() { try { // Erstelle cases-Ordner falls er nicht existiert if (!fs.existsSync(CASES_DIR)) { fs.mkdirSync(CASES_DIR, { recursive: true }); console.log('Cases-Ordner erstellt:', CASES_DIR); return []; } const allTasks = []; const files = fs.readdirSync(CASES_DIR); files.forEach(file => { if (file.endsWith('.json')) { const filePath = path.join(CASES_DIR, file); const data = fs.readFileSync(filePath, 'utf8'); const caseData = JSON.parse(data); // Unterstütze sowohl alte Struktur (Array) als auch neue Struktur (Objekt) if (Array.isArray(caseData)) { // Alte Struktur: direktes Array von Tasks allTasks.push(...caseData); } else if (caseData.tasks && Array.isArray(caseData.tasks)) { // Neue Struktur: Objekt mit chapter, description, tasks caseData.tasks.forEach(task => { // Füge chapter und chapterDescription zu jeder Task hinzu const taskWithChapter = { ...task, chapter: caseData.chapter, chapterDescription: caseData.description }; allTasks.push(taskWithChapter); }); } } }); return allTasks; } catch (error) { console.error('Fehler beim Laden der Aufgaben:', error); return []; } } // Finde die Datei, die eine bestimmte Task-ID enthält function findTaskFile(taskId) { try { if (!fs.existsSync(CASES_DIR)) { return null; } const files = fs.readdirSync(CASES_DIR); for (const file of files) { if (file.endsWith('.json')) { const filePath = path.join(CASES_DIR, file); const data = fs.readFileSync(filePath, 'utf8'); const caseData = JSON.parse(data); // Unterstütze sowohl alte Struktur (Array) als auch neue Struktur (Objekt) let tasks = []; if (Array.isArray(caseData)) { tasks = caseData; } else if (caseData.tasks && Array.isArray(caseData.tasks)) { tasks = caseData.tasks; } if (tasks.some(task => task.id === taskId)) { return { filePath, caseData }; } } } return null; } catch (error) { console.error('Fehler beim Finden der Task-Datei:', error); return null; } } // Speichere Aufgaben in der entsprechenden Datei function saveTask(taskId, updatedTask) { try { const fileInfo = findTaskFile(taskId); if (!fileInfo) { throw new Error(`Datei für Task ${taskId} nicht gefunden`); } const { filePath, caseData } = fileInfo; // Entferne chapter und chapterDescription aus der Task (werden beim Laden wieder hinzugefügt) const { chapter, chapterDescription, ...taskWithoutChapter } = updatedTask; // Unterstütze sowohl alte Struktur (Array) als auch neue Struktur (Objekt) if (Array.isArray(caseData)) { // Alte Struktur: direktes Array const taskIndex = caseData.findIndex(t => t.id === taskId); if (taskIndex === -1) { throw new Error(`Task ${taskId} nicht in Datei gefunden`); } caseData[taskIndex] = updatedTask; fs.writeFileSync(filePath, JSON.stringify(caseData, null, 2)); } else if (caseData.tasks && Array.isArray(caseData.tasks)) { // Neue Struktur: Objekt mit chapter, description, tasks const taskIndex = caseData.tasks.findIndex(t => t.id === taskId); if (taskIndex === -1) { throw new Error(`Task ${taskId} nicht in Datei gefunden`); } caseData.tasks[taskIndex] = taskWithoutChapter; fs.writeFileSync(filePath, JSON.stringify(caseData, null, 2)); } else { throw new Error('Ungültige Dateistruktur'); } return true; } catch (error) { console.error('Fehler beim Speichern der Aufgabe:', error); return false; } } // API: Hole alle Aufgaben app.get('/api/tasks', (req, res) => { const tasks = loadTasks(); res.json({ tasks }); }); // API: Prüfe Antwort app.post('/api/check-answer', (req, res) => { const { taskId, answer } = req.body; if (!taskId || answer === undefined) { return res.status(400).json({ error: 'taskId und answer sind erforderlich' }); } const tasks = loadTasks(); const task = tasks.find(t => t.id === taskId); if (!task) { return res.status(404).json({ error: 'Aufgabe nicht gefunden' }); } const userAnswer = parseInt(answer); const correctAnswer = parseInt(task.answer); const isCorrect = userAnswer === correctAnswer; // Initialisiere attempts Counter falls nicht vorhanden if (task.attempts === undefined) { task.attempts = 0; } // Erhöhe Versuchszähler bei jeder Antwortprüfung task.attempts += 1; // Speichere Antwort, isCorrect und Timestamp in der Task task.userAnswer = userAnswer; task.isCorrect = isCorrect; task.answerTimestamp = new Date().toISOString(); // Speichere die aktualisierte Task in der entsprechenden Datei if (!saveTask(taskId, task)) { return res.status(500).json({ error: 'Fehler beim Speichern der Antwort' }); } res.json({ correct: isCorrect, correctAnswer: correctAnswer, points: isCorrect ? task.points : 0 }); }); // Starte Server app.listen(PORT, () => { console.log(`MathQuest Server läuft auf http://localhost:${PORT}`); });