make case files
This commit is contained in:
27
cases/bode-museum.json
Normal file
27
cases/bode-museum.json
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
{
|
||||||
|
"chapter": "🔍 Bode-Museum: Der Big Maple Leaf Raub",
|
||||||
|
"description": "Am 27. März 2017 wurde aus dem Bode-Museum in Berlin eine der größten Goldmünzen der Welt gestohlen: die 'Big Maple Leaf' mit einem Gewicht von 100 kg. Die Täter drangen nachts in das Museum ein und entwendeten die wertvolle Münze. Die Polizei startete eine großangelegte Fahndung nach den Tätern und der gestohlenen Münze.",
|
||||||
|
"tasks": [
|
||||||
|
{
|
||||||
|
"id": "bode-museum-1",
|
||||||
|
"question": "🕵️ AKTE: Bode-Museum Berlin, 27.03.2017\n\nGESTOHLEN: 1 Goldmünze (Big Maple Leaf)\nGEWICHT: 100 kg\nGOLDPREIS (Tatzeit): 37.500 €/kg\n\nBerechne den Versicherungsschaden in Euro.",
|
||||||
|
"answer": 3750000,
|
||||||
|
"points": 50,
|
||||||
|
"type": "word-problem"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "bode-museum-2",
|
||||||
|
"question": "Die drei Täter verkauften das Gold an einen Hehler. Der Hehler zahlte ihnen 3.200.000 €. Sie teilten das Geld so auf: Der Anführer bekam doppelt so viel wie die anderen beiden. Die anderen beiden bekamen gleich viel. Wie viel Euro bekam jeder der beiden anderen Täter?",
|
||||||
|
"answer": 800000,
|
||||||
|
"points": 55,
|
||||||
|
"type": "word-problem"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "bode-museum-3",
|
||||||
|
"question": "📹 ÜBERWACHUNGSVIDEO - Bode-Museum:\n\n03:27 Uhr - Täter betreten das Museum\n03:52 Uhr - Münze wird gestohlen\n04:18 Uhr - Täter verlassen das Gebäude\n05:47 Uhr - Nachtwächter entdeckt den Diebstahl\n\nFragen:\na) Wie viele Minuten waren die Täter im Museum? (von Eintritt bis Verlassen)\nb) Wie viele Minuten vergingen zwischen Diebstahl und Entdeckung?\n\nAntworte mit der Summe beider Zeiten in Minuten.",
|
||||||
|
"answer": 166,
|
||||||
|
"points": 50,
|
||||||
|
"type": "word-problem"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
27
cases/steglitz.json
Normal file
27
cases/steglitz.json
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
{
|
||||||
|
"chapter": "🏦 Berlin-Steglitz: Der Bankeinbruch 2013",
|
||||||
|
"description": "Im Januar 2013 gruben Täter einen unterirdischen Tunnel von einem leerstehenden Ladenlokal zur Sparkasse in Berlin-Steglitz. Über mehrere Tage arbeiteten sie sich durch den Boden, um unbemerkt in die Tresorräume der Bank zu gelangen. Der Einbruch wurde erst entdeckt, nachdem die Täter bereits mit der Beute geflohen waren.",
|
||||||
|
"tasks": [
|
||||||
|
{
|
||||||
|
"id": "steglitz-1",
|
||||||
|
"question": "💬 Chat-Protokoll der Täter (von Polizei abgefangen):\n\nNach dem Bankeinbruch in Berlin-Steglitz 2013:\n\nTäter1: 'Wie viel haben wir eigentlich aus den Tresoren geholt?'\nTäter2: 'Ich hab alle Geldscheine gezählt: 847.000 €'\nTäter3: 'Ne, das kann nicht stimmen. Ich komme auf 1.234.000 €'\nTäter1: 'Moment, lass mich nochmal nachzählen...'\n\nBei der späteren Polizeivernehmung stellte sich heraus: Täter2 hatte sich beim Zählen um 387.000 € verzählt.\n\nWie viel wurde tatsächlich aus der Bank gestohlen?",
|
||||||
|
"answer": 1234000,
|
||||||
|
"points": 45,
|
||||||
|
"type": "word-problem"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "steglitz-2",
|
||||||
|
"question": "Die Täter gruben einen Tunnel von einem leerstehenden Ladenlokal zur Sparkasse in Berlin-Steglitz. Der Tunnel sollte 47 Meter lang werden.\n\nDrei Täter gruben gemeinsam und schafften zusammen 8 Meter pro Tag.\nNach 2 Tagen kam ein vierter Täter dazu. An diesem Tag gruben alle vier zusammen weitere 15 Meter.\n\nWie viele Meter des Tunnels fehlten noch, bis sie die Bank erreichten?",
|
||||||
|
"answer": 16,
|
||||||
|
"points": 50,
|
||||||
|
"type": "word-problem"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "steglitz-3",
|
||||||
|
"question": "📊 POLIZEIBERICHT - Zeitleiste des Bankeinbruchs:\n\nBerlin-Steglitz, Januar 2013:\n\nTag 1, 14:30 Uhr: Täter beginnen Tunnelbau vom leerstehenden Laden\nTag 3, 18:45 Uhr: Tunnel ist fertig, sie erreichen die Bank\nTag 4, 02:15 Uhr: Täter brechen in die Tresorräume ein\nTag 4, 04:37 Uhr: Täter fliehen durch den Tunnel mit der Beute\nTag 5, 11:20 Uhr: Bankangestellte entdecken den Einbruch\n\nBerechne: Wie viele Stunden vergingen vom Beginn des Tunnelbaus bis zur Flucht der Täter? (Antwort in Stunden, runde auf ganze Stunden)",
|
||||||
|
"answer": 84,
|
||||||
|
"points": 55,
|
||||||
|
"type": "word-problem"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
143
server.js
143
server.js
@@ -5,27 +5,133 @@ const path = require('path');
|
|||||||
|
|
||||||
const app = express();
|
const app = express();
|
||||||
const PORT = process.env.PORT || 3000;
|
const PORT = process.env.PORT || 3000;
|
||||||
const TASKS_FILE = path.join(__dirname, 'tasks.json');
|
const CASES_DIR = path.join(__dirname, 'cases');
|
||||||
|
|
||||||
// Middleware
|
// Middleware
|
||||||
app.use(cors());
|
app.use(cors());
|
||||||
app.use(express.json());
|
app.use(express.json());
|
||||||
app.use(express.static('public'));
|
app.use(express.static('public'));
|
||||||
|
|
||||||
// Lade Aufgaben
|
// Lade alle Aufgaben aus dem cases-Ordner
|
||||||
function loadTasks() {
|
function loadTasks() {
|
||||||
try {
|
try {
|
||||||
const data = fs.readFileSync(TASKS_FILE, 'utf8');
|
// Erstelle cases-Ordner falls er nicht existiert
|
||||||
return JSON.parse(data);
|
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) {
|
} catch (error) {
|
||||||
console.error('Fehler beim Laden der Aufgaben:', error);
|
console.error('Fehler beim Laden der Aufgaben:', error);
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Speichere Aufgaben
|
// Finde die Datei, die eine bestimmte Task-ID enthält
|
||||||
function saveTasks(tasks) {
|
function findTaskFile(taskId) {
|
||||||
fs.writeFileSync(TASKS_FILE, JSON.stringify(tasks, null, 2));
|
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
|
// API: Hole alle Aufgaben
|
||||||
@@ -44,30 +150,33 @@ app.post('/api/check-answer', (req, res) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const tasks = loadTasks();
|
const tasks = loadTasks();
|
||||||
const taskIndex = tasks.findIndex(t => t.id === taskId);
|
const task = tasks.find(t => t.id === taskId);
|
||||||
|
|
||||||
if (taskIndex === -1) {
|
if (!task) {
|
||||||
return res.status(404).json({ error: 'Aufgabe nicht gefunden' });
|
return res.status(404).json({ error: 'Aufgabe nicht gefunden' });
|
||||||
}
|
}
|
||||||
|
|
||||||
const task = tasks[taskIndex];
|
|
||||||
const userAnswer = parseInt(answer);
|
const userAnswer = parseInt(answer);
|
||||||
const correctAnswer = parseInt(task.answer);
|
const correctAnswer = parseInt(task.answer);
|
||||||
const isCorrect = userAnswer === correctAnswer;
|
const isCorrect = userAnswer === correctAnswer;
|
||||||
|
|
||||||
// Initialisiere attempts Counter falls nicht vorhanden
|
// Initialisiere attempts Counter falls nicht vorhanden
|
||||||
if (tasks[taskIndex].attempts === undefined) {
|
if (task.attempts === undefined) {
|
||||||
tasks[taskIndex].attempts = 0;
|
task.attempts = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Erhöhe Versuchszähler bei jeder Antwortprüfung
|
// Erhöhe Versuchszähler bei jeder Antwortprüfung
|
||||||
tasks[taskIndex].attempts += 1;
|
task.attempts += 1;
|
||||||
|
|
||||||
// Speichere Antwort, isCorrect und Timestamp in der Task
|
// Speichere Antwort, isCorrect und Timestamp in der Task
|
||||||
tasks[taskIndex].userAnswer = userAnswer;
|
task.userAnswer = userAnswer;
|
||||||
tasks[taskIndex].isCorrect = isCorrect;
|
task.isCorrect = isCorrect;
|
||||||
tasks[taskIndex].answerTimestamp = new Date().toISOString();
|
task.answerTimestamp = new Date().toISOString();
|
||||||
saveTasks(tasks);
|
|
||||||
|
// 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({
|
res.json({
|
||||||
correct: isCorrect,
|
correct: isCorrect,
|
||||||
|
|||||||
Reference in New Issue
Block a user