From b0e48103968f3f3267bdc45bd40c98786f31f2a3 Mon Sep 17 00:00:00 2001 From: Dlurak <84224239+Dlurak@users.noreply.github.com> Date: Tue, 9 Apr 2024 13:17:52 +0200 Subject: [PATCH] Implement a endpoint to update an assignment --- src/routes/assignments/index.ts | 4 +- src/routes/assignments/update.ts | 107 +++++++++++++++++++++++++++++++ src/utils/arrays/truthy.ts | 18 ++++++ 3 files changed, 128 insertions(+), 1 deletion(-) create mode 100644 src/routes/assignments/update.ts create mode 100644 src/utils/arrays/truthy.ts diff --git a/src/routes/assignments/index.ts b/src/routes/assignments/index.ts index 9d9aae3..130a47d 100644 --- a/src/routes/assignments/index.ts +++ b/src/routes/assignments/index.ts @@ -2,8 +2,10 @@ import Elysia from "elysia"; import { createAssignment } from "./create"; import { deleteAssignment } from "./delete"; import { listAssignments } from "./list"; +import { updateAssignment } from "./update"; export const assignmentsRouter = new Elysia({ prefix: "/assignments" }) .use(listAssignments) .use(createAssignment) - .use(deleteAssignment); + .use(deleteAssignment) + .use(updateAssignment); diff --git a/src/routes/assignments/update.ts b/src/routes/assignments/update.ts new file mode 100644 index 0000000..aec82ab --- /dev/null +++ b/src/routes/assignments/update.ts @@ -0,0 +1,107 @@ +import e from "@edgedb"; +import { 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 { atLeastOneTruthy } from "utils/arrays/truthy"; +import { customDateToNormal } from "utils/dates/customAndNormal"; +import { promiseResult } from "utils/errors"; +import { responseBuilder } from "utils/response"; +import { savePredicate } from "utils/undefined"; + +const successResponse = responseBuilder("success", { + message: "Successfully updated assignment", + data: null, +}); + +export const updateAssignment = new Elysia() + .use(HttpStatusCode()) + .use(auth) + .patch( + "/:id", + async ({ httpStatus, set, auth, params, body }) => { + if (!auth.isAuthorized) { + set.status = httpStatus.HTTP_401_UNAUTHORIZED; + return UNAUTHORIZED; + } + + const due = savePredicate(body.dueDate, customDateToNormal); + const from = savePredicate(body.fromDate, customDateToNormal); + const { subject, description } = body; + + const atLeastOneTruthyInput = atLeastOneTruthy([ + due, + from, + subject, + description, + ]); + if (!atLeastOneTruthyInput) { + return successResponse; + } + + const query = e.update(e.Assignment, (a) => ({ + filter_single: e.op( + e.op(a.id, "=", e.cast(e.uuid, params.id)), + "and", + e.op(auth.username, "in", a.class.students.username), + ), + set: { + updates: { + "+=": e.insert(e.Change, { + user: e.select(e.User, (u) => ({ + filter_single: e.op(u.username, "=", auth.username), + })), + }), + }, + subject: subject ?? a.subject, + description: description ?? a.description, + dueDate: due ?? a.dueDate, + fromDate: from ?? a.fromDate, + }, + })); + const result = await promiseResult(() => query.run(client)); + + if (result.isError) { + set.status = httpStatus.HTTP_500_INTERNAL_SERVER_ERROR; + return DATABASE_WRITE_FAILED; + } + if (!result.data) { + set.status = httpStatus.HTTP_404_NOT_FOUND; + return responseBuilder("error", { + error: "Homework not found in any of your classes", + }); + } + + return successResponse; + }, + { + body: t.Object({ + subject: t.Optional( + t.String({ + minLength: 1, + examples: ["Computer Science", "English"], + }), + ), + description: t.Optional( + t.String({ + minLength: 1, + }), + ), + dueDate: t.Optional( + t.Object({ + day: t.Number({ minimum: 1, maximum: 31 }), + month: t.Number({ minimum: 1, maximum: 12 }), + year: t.Number({ minimum: 1970 }), + }), + ), + fromDate: t.Optional( + t.Object({ + day: t.Number({ minimum: 1, maximum: 31 }), + month: t.Number({ minimum: 1, maximum: 12 }), + year: t.Number({ minimum: 1970 }), + }), + ), + }), + }, + ); diff --git a/src/utils/arrays/truthy.ts b/src/utils/arrays/truthy.ts new file mode 100644 index 0000000..80503ae --- /dev/null +++ b/src/utils/arrays/truthy.ts @@ -0,0 +1,18 @@ +/** + * Checks if at least one truthy value exists in the array. + * @param arr - The array to be checked. + * @returns True if at least one truthy value exists, otherwise false. + * @example + * ```typescript + * // Returns true since there is at least one truthy value in the array + * atLeastOneTruthy([0, 1, false, true, '', 'hello']); + * ``` + * + * @example + * ```typescript + * // Returns false since all elements in the array are falsy + * atLeastOneTruthy([0, false, '', null, undefined]); + * ``` + */ +export const atLeastOneTruthy = (arr: unknown[]) => + arr.map((i) => !!i).some((b) => b);