Skip to content

Commit

Permalink
Merge pull request #126 from Carifio24/stages
Browse files Browse the repository at this point in the history
Add endpoints for getting stages and stage states
  • Loading branch information
Carifio24 authored Aug 28, 2024
2 parents f14e1f4 + 72aeb3f commit 5faf3f1
Show file tree
Hide file tree
Showing 5 changed files with 140 additions and 1 deletion.
27 changes: 27 additions & 0 deletions src/database.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ import { initializeModels } from "./models";
import { StudentOption, StudentOptions } from "./models/student_options";
import { Question } from "./models/question";
import { logger } from "./logger";
import { Stage } from "./models/stage";

type SequelizeError = { parent: { code: string } };

Expand Down Expand Up @@ -337,6 +338,19 @@ export async function getAllEducators(): Promise<Educator[]> {
return Educator.findAll();
}

export async function getStory(storyName: string): Promise<Story | null> {
return Story.findOne({ where: { name: storyName } });
}

export async function getStages(storyName: string): Promise<Stage[]> {
return Stage.findAll({
where: {
story_name: storyName,
},
order: [["stage_index", "ASC"]],
});
}

export async function getStoryState(studentID: number, storyName: string): Promise<JSON | null> {
const result = await StoryState.findOne({
where: {
Expand Down Expand Up @@ -427,6 +441,19 @@ export async function deleteStageState(studentID: number, storyName: string, sta
});
}

export async function getStageStates(studentID: number, storyName: string): Promise<Record<string, JSON>> {
const stages = await getStages(storyName);
const stageNames = stages.map(stage => stage.stage_name);
const stageStates: Record<string, JSON> = {};
for (const name of stageNames) {
const state = await getStageState(studentID, storyName, name);
if (state !== null) {
stageStates[name] = state;
}
}
return stageStates;
}

export async function getClassesForEducator(educatorID: number): Promise<Class[]> {
return Class.findAll({
where: {
Expand Down
3 changes: 3 additions & 0 deletions src/models/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { Educator, initializeEducatorModel } from "./educator";
import { IgnoreStudent, initializeIgnoreStudentModel } from "./ignore_student";
import { ClassStories, initializeClassStoryModel } from "./story_class";
import { CosmicDSSession, initializeSessionModel } from "./session";
import { Stage, initializeStageModel } from "./stage";
import { StageState, initializeStageStateModel } from "./stage_state";
import { StoryState, initializeStoryStateModel } from "./story_state";
import { Story, initializeStoryModel } from "./story";
Expand All @@ -23,6 +24,7 @@ export {
DummyClass,
Educator,
IgnoreStudent,
Stage,
StageState,
Story,
StoryState,
Expand All @@ -38,6 +40,7 @@ export function initializeModels(db: Sequelize) {
initializeStoryModel(db);
initializeClassStoryModel(db);
initializeDummyClassModel(db);
initializeStageModel(db);
initializeStageStateModel(db);
initializeStoryStateModel(db);
initializeStudentClassModel(db);
Expand Down
52 changes: 52 additions & 0 deletions src/models/stage.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import { Sequelize, DataTypes, Model, InferAttributes, InferCreationAttributes, CreationOptional } from "sequelize";
import { Story } from "./story";


export class Stage extends Model<InferAttributes<Stage>, InferCreationAttributes<Stage>> {
declare story_name: string;
declare stage_name: string;
declare stage_index: CreationOptional<number | null>;
}

export function initializeStageModel(sequelize: Sequelize) {
Stage.init({
story_name: {
type: DataTypes.STRING,
allowNull: false,
unique: true,
primaryKey: true,
},
stage_name: {
type: DataTypes.STRING,
allowNull: false,
unique: true,
primaryKey: true,
references: {
model: Story,
key: "name",
}
},
stage_index: {
type: DataTypes.INTEGER.UNSIGNED,
allowNull: true,
defaultValue: null,
}
}, {
sequelize,
engine: "InnoDB",
indexes: [
{
unique: true,
fields: ["story_name", "stage_name"],
},
{
unique: true,
fields: ["story_name"],
},
{
unique: true,
fields: ["stage_name"],
},
]
});
}
46 changes: 45 additions & 1 deletion src/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@ import {
updateStageState,
deleteStageState,
findClassById,
getStages,
getStory,
getStageStates,
} from "./database";

import { getAPIKey, hasPermission } from "./authorization";
Expand All @@ -44,7 +47,7 @@ import {
VerificationResult,
} from "./request_results";

import { CosmicDSSession, StageState } from "./models";
import { CosmicDSSession } from "./models";

import { ParsedQs } from "qs";
import express, { Request, Response as ExpressResponse, NextFunction } from "express";
Expand Down Expand Up @@ -462,6 +465,47 @@ app.put("/story-state/:studentID/:storyName", async (req, res) => {
});
});

app.get("/stages/:storyName", async (req, res) => {
const storyName = req.params.storyName;
const story = await getStory(storyName);

if (story === null) {
res.status(404).json({
error: `No story found with name ${storyName}`
});
return;
}

const stages = await getStages(req.params.storyName);
res.json({
stages,
});
});

app.get("/stage-states/:studentID/:storyName", async (req, res) => {
const storyName = req.params.storyName;
const story = await getStory(storyName);

if (story === null) {
res.status(404).json({
error: `No story found with name ${storyName}`
});
return;
}

const studentID = Number(req.params.studentID);
const student = await findStudentById(studentID);
if (student === null) {
res.status(404).json({
error: `No student found with ID ${studentID}`
});
return;
}

const stageStates = await getStageStates(studentID, storyName);
res.json(stageStates);
});

app.get("/stage-state/:studentID/:storyName/:stageName", async (req, res) => {
const params = req.params;
const studentID = Number(params.studentID);
Expand Down
13 changes: 13 additions & 0 deletions src/sql/create_stage_table.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
CREATE TABLE Stages (
story_name varchar(50) NOT NULL,
stage_name varchar(50) NOT NULL,
stage_index int(11) UNSIGNED DEFAULT NULL,

PRIMARY KEY(story_name, stage_name),
INDEX(story_name),
INDEX(stage_name),
FOREIGN KEY(story_name)
REFERENCES Stories(name)
ON UPDATE CASCADE
ON DELETE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=0 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci PACK_KEYS=0;

0 comments on commit 5faf3f1

Please sign in to comment.