Skip to content

Commit

Permalink
Add a endpoint to accept/reject a request
Browse files Browse the repository at this point in the history
  • Loading branch information
Dlurak committed Mar 31, 2024
1 parent 1cc4224 commit 7ca7476
Show file tree
Hide file tree
Showing 3 changed files with 138 additions and 1 deletion.
1 change: 1 addition & 0 deletions dbschema/default.esdl
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ module default {
required name: str;

multi students: User {
# Not used - may be removed
joinedAt: datetime {
default := datetime_current();
readonly := true;
Expand Down
4 changes: 3 additions & 1 deletion src/routes/moderation/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@ import Elysia from "elysia";
import { createJoinRequest } from "./create";
import { listJoinRequests } from "./list";
import { ownJoinRequest } from "./own";
import { reviewJoinRequest } from "./review";

export const moderationRouter = new Elysia({ prefix: "/mod" })
.use(ownJoinRequest("/own"))
.use(createJoinRequest)
.use(listJoinRequests);
.use(listJoinRequests)
.use(reviewJoinRequest);
134 changes: 134 additions & 0 deletions src/routes/moderation/review.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
import e from "@edgedb";
import {
DATABASE_READ_FAILED,
DATABASE_WRITE_FAILED,
UNAUTHORIZED,
} from "constants/responses";
import Elysia, { t } from "elysia";
import { HttpStatusCode } from "elysia-http-status-code";
import { client } from "index";
import { auth } from "plugins/auth";
import { promiseResult } from "utils/errors";
import { responseBuilder } from "utils/response";

export const reviewJoinRequest = new Elysia()
.use(auth)
.use(HttpStatusCode())
.patch(
"/:id",
async ({ auth, httpStatus, set, params, body }) => {
if (!auth.isAuthorized) {
set.status = httpStatus.HTTP_401_UNAUTHORIZED;
return UNAUTHORIZED;
}

const idAsId = e.cast(e.uuid, params.id);

const currentStatusQuery = e.select(e.JoinRequest, (jr) => {
const idMatches = e.op(jr.id, "=", idAsId);
return {
filter_single: idMatches,
status: true,
user: () => ({ username: true }),
wantsToJoin: () => ({ id: true }),
};
});
const currentStatusResult = await promiseResult(() =>
currentStatusQuery.run(client),
);
if (currentStatusResult.isError) {
set.status = httpStatus.HTTP_500_INTERNAL_SERVER_ERROR;
return DATABASE_READ_FAILED;
}
if (!currentStatusResult.data) {
set.status = httpStatus.HTTP_404_NOT_FOUND;
return responseBuilder("error", {
error: "This request doesn't exist",
});
}
if (currentStatusResult.data.status !== "Pending") {
set.status = httpStatus.HTTP_404_NOT_FOUND;
return responseBuilder("error", {
error: "This request is already proccessed",
});
}

const updateQuery = e.update(e.JoinRequest, (jr) => {
const idMatches = e.op(jr.id, "=", idAsId);
const userIsPriviliged = e.op(
jr.wantsToJoin.students.username,
"=",
auth.username,
);

return {
filter_single: e.op(idMatches, "and", userIsPriviliged),
set: {
status: body.status,
reviewedAt: new Date(),
reviewedBy: e.select(e.User, (u) => ({
filter_single: e.op(u.username, "=", auth.username),
})),
},
};
});
const result = await promiseResult(() => updateQuery.run(client));

if (result.isError) {
set.status = httpStatus.HTTP_500_INTERNAL_SERVER_ERROR;
return DATABASE_WRITE_FAILED;
}
if (!result.data) {
set.status = httpStatus.HTTP_403_FORBIDDEN;
return responseBuilder("error", {
error: "You don't have the rights to review this request",
});
}

const isAccepted = body.status === "Accepted";
if (!isAccepted) {
return responseBuilder("success", {
message: "Sucessfully rejected",
data: null,
});
}

// TODO: Put this into one transaction together with `updateQuery`
const updateClassQuery = e.update(e.Class, (c) => {
const classIdAsId = e.cast(
e.uuid,
currentStatusResult.data?.wantsToJoin.id || "",
);
const studentName = currentStatusResult.data?.user.username || "";

return {
filter_single: e.op(c.id, "=", classIdAsId),
set: {
students: {
"+=": e.select(e.User, (u) => ({
filter_single: e.op(u.username, "=", studentName),
})),
},
},
};
});
const updateClassResult = await promiseResult(() =>
updateClassQuery.run(client),
);
if (updateClassResult.isError) {
// In this case the status is already changed but the user isn't a student of the class :/
set.status = httpStatus.HTTP_500_INTERNAL_SERVER_ERROR;
return DATABASE_WRITE_FAILED;
}

return responseBuilder("success", {
message: "Successfully accepted",
data: null,
});
},
{
body: t.Object({
status: t.Union([t.Literal("Accepted"), t.Literal("Rejected")]),
}),
},
);

0 comments on commit 7ca7476

Please sign in to comment.