From 987f0c9081b1aa2f61153f34cf0057c5b895e31a Mon Sep 17 00:00:00 2001 From: Daniel Hougaard <62331820+DanielHougaard@users.noreply.github.com> Date: Fri, 19 Jan 2024 00:24:54 +0400 Subject: [PATCH] Added secret reminder service --- .../src/services/secret-reminder/index.ts | 1 + .../secret-reminder-service.ts | 101 ++++++++++++++++++ 2 files changed, 102 insertions(+) create mode 100644 backend-pg/src/services/secret-reminder/index.ts create mode 100644 backend-pg/src/services/secret-reminder/secret-reminder-service.ts diff --git a/backend-pg/src/services/secret-reminder/index.ts b/backend-pg/src/services/secret-reminder/index.ts new file mode 100644 index 000000000..ffd4ed90c --- /dev/null +++ b/backend-pg/src/services/secret-reminder/index.ts @@ -0,0 +1 @@ +export { secretReminderServiceFactory } from "./secret-reminder-service"; diff --git a/backend-pg/src/services/secret-reminder/secret-reminder-service.ts b/backend-pg/src/services/secret-reminder/secret-reminder-service.ts new file mode 100644 index 000000000..a1ccb9b93 --- /dev/null +++ b/backend-pg/src/services/secret-reminder/secret-reminder-service.ts @@ -0,0 +1,101 @@ +import { BadRequestError } from "@app/lib/errors"; +import { logger } from "@app/lib/logger"; + +import { TSecretReminderQueueFactory } from "./secret-reminder-queue"; +import { + TCreateSecretReminderDTO, + TDeleteSecretReminderDTO, + THandleReminderDTO +} from "./secret-reminder-types"; + +type TSecretReminderServiceFactoryDep = { + secretReminderQueue: TSecretReminderQueueFactory; +}; + +export type TSecretReminderServiceFactory = ReturnType; + +export const secretReminderServiceFactory = ({ + secretReminderQueue +}: TSecretReminderServiceFactoryDep) => { + const createReminder = async ({ oldSecret, newSecret, projectId }: TCreateSecretReminderDTO) => { + try { + if (oldSecret.id !== newSecret.id) { + throw new BadRequestError({ + name: "SecretReminderIdMismatch", + message: "Existing secret didn't match the updated secret ID." + }); + } + + if (!newSecret.secretReminderRepeatDays) { + throw new BadRequestError({ + name: "SecretReminderRepeatDaysMissing", + message: "Secret reminder repeat days is missing." + }); + } + + // If the secret already has a reminder, we should remove the existing one first. + if (oldSecret.secretReminderRepeatDays) { + await secretReminderQueue.removeFromQueue(oldSecret.id, oldSecret.secretReminderRepeatDays); + } + + await secretReminderQueue.addToQueue({ + note: newSecret.secretReminderNote, + projectId, + repeatDays: newSecret.secretReminderRepeatDays, + secretId: newSecret.id + }); + } catch (err) { + logger.error(err, "Failed to create secret reminder."); + throw new BadRequestError({ + name: "SecretReminderCreateFailed", + message: "Failed to create secret reminder." + }); + } + }; + + const deleteReminder = async ({ secretId, repeatDays }: TDeleteSecretReminderDTO) => { + try { + await secretReminderQueue.removeFromQueue(secretId, repeatDays); + } catch (err) { + logger.error(err, "Failed to remove secret reminder from queue."); + throw new BadRequestError({ + name: "SecretReminderDeleteFailed", + message: "Failed to delete secret reminder." + }); + } + }; + + // A handler function to cut down on code duplication in the future. + const handleReminder = async ({ newSecret, oldSecret, projectId }: THandleReminderDTO) => { + const { secretReminderRepeatDays, secretReminderNote } = newSecret; + + if (newSecret.type !== "personal" && secretReminderRepeatDays !== undefined) { + if ( + (secretReminderRepeatDays && + oldSecret.secretReminderRepeatDays !== secretReminderRepeatDays) || + (secretReminderNote && oldSecret.secretReminderNote !== secretReminderNote) + ) { + await createReminder({ + oldSecret, + newSecret, + projectId + }); + } else if ( + secretReminderRepeatDays === null && + secretReminderNote === null && + oldSecret.secretReminderRepeatDays + ) { + await deleteReminder({ + secretId: oldSecret.id, + repeatDays: oldSecret.secretReminderRepeatDays + }); + } + } + }; + + return { + createReminder, + deleteReminder, + handleReminder + }; +};