Added wall creation, deletion and fetching

This commit is contained in:
2026-01-01 13:26:27 +01:00
parent cd72390f42
commit 163fccb9b2

View File

@@ -4,7 +4,70 @@ import { checkStringProp } from './util.js';
/** /**
* @type {Collection} * @type {Collection}
*/ */
let games; let cGames;
/**
* @type {Collection}
*/
let cWalls;
/**
* @type {Collection}
*/
let cCategories;
/**
* @type {Collection}
*/
let cQuestions;
const QuestionType = {
SIMPLE: 'SIMPLE',
MULTIPLE_CHOICE: 'MULTIPLE_CHOICE',
IMAGE: 'IMAGE',
IMAGE_MULTIPLE_CHOICE: 'IMAGE_MULTIPLE_CHOICE',
AUDIO: 'AUDIO',
AUDIO_MULTIPLE_CHOICE: 'AUDIO_MULTIPLE_CHOICE',
};
/**
*
* @param {number} points
* @param {string} question
* @param {string} answer
* @param {ObjectId} owner
* @returns
*/
function createSimpleQuestion(points, question, answer, owner) {
return {
owner,
points,
type: QuestionType.SIMPLE,
data: createSimpleData(question, answer),
};
}
/**
*
* @param {string} question
* @param {string} answer
* @returns
*/
function createSimpleData(question, answer) {
return {
question,
answer,
};
}
/**
*
* @param {ObjectId[]} ids
*/
function splitQuestionIds(ids) {
let res = [];
for (let i = 0; i < ids.length; i += 5) {
res.push(ids.slice(i, i + 5));
}
return res;
}
/** /**
* *
@@ -12,11 +75,19 @@ let games;
* @param {Db} db * @param {Db} db
*/ */
export function initGames(app, db) { export function initGames(app, db) {
games = db.collection('games'); cGames = db.collection('games');
cWalls = db.collection('walls');
cCategories = db.collection('categories');
cQuestions = db.collection('questions');
app.get('/game', fetchGame); app.get('/game', fetchGame);
app.post('/game', createGame); app.post('/game', createGame);
app.delete('/game/:gameid', deleteGame); app.delete('/game/:gameid', deleteGameRoute);
app.get('/games', fetchGames); app.get('/games', fetchGames);
app.get('/wall', fetchWall);
app.get('/walls/:gameid', fetchWalls);
app.post('/wall', createWall);
app.delete('/wall/:wallid', deleteWallRoute);
} }
/** /**
@@ -32,7 +103,7 @@ async function createGame(req, res) {
const name = req.body.name; const name = req.body.name;
games cGames
.insertOne({ .insertOne({
name, name,
walls: [], walls: [],
@@ -53,7 +124,7 @@ async function createGame(req, res) {
* @param {import('express').Response} res * @param {import('express').Response} res
*/ */
async function fetchGames(req, res) { async function fetchGames(req, res) {
let list = games.find({ let list = cGames.find({
owner: req.user._id, owner: req.user._id,
}); });
@@ -73,7 +144,7 @@ async function fetchGame(req, res) {
const id = new ObjectId(req.query.id); const id = new ObjectId(req.query.id);
let game = await games.findOne({ let game = await cGames.findOne({
_id: id, _id: id,
owner: req.user._id, owner: req.user._id,
}); });
@@ -90,8 +161,8 @@ async function fetchGame(req, res) {
* @param {import('express').Request} req * @param {import('express').Request} req
* @param {import('express').Response} res * @param {import('express').Response} res
*/ */
async function deleteGame(req, res) { async function deleteGameRoute(req, res) {
let game = await games.findOne({ let game = await cGames.findOne({
owner: req.user._id, owner: req.user._id,
_id: new ObjectId(req.params.gameid), _id: new ObjectId(req.params.gameid),
}); });
@@ -101,8 +172,7 @@ async function deleteGame(req, res) {
return; return;
} }
games deleteGame(game._id)
.deleteOne({ _id: game._id })
.then(() => { .then(() => {
res.sendStatus(200); res.sendStatus(200);
}) })
@@ -111,3 +181,250 @@ async function deleteGame(req, res) {
res.sendStatus(500); res.sendStatus(500);
}); });
} }
/**
*
* @param {import('express').Request} req
* @param {import('express').Response} res
*/
async function fetchWall(req, res) {
if (req.query.id === undefined || req.query.id.length <= 0) {
res.sendStatus(400);
return;
}
const id = new ObjectId(req.query.id);
let wall = await cWalls.findOne({
_id: id,
owner: req.user._id,
});
if (wall) {
res.status(200).send(wall);
} else {
res.sendStatus(404);
}
}
/**
*
* @param {import('express').Request} req
* @param {import('express').Response} res
*/
async function fetchWalls(req, res) {
let game = await cGames.findOne({
owner: req.user._id,
_id: new ObjectId(req.params.gameid),
});
if (!game) {
res.sendStatus(404);
return;
}
let fetchedWalls = cWalls.find({
_id: {
$in: game.walls,
},
});
res.status(200).send(await fetchedWalls.toArray());
}
/**
*
* @param {import('express').Request} req
* @param {import('express').Response} res
*/
async function createWall(req, res) {
if (
!checkStringProp(req.body, 'gameid') &&
!checkStringProp(req.body, 'name')
) {
res.sendStatus(400);
return;
}
/**
* @type {string}
*/
const gameid = req.body.gameid;
/**
* @type {string}
*/
const wallname = req.body.name;
let game = await cGames.findOne({
owner: req.user._id,
_id: new ObjectId(gameid),
});
if (!game) {
res.sendStatus(404);
return;
}
let newQuestions = [];
for (let id = 0; id < 25; id++) {
newQuestions.push(
createSimpleQuestion(-1, 'Frage', 'Antwort', req.user._id),
);
}
cQuestions
.insertMany(newQuestions)
.then((insertedQuestions) => {
let questionsIds = splitQuestionIds(
Object.values(insertedQuestions.insertedIds),
);
let newCategories = [];
for (let i = 1; i <= 5; i++) {
newCategories.push({
name: `Kategorie ${i}`,
questions: questionsIds[i - 1],
owner: req.user._id,
});
}
return cCategories.insertMany(newCategories);
})
.then((insertedCategories) => {
return cWalls.insertOne({
name: wallname,
categories: Object.values(insertedCategories.insertedIds),
owner: req.user._id,
});
})
.then((insertedWall) => {
return cGames.updateOne(
{
_id: game._id,
},
{
$push: {
walls: insertedWall.insertedId,
},
},
);
})
.then(() => {
res.sendStatus(200);
})
.catch((err) => {
console.error(err);
res.sendStatus(500);
});
}
/**
*
* @param {import('express').Request} req
* @param {import('express').Response} res
*/
async function deleteWallRoute(req, res) {
let wall = await cWalls.findOne({
_id: new ObjectId(req.params.wallid),
owner: req.user._id,
});
if (!wall) {
res.sendStatus(404);
return;
}
let game = await cGames.findOne({
owner: req.user._id,
walls: wall._id,
});
if (!game) {
res.sendStatus(404);
return;
}
deleteWall(wall._id)
.then(() => {
return cGames.updateOne(
{
_id: game._id,
},
{
$pull: {
walls: wall._id,
},
},
);
})
.then(() => {
res.sendStatus(200);
})
.catch((err) => {
console.error(err);
res.sendStatus(500);
});
}
/**
*
* @param {ObjectId} _id
*/
function deleteGame(_id) {
return cGames
.findOne({ _id })
.then((game) => {
let wallDeletions = [];
for (const wallId of game.walls) {
wallDeletions.push(deleteWall(wallId));
}
return Promise.all(wallDeletions);
})
.then(() => {
return cGames.deleteOne({ _id });
});
}
/**
*
* @param {ObjectId} _id
*/
function deleteWall(_id) {
return cWalls
.findOne({ _id })
.then((wall) => {
let categoryDeletions = [];
for (const catId of wall.categories) {
categoryDeletions.push(deleteCategory(catId));
}
return Promise.all(categoryDeletions);
})
.then(() => {
return cWalls.deleteOne({ _id: _id });
});
}
/**
*
* @param {ObjectId} _id
*/
function deleteCategory(_id) {
return cCategories
.findOne({
_id,
})
.then((category) => {
return cQuestions.deleteMany({
_id: {
$in: category.questions,
},
});
})
.then(() => {
return cCategories.deleteOne({
_id,
});
});
}