diff --git a/src/stories/hubbles_law/database.ts b/src/stories/hubbles_law/database.ts index 8e8c1a7..65fad45 100644 --- a/src/stories/hubbles_law/database.ts +++ b/src/stories/hubbles_law/database.ts @@ -1,5 +1,5 @@ import { Attributes, FindOptions, Op, QueryTypes, Sequelize, WhereAttributeHash, WhereOptions, col, fn, literal } from "sequelize"; -import { AsyncMergedHubbleStudentClasses, Galaxy, HubbleMeasurement, SampleHubbleMeasurement, SyncMergedHubbleClasses } from "./models"; +import { AsyncMergedHubbleStudentClasses, Galaxy, HubbleMeasurement, HubbleWaitingRoomOverride, SampleHubbleMeasurement, SyncMergedHubbleClasses } from "./models"; import { classSize, findClassById, findStudentById } from "../../database"; import { RemoveHubbleMeasurementResult, SubmitHubbleMeasurementResult } from "./request_results"; import { Class, StoryState, Student, StudentsClasses } from "../../models"; @@ -848,3 +848,23 @@ export async function addClassToMergeGroup(classID: number): Promise { + return HubbleWaitingRoomOverride.findOrCreate({ + where: { + class_id: classID, + } + }) + .then(result => result[1]) + .catch((error: Error) => error); +} + +export async function removeWaitingRoomOverride(classID: number): Promise { + return HubbleWaitingRoomOverride.destroy({ + where: { + class_id: classID, + } + }) + .then(_result => true) + .catch(_error => false); +} diff --git a/src/stories/hubbles_law/router.ts b/src/stories/hubbles_law/router.ts index 0f4acc9..01db3ba 100644 --- a/src/stories/hubbles_law/router.ts +++ b/src/stories/hubbles_law/router.ts @@ -38,7 +38,9 @@ import { getClassMeasurementCount, getStudentsWithCompleteMeasurementsCount, getMergedIDsForClass, - addClassToMergeGroup + addClassToMergeGroup, + setWaitingRoomOverride, + removeWaitingRoomOverride } from "./database"; import { @@ -47,7 +49,7 @@ import { } from "./request_results"; import { Express, Router } from "express"; -import { Sequelize } from "sequelize"; +import { Sequelize, ForeignKeyConstraintError, UniqueConstraintError } from "sequelize"; import { classForStudentStory, findClassById, findStudentById } from "../../database"; import { initializeModels } from "./models"; import { setUpHubbleAssociations } from "./associations"; @@ -553,6 +555,94 @@ router.get("/spectra/:type/:name", async (req, res) => { }); +const WaitingRoomOverrideSchema = S.struct({ + class_id: S.number.pipe(S.int()), +}); + +router.put("/waiting-room-override", async (req, res) => { + const body = req.body; + const maybe = S.decodeUnknownEither(WaitingRoomOverrideSchema)(body); + if (Either.isLeft(maybe)) { + res.status(400).json({ + error: "Invalid format. Request body should have the form { class_id: }", + }); + return; + } + + const right = maybe.right; + const result = await setWaitingRoomOverride(right.class_id); + const success = !(result instanceof Error); + const responseData = { + success, + class_id: right.class_id, + }; + if (!success) { + if (result instanceof ForeignKeyConstraintError) { + res.status(404).json({ + ...responseData, + error: `No class found with ID ${right.class_id}`, + }); + + // It's fine if the override already exists + } else if (result instanceof UniqueConstraintError) { + res.status(200).json({ + class_id: right.class_id, + success: true, + message: `The waiting room override for class ${right.class_id} was already set`, + }); + } else { + res.status(500).json({ + ...responseData, + error: `An error occurred while setting the waiting room override for class ${right.class_id}`, + }); + } + return; + } + + if (result) { + res.status(201).json({ + ...responseData, + message: `Successfully set waiting room override for class ${right.class_id}`, + }); + } else { + res.status(200).json({ + message: `The waiting room override for class ${right.class_id} was already set`, + }); + } +}); + + +router.delete("/waiting-room-override", async (req, res) => { + const body = req.body; + const maybe = S.decodeUnknownEither(WaitingRoomOverrideSchema)(body); + if (Either.isLeft(maybe)) { + res.status(400).json({ + error: "Invalid format. Request body should have the form { class_id: }", + }); + return; + } + + const right = maybe.right; + const success = await removeWaitingRoomOverride(right.class_id); + const responseData = { + success, + class_id: right.class_id, + }; + if (!success) { + res.status(500).json({ + ...responseData, + error: `An error occurred while removing the waiting room override for class ${right.class_id}`, + }); + return; + } + + res.json({ + ...responseData, + message: `The waiting room override for class ${right.class_id} was removed, if one existed.`, + }); +}); + + /** These endpoints are specifically for the spectrum-checking branch */ router.get("/unchecked-galaxies", async (_req, res) => {