Skip to content

Commit

Permalink
Merge pull request #48 from polyglot-edu/20-new-execution-api-concept
Browse files Browse the repository at this point in the history
20 new execution api concept
  • Loading branch information
tmaog authored May 31, 2024
2 parents 856e348 + 8c8beaa commit c77872d
Show file tree
Hide file tree
Showing 6 changed files with 202 additions and 1 deletion.
117 changes: 117 additions & 0 deletions src/controllers/course.controllers.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
import { Request, Response } from "express";
import User from "../models/user.model";
import Course from "../models/course.model";
import Flow from "../models/flow.model";

export async function createCourse(req: Request, res: Response) {
const userId = req.user?._id;
const { title, description, flowsId } = req.body;

try {
if (!userId) {
return res.status(400).send("userId is required");
}

if(!title) res.status(400).send("title is required");


if(!description) res.status(400).send("description is required");

const user = await User.findById(userId);
if (!user) {
return res.status(404).send("User not found");
}

if (await Course.findOne({ title: title })) {
return res.status(400).send("Course already exists");
}
/* IMPLEMENT THIS LATER
let flowsNotFound: string[] = [];
console.log(flowsId);
if(flowsId.length > 0){
for (const flow of flowsId) {
const dbflow = await Flow.findOne({ _id: flow });
if (!dbflow) {
flowsNotFound.push(flow);
}
}
}
if (flowsNotFound.length > 0) {
return res.status(404).send("Flows " + flowsNotFound.join(", ") + " not found");
}
*/
const course = new Course({
title: title,
description: description,
author: userId,
});

if (flowsId) for (const flow of flowsId) if (flow!=null) course.flows.push(flow);

console.log(course);
await course.save();
const courseRes = await Course.find({title: course.title})
.populate("author")
.populate("flows");

return res.status(201).json(courseRes);
} catch (err) {
console.error(err);
res.status(500).send;
}
}

export async function deleteCourse(req: Request, res: Response) {
const courseId = req.params.id;
const userId = req.user?._id;
try {
if (!userId) {
return res.status(400).send("userId is required");
}

const user = await User.findById(userId);
if (!user) {
return res.status(404).send("User not found");
}

if (!courseId) {
return res.status(404).send("courseId is required");
}

const dbcourse = await Course.findById(courseId);
if (!dbcourse) {
return res.status(404).send("Course not found");
}

if (dbcourse.author !== userId && userId != "admin") {
return res.status(403).send("You are not the author of this course");
}

await Course.deleteOne({ _id: courseId });

return res.status(204).send();
} catch (err) {
res.status(500).send;
}
}

export async function getCourses(req: Request, res: Response) {
try {
const q = req.query?.q?.toString();
const me = req.query?.me?.toString();
const query: any = q ? { title: { $regex: q, $options: "i" } } : {};

if (me) {
query.author = req.user?._id;
}

const courses = await Course.find(query)
.populate("author")
.populate("flows");
return res.json(courses);
} catch (err) {
console.error(err);
return res.status(500).send;
}
}
38 changes: 37 additions & 1 deletion src/controllers/execution.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ type GetNextExerciseV2Body = {

type ProgressBody = {
ctxId: string;
satisfiedConditions: string[];
satisfiedConditions?: string[];
flowId?: string;
authorId: string;
};
Expand Down Expand Up @@ -191,6 +191,9 @@ export async function progressExecution(
if (flow.author != authorId && authorId != "admin")
res.status(400).send("You need to be the author to unlock the progress");

if (!satisfiedConditions)
return res.status(404).send("Error satisfied conditions missing");

if (satisfiedConditions.length === 0) return res.status(200).json(null);

const algo = flow?.execution?.algo ?? "Random Execution";
Expand All @@ -213,6 +216,39 @@ export async function progressExecution(
}
}

export async function resetProgress(
req: Request<{}, any, ProgressBody>,
res: Response,
next: NextFunction,
) {
const { ctxId, satisfiedConditions, authorId } = req.body;
try {
const ctx = ctxs[ctxId];

if (!ctx) {
return res.status(400).json({ error: "Ctx not found!" });
}

const flow = await PolyglotFlowModel.findById(ctx.flowId).populate([
"nodes",
"edges",
]);

if (!flow) return res.status(404).send();

if (flow.author != authorId && authorId != "admin")
res.status(400).send("You need to be the author to unlock the progress");

//delete context with ctxId==ctx
//idea: ctxs[ctxId] remove
// Object.entries(ctxs).splice()

return res.status(200).send("Execution resetted correctly");
} catch (err) {
next(err);
}
}

export async function getNextExercisev2(
req: Request<{}, any, GetNextExerciseV2Body>,
res: Response,
Expand Down
30 changes: 30 additions & 0 deletions src/models/course.model.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import mongoose, { Document } from "mongoose";
import { v4 as uuidv4 } from "uuid";
import validator from "validator";

export type CourseDocument = Document & {
title: string;
description: string;
author: string;
flows: string[];
};

const courseSchema = new mongoose.Schema<CourseDocument>({
_id: {
type: String,
required: true,
default: () => uuidv4(),
validate: {
validator: (id: string) => validator.isUUID(id),
message: "Invalid UUID-v4",
},
},
title: { type: String, required: true },
description: { type: String, required: true },
author: { type: String, required: true, ref: "User" },
flows: [{ type: String, ref: "Flow" }],
});

const Course = mongoose.model<CourseDocument>("Course", courseSchema);

export default Course;
15 changes: 15 additions & 0 deletions src/routes/course.routes.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import express from "express";
import { checkAuth } from "../middlewares/auth.middleware";
import * as CourseController from "../controllers/course.controllers";

const router = express.Router();
// cambiare tutto con flow

router.route("/:id").delete(checkAuth, CourseController.deleteCourse);
router
.route("/")
.post(checkAuth, CourseController.createCourse)
.get(checkAuth, CourseController.getCourses);

// get enrolled courses
export default router;
1 change: 1 addition & 0 deletions src/routes/execution.routes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ router.post("/actual", ExecutionController.getActualNode);
router.post("/next", ExecutionController.getNextExercisev2);
router.post("/progressInfo", ExecutionController.getFlowCtxs);
router.post("/progressAction", ExecutionController.progressExecution);
router.post("/resetProgress", ExecutionController.progressExecution);
router.post("/cmd", ExecutionController.sendCommand);

// router.post("/next", ExecutionController.getNextExercise)
Expand Down
2 changes: 2 additions & 0 deletions src/routes/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import express from "express";
import flowRouter from "./flows.routes";
import courseRouter from "./course.routes";
import executionRouter from "./execution.routes";
import userRouter from "./user.routes";
import searchRouter from "./search.routes";
Expand All @@ -10,6 +11,7 @@ import conceptRouter from "./concept.routes";
const router = express.Router();

router.use("/api/flows", flowRouter);
router.use("/api/course", courseRouter);
router.use("/api/execution", executionRouter);
router.use("/api/user", userRouter);
router.use("/api/search", searchRouter);
Expand Down

0 comments on commit c77872d

Please sign in to comment.