From 8a8bc5a6ed75cd45cf4057a5bacc269c274d10d8 Mon Sep 17 00:00:00 2001 From: Dave Richer Date: Tue, 6 May 2025 13:53:40 -0400 Subject: [PATCH] feature/IO-3225-Notifications-1.5: Final Refactoring / Optimization --- server/graphql-client/queries.js | 65 ++++++++----------------- server/notifications/autoAddWatchers.js | 41 +++++++--------- 2 files changed, 38 insertions(+), 68 deletions(-) diff --git a/server/graphql-client/queries.js b/server/graphql-client/queries.js index 56909d9b0..d61d814b9 100644 --- a/server/graphql-client/queries.js +++ b/server/graphql-client/queries.js @@ -9,6 +9,7 @@ query FIND_BODYSHOP_BY_MESSAGING_SERVICE_SID($mssid: String!, $phone: String!) { } }`; +// Unused exports.GET_JOB_BY_RO_NUMBER = ` query GET_JOB_BY_RO_NUMBER($ro_number: String!) { jobs(where:{ro_number:{_eq:$ro_number}}) { @@ -1773,6 +1774,7 @@ exports.QUERY_JOB_COSTING_DETAILS_MULTI = ` query QUERY_JOB_COSTING_DETAILS_MULT } }`; +// Exists in Commented out Query exports.INSERT_IOEVENT = ` mutation INSERT_IOEVENT($event: ioevents_insert_input!) { insert_ioevents_one(object: $event) { id @@ -2765,17 +2767,6 @@ query GET_JOB_WATCHERS($jobid: uuid!) { } `; -exports.GET_JOB_WATCHERS_MINIMAL = ` - query GET_JOB_WATCHERS_MINIMAL($jobid: uuid!) { - job_watchers(where: { jobid: { _eq: $jobid } }) { - user_email - user { - authid - } - } - } -`; - exports.GET_NOTIFICATION_ASSOCIATIONS = ` query GET_NOTIFICATION_ASSOCIATIONS($emails: [String!]!, $shopid: uuid!) { associations(where: { @@ -2941,8 +2932,16 @@ exports.INSERT_NEW_DOCUMENT = ` } `; -exports.GET_AUTOADD_NOTIFICATION_USERS = ` - query GET_AUTOADD_NOTIFICATION_USERS($shopId: uuid!) { +exports.INSERT_JOB_WATCHERS = ` + mutation INSERT_JOB_WATCHERS($watchers: [job_watchers_insert_input!]!) { + insert_job_watchers(objects: $watchers, on_conflict: { constraint: job_watchers_pkey, update_columns: [] }) { + affected_rows + } + } +`; + +exports.GET_NOTIFICATION_WATCHERS = ` + query GET_NOTIFICATION_WATCHERS($shopId: uuid!, $employeeIds: [uuid!]!) { associations(where: { _and: [ { shopid: { _eq: $shopId } }, @@ -2953,43 +2952,19 @@ exports.GET_AUTOADD_NOTIFICATION_USERS = ` id useremail } - } -`; - -exports.INSERT_JOB_WATCHERS = ` - mutation INSERT_JOB_WATCHERS($watchers: [job_watchers_insert_input!]!) { - insert_job_watchers(objects: $watchers) { - affected_rows - returning { - user_email - } - } - } -`; - -exports.GET_NOTIFICATION_ASSOCIATIONS_BY_IDS = ` - query GET_NOTIFICATION_ASSOCIATIONS_BY_IDS($associationIds: [uuid!]!, $shopid: uuid!) { - associations(where: { id: { _in: $associationIds }, shopid: { _eq: $shopid }, active: { _eq: true } }) { - id - useremail - } - } -`; - -exports.GET_EMPLOYEE_EMAILS = ` - query GET_EMPLOYEE_EMAILS($employeeIds: [uuid!]!, $shopid: uuid!) { - employees(where: { id: { _in: $employeeIds }, shopid: { _eq: $shopid }, active: { _eq: true } }) { - id + employees(where: { id: { _in: $employeeIds }, shopid: { _eq: $shopId }, active: { _eq: true } }) { user_email } } `; -exports.GET_NOTIFICATION_ASSOCIATIONS_BY_EMAILS = ` - query GET_NOTIFICATION_ASSOCIATIONS_BY_EMAILS($emails: [String!]!, $shopid: uuid!) { - associations(where: { useremail: { _in: $emails }, shopid: { _eq: $shopid }, active: { _eq: true } }) { - id - useremail +exports.GET_JOB_WATCHERS_MINIMAL = ` + query GET_JOB_WATCHERS_MINIMAL($jobid: uuid!) { + job_watchers(where: { jobid: { _eq: $jobid } }) { + user_email + user { + authid + } } } `; diff --git a/server/notifications/autoAddWatchers.js b/server/notifications/autoAddWatchers.js index e302610ea..e2579cffd 100644 --- a/server/notifications/autoAddWatchers.js +++ b/server/notifications/autoAddWatchers.js @@ -10,8 +10,7 @@ const { client: gqlClient } = require("../graphql-client/graphql-client"); const { isEmpty } = require("lodash"); const { GET_JOB_WATCHERS_MINIMAL, - GET_AUTOADD_NOTIFICATION_USERS, - GET_EMPLOYEE_EMAILS, + GET_NOTIFICATION_WATCHERS, INSERT_JOB_WATCHERS } = require("../graphql-client/queries"); @@ -53,33 +52,30 @@ const autoAddWatchers = async (req) => { const bodyshopData = await getBodyshopFromRedis(shopId); const notificationFollowers = bodyshopData?.notification_followers || []; - // Fetch auto-add users from associations - const autoAddData = await gqlClient.request(GET_AUTOADD_NOTIFICATION_USERS, { shopId }); + // Execute queries in parallel + const [notificationData, existingWatchersData] = await Promise.all([ + gqlClient.request(GET_NOTIFICATION_WATCHERS, { + shopId, + employeeIds: notificationFollowers.filter((id) => id) + }), + gqlClient.request(GET_JOB_WATCHERS_MINIMAL, { jobid: jobId }) + ]); // Get users with notifications_autoadd: true const autoAddUsers = - autoAddData?.associations?.map((assoc) => ({ + notificationData?.associations?.map((assoc) => ({ email: assoc.useremail, associationId: assoc.id })) || []; - // Get users from notification_followers (array of employee IDs) - let followerEmails = []; - if (notificationFollowers.length > 0) { - const validFollowers = notificationFollowers.filter((id) => id); // Remove null values - if (validFollowers.length > 0) { - const employeeData = await gqlClient.request(GET_EMPLOYEE_EMAILS, { - employeeIds: validFollowers, - shopid: shopId - }); - followerEmails = employeeData.employees - .filter((e) => e.user_email) - .map((e) => ({ - email: e.user_email, - associationId: null - })); - } - } + // Get users from notification_followers + const followerEmails = + notificationData?.employees + ?.filter((e) => e.user_email) + ?.map((e) => ({ + email: e.user_email, + associationId: null + })) || []; // Combine and deduplicate emails (use email as the unique key) const usersToAdd = [...autoAddUsers, ...followerEmails].reduce((acc, user) => { @@ -94,7 +90,6 @@ const autoAddWatchers = async (req) => { } // Check existing watchers to avoid duplicates - const existingWatchersData = await gqlClient.request(GET_JOB_WATCHERS_MINIMAL, { jobid: jobId }); const existingWatcherEmails = existingWatchersData?.job_watchers?.map((w) => w.user_email) || []; // Filter out already existing watchers and optionally the user who created the job