diff --git a/backend/execution-worker/execute.js b/backend/execution-worker/execute.js index aa170cc..af41d2d 100644 --- a/backend/execution-worker/execute.js +++ b/backend/execution-worker/execute.js @@ -8,6 +8,10 @@ const executeFromQueue = async (message, channel) => { const { code, language, submissionId, problemStatementId, temp } = JSON.parse(message); if ( + code == "" || + language == "" || + submissionId == "" || + problemStatementId == "" || code.trim() == "" || language.trim() == "" || (submissionId.trim() == "" && !temp) || diff --git a/backend/handlers/editorial.js b/backend/handlers/editorial.js new file mode 100644 index 0000000..0d7aa73 --- /dev/null +++ b/backend/handlers/editorial.js @@ -0,0 +1,127 @@ +import { PrismaClient } from "@prisma/client"; + +const prisma = new PrismaClient(); + +const getEditorials = async (req, res) => { + const { problemStatementId } = req.params; + const editorials = await prisma.editorial.findMany({ + where: { + problemStatementId, + hidden: false, + }, + select: { + id: true, + title: true, + createdAt: true, + }, + }); + res.json({ + success: true, + message: "Editorials found succesfully", + data: { + editorials, + }, + }); +}; + +const getEditorialById = async (req, res) => { + const { problemStatementId, editorialId } = req.params; + const editorial = await prisma.editorial.findUnique({ + where: { + problemStatementId, + id: editorialId, + hidden: false, + }, + }); + if (!editorial) { + return res.status(404).json({ + success: false, + message: "Editorial not found", + data: null, + }); + } + res.json({ + success: true, + message: "Editorial found", + data: { + editorial, + }, + }); +}; + +const newEditorial = async (req, res) => { + const { problemStatementId } = req.params; + const { title, content } = req.body; + if (!title || !content || !title.trim() || !content.trim()) { + return res.status(400).json({ + success: false, + message: "Title and Content are required", + data: null, + }); + } + const successfulSubmissionCount = await prisma.submission.count({ + where: { + problemStatementId, + userId: req.user.id, + success: true, + }, + }); + if (successfulSubmissionCount == 0) { + return res.status(403).json({ + success: false, + message: + "You cannot submit an editorial without succesfully solving this problem statement", + data: null, + }); + } + const alreadySubmitted = await prisma.editorial.findFirst({ + where: { + problemStatementId, + userId: req.user.id, + hidden: false, + }, + }); + if (alreadySubmitted) { + return res.status(403).json({ + success: false, + message: "You can only submit 1 Editorial per Problem Statement", + data: null, + }); + } + var editorial; + try { + editorial = await prisma.editorial.create({ + data: { + title, + content, + problemStatementId: problemStatementId, + userId: req.user.id, + }, + }); + } catch (e) { + return res.status(500).json({ + success: false, + message: "Could not create editorial", + data: null, + }); + } + res.json({ + success: true, + message: "Editorial submitted succesfully", + data: { + id: editorial.id, + }, + }); +}; + +const deleteEditorial = async (req, res) => {}; + +const updateEditorial = async (req, res) => {}; + +export { + getEditorials, + getEditorialById, + newEditorial, + deleteEditorial, + updateEditorial, +}; diff --git a/backend/handlers/problem-statement.js b/backend/handlers/problem-statement.js index 8ee92bb..617ad09 100644 --- a/backend/handlers/problem-statement.js +++ b/backend/handlers/problem-statement.js @@ -70,12 +70,12 @@ const newProblemStatementHandler = async (req, res) => { const { title, description, difficulty, testCases } = req.body; if ( !title || - title.trim() == "" || !description || - description.trim() == "" || !difficulty || - !["Easy", "Medium", "Hard"].includes(difficulty.trim()) || !testCases || + title.trim() == "" || + description.trim() == "" || + !["Easy", "Medium", "Hard"].includes(difficulty.trim()) || testCases.length == 0 ) { return res.status(400).json({ @@ -132,12 +132,12 @@ const editProblemStatementHandler = async (req, res) => { const { title, description, difficulty, testCases } = req.body; if ( !title || - title.trim() == "" || !description || - description.trim() == "" || !difficulty || - !["Easy", "Medium", "Hard"].includes(difficulty.trim()) || !testCases || + title.trim() == "" || + description.trim() == "" || + !["Easy", "Medium", "Hard"].includes(difficulty.trim()) || testCases.length == 0 ) { return res.status(400).json({ diff --git a/backend/index.js b/backend/index.js index d7c427b..fda4393 100644 --- a/backend/index.js +++ b/backend/index.js @@ -5,6 +5,7 @@ import codeRouter from "./router/code.js"; import problemStatementRouter from "./router/problem-statement.js"; import leaderboardRouter from "./router/leaderboard.js"; import userRouter from "./router/user.js"; +import editorialsRouter from "./router/editorial.js"; import logger from "morgan"; const app = express(); @@ -23,6 +24,7 @@ app.use("/code", codeRouter); app.use("/problem-statement", problemStatementRouter); app.use("/leaderboard", leaderboardRouter); app.use("/user", userRouter); +app.use("/editorial", editorialsRouter); app.use(function (req, res, next) { res.status(404).json({ diff --git a/backend/middlewares/problem-statement.js b/backend/middlewares/problem-statement.js new file mode 100644 index 0000000..3fe696b --- /dev/null +++ b/backend/middlewares/problem-statement.js @@ -0,0 +1,28 @@ +import { PrismaClient } from "@prisma/client"; + +const prisma = new PrismaClient(); + +const checkProblemStatement = async (req, res, next) => { + const { problemStatementId } = req.params; + if (!problemStatementId) { + return res.status(400).json({ + success: false, + message: "Problem Statement Id is required", + data: null, + }); + } + const problemStatementExists = + (await prisma.problemStatement.count({ + where: { id: problemStatementId }, + })) > 0; + if (!problemStatementExists) { + return res.status(404).json({ + success: false, + message: "Problem Statement does not exist", + data: null, + }); + } + next(); +}; + +export { checkProblemStatement }; diff --git a/backend/router/auth.js b/backend/router/auth.js index d290b33..93928d8 100644 --- a/backend/router/auth.js +++ b/backend/router/auth.js @@ -9,9 +9,7 @@ import { verifyOtpHandler, } from "../handlers/auth.js"; -import { checkAuth } from "../middlewares/auth.js"; - -var router = Router(); +const router = Router(); router.post("/register", registerHandler); router.get("/verify", verifyHandler); diff --git a/backend/router/code.js b/backend/router/code.js index 6e951fa..273e496 100644 --- a/backend/router/code.js +++ b/backend/router/code.js @@ -6,7 +6,7 @@ import { aiHelperHandler, } from "../handlers/code.js"; -var router = Router(); +const router = Router(); router.post("/submit/:problemStatementId/:language", checkAuth, (req, res) => queueCodeHandler(req, res), diff --git a/backend/router/editorial.js b/backend/router/editorial.js new file mode 100644 index 0000000..5a56a23 --- /dev/null +++ b/backend/router/editorial.js @@ -0,0 +1,45 @@ +import { Router } from "express"; +import { + getEditorials, + getEditorialById, + newEditorial, + deleteEditorial, + updateEditorial, +} from "../handlers/editorial.js"; +import { checkAuth } from "../middlewares/auth.js"; +import { checkProblemStatement } from "../middlewares/problem-statement.js"; + +const router = Router(); + +router.get( + "/:problemStatementId/", + checkAuth, + checkProblemStatement, + getEditorials, +); +router.get( + "/:problemStatementId/:editorialId", + checkAuth, + checkProblemStatement, + getEditorialById, +); +router.post( + "/:problemStatementId/new", + checkAuth, + checkProblemStatement, + newEditorial, +); +router.delete( + "/:problemStatementId/:editorialId/delete", + checkAuth, + checkProblemStatement, + deleteEditorial, +); +router.put( + "/:problemStatementId/:editorialId/update", + checkAuth, + checkProblemStatement, + updateEditorial, +); + +export default router; diff --git a/backend/router/leaderboard.js b/backend/router/leaderboard.js index 86e8bd4..2db589d 100644 --- a/backend/router/leaderboard.js +++ b/backend/router/leaderboard.js @@ -5,7 +5,7 @@ import { getUserPointsHandler, } from "../handlers/leaderboard.js"; -var router = Router(); +const router = Router(); router.get("/", getLeaderboardHandler); router.get("/getUserPoints", checkAuth, getUserPointsHandler); diff --git a/backend/router/problem-statement.js b/backend/router/problem-statement.js index 90f94dc..0a230a6 100644 --- a/backend/router/problem-statement.js +++ b/backend/router/problem-statement.js @@ -8,7 +8,7 @@ import { deleteProblemStatementHandler, } from "../handlers/problem-statement.js"; -var router = Router(); +const router = Router(); router.get("/all", checkAuth, getProblemStatementsHandler); router.get("/:problemStatementId", checkAuth, getProblemStatementByIdHandler); diff --git a/backend/router/user.js b/backend/router/user.js index c50000a..84ba7b2 100644 --- a/backend/router/user.js +++ b/backend/router/user.js @@ -3,7 +3,7 @@ import { userDataHandler, getUserByIdHandler } from "../handlers/user.js"; import { checkAuth } from "../middlewares/auth.js"; -var router = Router(); +const router = Router(); router.get("/", checkAuth, userDataHandler); router.get("/:id", getUserByIdHandler);