From e2e5f3f8856ce43089440cc1aceaaee399a243af Mon Sep 17 00:00:00 2001 From: Dave Richer Date: Thu, 9 Jan 2025 13:28:56 -0800 Subject: [PATCH 1/3] feature/IO-3060-Realtime-Notifications-System - Add handlers for Job and Bill Change / Register Routers - Add Tables / Modify Tables / Add permissions. --- hasura/metadata/tables.yaml | 165 ++++++++++++++++++ .../down.sql | 4 + .../up.sql | 2 + .../down.sql | 1 + .../up.sql | 2 + .../down.sql | 3 + .../up.sql | 1 + .../down.sql | 4 + .../up.sql | 2 + .../down.sql | 1 + .../up.sql | 2 + .../eventHandlers/handeJobChange.js | 5 + .../eventHandlers/handleBillChange.js | 5 + server/routes/notificationsRoutes.js | 15 +- 14 files changed, 208 insertions(+), 4 deletions(-) create mode 100644 hasura/migrations/1736452866094_alter_table_public_associations_add_column_notification_settings/down.sql create mode 100644 hasura/migrations/1736452866094_alter_table_public_associations_add_column_notification_settings/up.sql create mode 100644 hasura/migrations/1736455300329_create_table_public_notifications/down.sql create mode 100644 hasura/migrations/1736455300329_create_table_public_notifications/up.sql create mode 100644 hasura/migrations/1736457116827_alter_table_public_notifications_drop_column_scenario/down.sql create mode 100644 hasura/migrations/1736457116827_alter_table_public_notifications_drop_column_scenario/up.sql create mode 100644 hasura/migrations/1736457173242_alter_table_public_notifications_add_column_scenario/down.sql create mode 100644 hasura/migrations/1736457173242_alter_table_public_notifications_add_column_scenario/up.sql create mode 100644 hasura/migrations/1736457615046_create_table_public_job_watchers/down.sql create mode 100644 hasura/migrations/1736457615046_create_table_public_job_watchers/up.sql create mode 100644 server/notifications/eventHandlers/handeJobChange.js create mode 100644 server/notifications/eventHandlers/handleBillChange.js diff --git a/hasura/metadata/tables.yaml b/hasura/metadata/tables.yaml index 240b218a4..d7ddeb768 100644 --- a/hasura/metadata/tables.yaml +++ b/hasura/metadata/tables.yaml @@ -207,6 +207,7 @@ - default_prod_list_view - id - kanban_settings + - notification_settings - qbo_realmId - shopid - useremail @@ -222,6 +223,7 @@ - authlevel - default_prod_list_view - kanban_settings + - notification_settings - qbo_realmId filter: user: @@ -2805,6 +2807,80 @@ _eq: X-Hasura-User-Id - active: _eq: true +- table: + name: job_watchers + schema: public + object_relationships: + - name: job + using: + foreign_key_constraint_on: job_id + - name: user + using: + foreign_key_constraint_on: user_email + insert_permissions: + - role: user + permission: + check: + user: + _and: + - associations: + active: + _eq: true + - authid: + _eq: X-Hasura-User-Id + columns: + - user_email + - created_at + - id + - job_id + comment: "" + select_permissions: + - role: user + permission: + columns: + - user_email + - created_at + - id + - job_id + filter: + user: + _and: + - associations: + active: + _eq: true + - authid: + _eq: X-Hasura-User-Id + comment: "" + update_permissions: + - role: user + permission: + columns: + - user_email + - created_at + - id + - job_id + filter: + user: + _and: + - associations: + active: + _eq: true + - authid: + _eq: X-Hasura-User-Id + check: null + comment: "" + delete_permissions: + - role: user + permission: + filter: + user: + _and: + - associations: + active: + _eq: true + - authid: + _eq: X-Hasura-User-Id + comment: "" - table: name: joblines schema: public @@ -4669,6 +4745,95 @@ _eq: X-Hasura-User-Id - active: _eq: true +- table: + name: notifications + schema: public + object_relationships: + - name: association + using: + foreign_key_constraint_on: association_id + - name: job + using: + foreign_key_constraint_on: job_id + insert_permissions: + - role: user + permission: + check: + association: + _and: + - active: + _eq: true + - user: + authid: + _eq: X-Hasura-User-Id + columns: + - association_id + - created_at + - fcm_data + - fcm_message + - fcm_title + - id + - job_id + - meta + - read + - scenario + - ui_translation_meta + - ui_translation_string + - updated_at + comment: "" + select_permissions: + - role: user + permission: + columns: + - association_id + - created_at + - fcm_data + - fcm_message + - fcm_title + - id + - job_id + - meta + - read + - scenario + - ui_translation_meta + - ui_translation_string + - updated_at + filter: + association: + _and: + - active: + _eq: true + - user: + authid: + _eq: X-Hasura-User-Id + comment: "" + update_permissions: + - role: user + permission: + columns: + - association_id + - created_at + - fcm_data + - fcm_message + - fcm_title + - id + - job_id + - meta + - read + - scenario + - ui_translation_meta + - ui_translation_string + - updated_at + filter: + association: + _and: + - active: + _eq: true + - user: + authid: + _eq: X-Hasura-User-Id + check: null + comment: "" - table: name: owners schema: public diff --git a/hasura/migrations/1736452866094_alter_table_public_associations_add_column_notification_settings/down.sql b/hasura/migrations/1736452866094_alter_table_public_associations_add_column_notification_settings/down.sql new file mode 100644 index 000000000..4e2b8ebd3 --- /dev/null +++ b/hasura/migrations/1736452866094_alter_table_public_associations_add_column_notification_settings/down.sql @@ -0,0 +1,4 @@ +-- Could not auto-generate a down migration. +-- Please write an appropriate down migration for the SQL below: +-- alter table "public"."associations" add column "notification_settings" jsonb +-- null; diff --git a/hasura/migrations/1736452866094_alter_table_public_associations_add_column_notification_settings/up.sql b/hasura/migrations/1736452866094_alter_table_public_associations_add_column_notification_settings/up.sql new file mode 100644 index 000000000..da1bac389 --- /dev/null +++ b/hasura/migrations/1736452866094_alter_table_public_associations_add_column_notification_settings/up.sql @@ -0,0 +1,2 @@ +alter table "public"."associations" add column "notification_settings" jsonb + null; diff --git a/hasura/migrations/1736455300329_create_table_public_notifications/down.sql b/hasura/migrations/1736455300329_create_table_public_notifications/down.sql new file mode 100644 index 000000000..6fc4e3068 --- /dev/null +++ b/hasura/migrations/1736455300329_create_table_public_notifications/down.sql @@ -0,0 +1 @@ +DROP TABLE "public"."notifications"; diff --git a/hasura/migrations/1736455300329_create_table_public_notifications/up.sql b/hasura/migrations/1736455300329_create_table_public_notifications/up.sql new file mode 100644 index 000000000..20c46499b --- /dev/null +++ b/hasura/migrations/1736455300329_create_table_public_notifications/up.sql @@ -0,0 +1,2 @@ +CREATE TABLE "public"."notifications" ("id" uuid NOT NULL DEFAULT gen_random_uuid(), "created_at" timestamptz NOT NULL DEFAULT now(), "updated_at" timestamptz NOT NULL DEFAULT now(), "job_id" uuid NOT NULL, "association_id" uuid NOT NULL, "ui_translation_string" text NOT NULL, "ui_translation_meta" jsonb, "fcm_title" text NOT NULL, "fcm_message" text NOT NULL, "fcm_data" jsonb, "read" timestamptz, "meta" jsonb, "scenario" Integer NOT NULL, PRIMARY KEY ("id") , FOREIGN KEY ("job_id") REFERENCES "public"."jobs"("id") ON UPDATE restrict ON DELETE restrict, FOREIGN KEY ("association_id") REFERENCES "public"."associations"("id") ON UPDATE restrict ON DELETE restrict, UNIQUE ("id"));COMMENT ON TABLE "public"."notifications" IS E'Real Time Notifications System'; +CREATE EXTENSION IF NOT EXISTS pgcrypto; diff --git a/hasura/migrations/1736457116827_alter_table_public_notifications_drop_column_scenario/down.sql b/hasura/migrations/1736457116827_alter_table_public_notifications_drop_column_scenario/down.sql new file mode 100644 index 000000000..38a88b4df --- /dev/null +++ b/hasura/migrations/1736457116827_alter_table_public_notifications_drop_column_scenario/down.sql @@ -0,0 +1,3 @@ +comment on column "public"."notifications"."scenario" is E'Real Time Notifications System'; +alter table "public"."notifications" alter column "scenario" drop not null; +alter table "public"."notifications" add column "scenario" int4; diff --git a/hasura/migrations/1736457116827_alter_table_public_notifications_drop_column_scenario/up.sql b/hasura/migrations/1736457116827_alter_table_public_notifications_drop_column_scenario/up.sql new file mode 100644 index 000000000..19d298dc1 --- /dev/null +++ b/hasura/migrations/1736457116827_alter_table_public_notifications_drop_column_scenario/up.sql @@ -0,0 +1 @@ +alter table "public"."notifications" drop column "scenario" cascade; diff --git a/hasura/migrations/1736457173242_alter_table_public_notifications_add_column_scenario/down.sql b/hasura/migrations/1736457173242_alter_table_public_notifications_add_column_scenario/down.sql new file mode 100644 index 000000000..88746e6fc --- /dev/null +++ b/hasura/migrations/1736457173242_alter_table_public_notifications_add_column_scenario/down.sql @@ -0,0 +1,4 @@ +-- Could not auto-generate a down migration. +-- Please write an appropriate down migration for the SQL below: +-- alter table "public"."notifications" add column "scenario" text +-- not null; diff --git a/hasura/migrations/1736457173242_alter_table_public_notifications_add_column_scenario/up.sql b/hasura/migrations/1736457173242_alter_table_public_notifications_add_column_scenario/up.sql new file mode 100644 index 000000000..7f26cc332 --- /dev/null +++ b/hasura/migrations/1736457173242_alter_table_public_notifications_add_column_scenario/up.sql @@ -0,0 +1,2 @@ +alter table "public"."notifications" add column "scenario" text + not null; diff --git a/hasura/migrations/1736457615046_create_table_public_job_watchers/down.sql b/hasura/migrations/1736457615046_create_table_public_job_watchers/down.sql new file mode 100644 index 000000000..b718e9f8f --- /dev/null +++ b/hasura/migrations/1736457615046_create_table_public_job_watchers/down.sql @@ -0,0 +1 @@ +DROP TABLE "public"."job_watchers"; diff --git a/hasura/migrations/1736457615046_create_table_public_job_watchers/up.sql b/hasura/migrations/1736457615046_create_table_public_job_watchers/up.sql new file mode 100644 index 000000000..1debac3c0 --- /dev/null +++ b/hasura/migrations/1736457615046_create_table_public_job_watchers/up.sql @@ -0,0 +1,2 @@ +CREATE TABLE "public"."job_watchers" ("id" uuid NOT NULL DEFAULT gen_random_uuid(), "job_id" uuid NOT NULL, "user_email" text NOT NULL, "created_at" timestamptz NOT NULL DEFAULT now(), PRIMARY KEY ("id") , FOREIGN KEY ("user_email") REFERENCES "public"."users"("email") ON UPDATE restrict ON DELETE restrict, FOREIGN KEY ("job_id") REFERENCES "public"."jobs"("id") ON UPDATE restrict ON DELETE restrict, UNIQUE ("id"));COMMENT ON TABLE "public"."job_watchers" IS E'Job Watchers'; +CREATE EXTENSION IF NOT EXISTS pgcrypto; diff --git a/server/notifications/eventHandlers/handeJobChange.js b/server/notifications/eventHandlers/handeJobChange.js new file mode 100644 index 000000000..db38d5e87 --- /dev/null +++ b/server/notifications/eventHandlers/handeJobChange.js @@ -0,0 +1,5 @@ +const handleJobChange = (req, res) => { + return res.status(200).json({ message: "Job change handled." }); +}; + +module.exports = handleJobChange; diff --git a/server/notifications/eventHandlers/handleBillChange.js b/server/notifications/eventHandlers/handleBillChange.js new file mode 100644 index 000000000..fcabafe85 --- /dev/null +++ b/server/notifications/eventHandlers/handleBillChange.js @@ -0,0 +1,5 @@ +const handleBillChange = (req, res) => { + return res.status(200).json({ message: "Bill change handled." }); +}; + +module.exports = handleBillChange; diff --git a/server/routes/notificationsRoutes.js b/server/routes/notificationsRoutes.js index cd31b7172..235d71e7f 100644 --- a/server/routes/notificationsRoutes.js +++ b/server/routes/notificationsRoutes.js @@ -1,12 +1,19 @@ const express = require("express"); const validateFirebaseIdTokenMiddleware = require("../middleware/validateFirebaseIdTokenMiddleware"); const { subscribe, unsubscribe, sendNotification } = require("../firebase/firebase-handler"); +const eventAuthorizationMiddleware = require("../middleware/eventAuthorizationMIddleware"); +const handleJobChange = require("../notifications/eventHandlers/handeJobChange"); +const handleBillChange = require("../notifications/eventHandlers/handleBillChange"); + const router = express.Router(); -router.use(validateFirebaseIdTokenMiddleware); +// These are FCM handlers +router.post("/subscribe", validateFirebaseIdTokenMiddleware, subscribe); +router.post("/unsubscribe", validateFirebaseIdTokenMiddleware, unsubscribe); +router.post("/sendtestnotification", validateFirebaseIdTokenMiddleware, sendNotification); -router.post("/subscribe", subscribe); -router.post("/unsubscribe", unsubscribe); -router.post("/sendtestnotification", sendNotification); +// Hasura Entry points for creating notifications +router.post("/events/handleJobChange", eventAuthorizationMiddleware, handleJobChange); +router.post("/events/handleBillChange", eventAuthorizationMiddleware, handleBillChange); module.exports = router; From 3bc6504ae68cb5cd6b67cacb10a8b5877c76424d Mon Sep 17 00:00:00 2001 From: Dave Richer Date: Fri, 10 Jan 2025 09:33:47 -0800 Subject: [PATCH 2/3] feature/IO-3060-Realtime-Notifications-Progress Update --- hasura/metadata/tables.yaml | 25 ++++++++++++++++--- .../down.sql | 3 +++ .../up.sql | 1 + .../handlePartsDispatchChange.js | 5 ++++ .../eventHandlers/handlePartsOrderChange.js | 5 ++++ .../eventHandlers/handleTasksChange.js | 5 ++++ .../eventHandlers/handleTimeTicketsChange.js | 5 ++++ server/routes/notificationsRoutes.js | 7 ++++++ 8 files changed, 53 insertions(+), 3 deletions(-) create mode 100644 hasura/migrations/1736522640938_alter_table_public_notifications_drop_column_scenario/down.sql create mode 100644 hasura/migrations/1736522640938_alter_table_public_notifications_drop_column_scenario/up.sql create mode 100644 server/notifications/eventHandlers/handlePartsDispatchChange.js create mode 100644 server/notifications/eventHandlers/handlePartsOrderChange.js create mode 100644 server/notifications/eventHandlers/handleTasksChange.js create mode 100644 server/notifications/eventHandlers/handleTimeTicketsChange.js diff --git a/hasura/metadata/tables.yaml b/hasura/metadata/tables.yaml index d7ddeb768..c9b1922ca 100644 --- a/hasura/metadata/tables.yaml +++ b/hasura/metadata/tables.yaml @@ -4776,7 +4776,6 @@ - job_id - meta - read - - scenario - ui_translation_meta - ui_translation_string - updated_at @@ -4794,7 +4793,6 @@ - job_id - meta - read - - scenario - ui_translation_meta - ui_translation_string - updated_at @@ -4820,7 +4818,6 @@ - job_id - meta - read - - scenario - ui_translation_meta - ui_translation_string - updated_at @@ -6200,6 +6197,28 @@ _eq: X-Hasura-User-Id - active: _eq: true + event_triggers: + - name: notifications_time_tickets + definition: + enable_manual: false + insert: + columns: '*' + update: + columns: '*' + retry_conf: + interval_sec: 10 + num_retries: 0 + timeout_sec: 60 + webhook_from_env: HASURA_API_URL + headers: + - name: event-secret + value_from_env: EVENT_SECRET + request_transform: + method: POST + query_params: {} + template_engine: Kriti + url: '{{$base_url}}/events/handleTimeTicketsChange' + version: 2 - table: name: transitions schema: public diff --git a/hasura/migrations/1736522640938_alter_table_public_notifications_drop_column_scenario/down.sql b/hasura/migrations/1736522640938_alter_table_public_notifications_drop_column_scenario/down.sql new file mode 100644 index 000000000..7ef1b7017 --- /dev/null +++ b/hasura/migrations/1736522640938_alter_table_public_notifications_drop_column_scenario/down.sql @@ -0,0 +1,3 @@ +comment on column "public"."notifications"."scenario" is E'Real Time Notifications System'; +alter table "public"."notifications" alter column "scenario" drop not null; +alter table "public"."notifications" add column "scenario" text; diff --git a/hasura/migrations/1736522640938_alter_table_public_notifications_drop_column_scenario/up.sql b/hasura/migrations/1736522640938_alter_table_public_notifications_drop_column_scenario/up.sql new file mode 100644 index 000000000..19d298dc1 --- /dev/null +++ b/hasura/migrations/1736522640938_alter_table_public_notifications_drop_column_scenario/up.sql @@ -0,0 +1 @@ +alter table "public"."notifications" drop column "scenario" cascade; diff --git a/server/notifications/eventHandlers/handlePartsDispatchChange.js b/server/notifications/eventHandlers/handlePartsDispatchChange.js new file mode 100644 index 000000000..fd3f78b97 --- /dev/null +++ b/server/notifications/eventHandlers/handlePartsDispatchChange.js @@ -0,0 +1,5 @@ +const handlePartsDispatchChange = (req, res) => { + return res.status(200).json({ message: "Parts Dispatch change handled." }); +}; + +module.exports = handlePartsDispatchChange; diff --git a/server/notifications/eventHandlers/handlePartsOrderChange.js b/server/notifications/eventHandlers/handlePartsOrderChange.js new file mode 100644 index 000000000..16c09ef2f --- /dev/null +++ b/server/notifications/eventHandlers/handlePartsOrderChange.js @@ -0,0 +1,5 @@ +const handlePartsOrderChange = (req, res) => { + return res.status(200).json({ message: "Parts Order change handled." }); +}; + +module.exports = handlePartsOrderChange; diff --git a/server/notifications/eventHandlers/handleTasksChange.js b/server/notifications/eventHandlers/handleTasksChange.js new file mode 100644 index 000000000..5a6e7f344 --- /dev/null +++ b/server/notifications/eventHandlers/handleTasksChange.js @@ -0,0 +1,5 @@ +const handleTasksChange = (req, res) => { + return res.status(200).json({ message: "Tasks change handled." }); +}; + +module.exports = handleTasksChange; diff --git a/server/notifications/eventHandlers/handleTimeTicketsChange.js b/server/notifications/eventHandlers/handleTimeTicketsChange.js new file mode 100644 index 000000000..403fa4060 --- /dev/null +++ b/server/notifications/eventHandlers/handleTimeTicketsChange.js @@ -0,0 +1,5 @@ +const handleTimeTicketsChange = (req, res) => { + return res.status(200).json({ message: "Time Tickets change handled." }); +}; + +module.exports = handleTimeTicketsChange; diff --git a/server/routes/notificationsRoutes.js b/server/routes/notificationsRoutes.js index 235d71e7f..a459b9a53 100644 --- a/server/routes/notificationsRoutes.js +++ b/server/routes/notificationsRoutes.js @@ -4,6 +4,9 @@ const { subscribe, unsubscribe, sendNotification } = require("../firebase/fireba const eventAuthorizationMiddleware = require("../middleware/eventAuthorizationMIddleware"); const handleJobChange = require("../notifications/eventHandlers/handeJobChange"); const handleBillChange = require("../notifications/eventHandlers/handleBillChange"); +const handlePartsOrderChange = require("../notifications/eventHandlers/handlePartsOrderChange"); +const handlePartsDispatchChange = require("../notifications/eventHandlers/handlePartsDispatchChange"); +const handleTasksChange = require("../notifications/eventHandlers/handleTasksChange"); const router = express.Router(); @@ -15,5 +18,9 @@ router.post("/sendtestnotification", validateFirebaseIdTokenMiddleware, sendNoti // Hasura Entry points for creating notifications router.post("/events/handleJobChange", eventAuthorizationMiddleware, handleJobChange); router.post("/events/handleBillChange", eventAuthorizationMiddleware, handleBillChange); +router.post("/events/handlePartsOrderChange", eventAuthorizationMiddleware, handlePartsOrderChange); +router.post("/events/handlePartsDispatchChange", eventAuthorizationMiddleware, handlePartsDispatchChange); +router.post("/events/handleTasksChange", eventAuthorizationMiddleware, handleTasksChange); +router.post("/events/handleTimeTicketsChange", eventAuthorizationMiddleware, handleTasksChange); module.exports = router; From 8a0916a47f1e421a5dba0bc7f8f5901e9ecb2b78 Mon Sep 17 00:00:00 2001 From: Dave Richer Date: Mon, 13 Jan 2025 07:27:10 -0800 Subject: [PATCH 3/3] feature/IO-3060-Realtime-Notifications- Checkpoint --- hasura/metadata/tables.yaml | 166 +++++++++++++----- .../down.sql | 3 + .../up.sql | 1 + .../down.sql | 1 + .../up.sql | 1 + .../down.sql | 5 + .../up.sql | 3 + .../down.sql | 2 + .../up.sql | 2 + .../down.sql | 2 + .../up.sql | 2 + .../down.sql | 2 + .../up.sql | 2 + .../down.sql | 1 + .../up.sql | 1 + .../down.sql | 1 + .../up.sql | 1 + .../down.sql | 1 + .../up.sql | 1 + server/email/tasksEmails.js | 27 ++- .../eventHandlers/handeJobChange.js | 5 - .../eventHandlers/handeJobsChange.js | 5 + .../eventHandlers/handleBillChange.js | 5 - .../eventHandlers/handleBillsChange.js | 5 + server/routes/notificationsRoutes.js | 12 +- 25 files changed, 188 insertions(+), 69 deletions(-) create mode 100644 hasura/migrations/1736532531529_notification_settings_to_null/down.sql create mode 100644 hasura/migrations/1736532531529_notification_settings_to_null/up.sql create mode 100644 hasura/migrations/1736532558976_alter_table_public_associations_alter_column_notification_settings/down.sql create mode 100644 hasura/migrations/1736532558976_alter_table_public_associations_alter_column_notification_settings/up.sql create mode 100644 hasura/migrations/1736532890968_notifications_json_empty/down.sql create mode 100644 hasura/migrations/1736532890968_notifications_json_empty/up.sql create mode 100644 hasura/migrations/1736532914109_alter_table_public_notifications_alter_column_meta/down.sql create mode 100644 hasura/migrations/1736532914109_alter_table_public_notifications_alter_column_meta/up.sql create mode 100644 hasura/migrations/1736532933220_alter_table_public_notifications_alter_column_fcm_data/down.sql create mode 100644 hasura/migrations/1736532933220_alter_table_public_notifications_alter_column_fcm_data/up.sql create mode 100644 hasura/migrations/1736532952372_alter_table_public_notifications_alter_column_ui_translation_meta/down.sql create mode 100644 hasura/migrations/1736532952372_alter_table_public_notifications_alter_column_ui_translation_meta/up.sql create mode 100644 hasura/migrations/1736781880394_alter_table_public_notifications_alter_column_job_id/down.sql create mode 100644 hasura/migrations/1736781880394_alter_table_public_notifications_alter_column_job_id/up.sql create mode 100644 hasura/migrations/1736781913160_alter_table_public_notifications_alter_column_association_id/down.sql create mode 100644 hasura/migrations/1736781913160_alter_table_public_notifications_alter_column_association_id/up.sql create mode 100644 hasura/migrations/1736781949826_alter_table_public_job_watchers_alter_column_job_id/down.sql create mode 100644 hasura/migrations/1736781949826_alter_table_public_job_watchers_alter_column_job_id/up.sql delete mode 100644 server/notifications/eventHandlers/handeJobChange.js create mode 100644 server/notifications/eventHandlers/handeJobsChange.js delete mode 100644 server/notifications/eventHandlers/handleBillChange.js create mode 100644 server/notifications/eventHandlers/handleBillsChange.js diff --git a/hasura/metadata/tables.yaml b/hasura/metadata/tables.yaml index c9b1922ca..68dab7c39 100644 --- a/hasura/metadata/tables.yaml +++ b/hasura/metadata/tables.yaml @@ -683,6 +683,31 @@ - exported: _eq: false event_triggers: + - name: notifications_bills + definition: + enable_manual: false + insert: + columns: '*' + retry_conf: + interval_sec: 10 + num_retries: 0 + timeout_sec: 60 + webhook_from_env: HASURA_API_URL + headers: + - name: event-secret + value_from_env: EVENT_SECRET + request_transform: + body: + action: transform + template: |- + { + "success": true + } + method: POST + query_params: {} + template_engine: Kriti + url: '{{$base_url}}/job/events/handleBillsChange' + version: 2 - name: os_bills definition: delete: @@ -2813,7 +2838,7 @@ object_relationships: - name: job using: - foreign_key_constraint_on: job_id + foreign_key_constraint_on: jobid - name: user using: foreign_key_constraint_on: user_email @@ -2832,7 +2857,7 @@ - user_email - created_at - id - - job_id + - jobid comment: "" select_permissions: - role: user @@ -2841,7 +2866,7 @@ - user_email - created_at - id - - job_id + - jobid filter: user: _and: @@ -2858,7 +2883,7 @@ - user_email - created_at - id - - job_id + - jobid filter: user: _and: @@ -4402,6 +4427,58 @@ template_engine: Kriti url: '{{$base_url}}/record-handler/arms' version: 2 + - name: notifications_jobs + definition: + enable_manual: false + insert: + columns: '*' + update: + columns: + - queued_for_parts + - employee_prep + - clm_total + - towin + - employee_body + - converted + - scheduled_in + - scheduled_completion + - scheduled_delivery + - actual_delivery + - actual_completion + - alt_transport + - date_exported + - status + - employee_csr + - actual_in + - deliverchecklist + - comment + - job_totals + - employee_refinish + - inproduction + - production_vars + - intakechecklist + - cieca_ttl + - date_invoiced + retry_conf: + interval_sec: 10 + num_retries: 0 + timeout_sec: 60 + webhook_from_env: HASURA_API_URL + headers: + - name: event-secret + value_from_env: EVENT_SECRET + request_transform: + body: + action: transform + template: |- + { + "success": true + } + method: POST + query_params: {} + template_engine: Kriti + url: '{{$base_url}}/job/events/handleJobsChange' + version: 2 - name: os_jobs definition: delete: @@ -4751,46 +4828,21 @@ object_relationships: - name: association using: - foreign_key_constraint_on: association_id + foreign_key_constraint_on: associationid - name: job using: - foreign_key_constraint_on: job_id - insert_permissions: - - role: user - permission: - check: - association: - _and: - - active: - _eq: true - - user: - authid: - _eq: X-Hasura-User-Id - columns: - - association_id - - created_at - - fcm_data - - fcm_message - - fcm_title - - id - - job_id - - meta - - read - - ui_translation_meta - - ui_translation_string - - updated_at - comment: "" + foreign_key_constraint_on: jobid select_permissions: - role: user permission: columns: - - association_id + - associationid - created_at - fcm_data - fcm_message - fcm_title - id - - job_id + - jobid - meta - read - ui_translation_meta @@ -4809,18 +4861,8 @@ - role: user permission: columns: - - association_id - - created_at - - fcm_data - - fcm_message - - fcm_title - - id - - job_id - meta - read - - ui_translation_meta - - ui_translation_string - - updated_at filter: association: _and: @@ -5071,6 +5113,32 @@ - active: _eq: true check: null + event_triggers: + - name: notifications_parts_dispatch + definition: + enable_manual: false + insert: + columns: '*' + retry_conf: + interval_sec: 10 + num_retries: 0 + timeout_sec: 60 + webhook_from_env: HASURA_API_URL + headers: + - name: event-secret + value_from_env: EVENT_SECRET + request_transform: + body: + action: transform + template: |- + { + "success": true + } + method: POST + query_params: {} + template_engine: Kriti + url: '{{$base_url}}/job/events/handlePartsDispatchChange' + version: 2 - table: name: parts_dispatch_lines schema: public @@ -6049,6 +6117,8 @@ update: columns: - assigned_to + - completed + - description retry_conf: interval_sec: 10 num_retries: 3 @@ -6203,8 +6273,6 @@ enable_manual: false insert: columns: '*' - update: - columns: '*' retry_conf: interval_sec: 10 num_retries: 0 @@ -6214,10 +6282,16 @@ - name: event-secret value_from_env: EVENT_SECRET request_transform: + body: + action: transform + template: |- + { + "success": true + } method: POST query_params: {} template_engine: Kriti - url: '{{$base_url}}/events/handleTimeTicketsChange' + url: '{{$base_url}}/job/events/handleTimeTicketsChange' version: 2 - table: name: transitions diff --git a/hasura/migrations/1736532531529_notification_settings_to_null/down.sql b/hasura/migrations/1736532531529_notification_settings_to_null/down.sql new file mode 100644 index 000000000..9b79fc484 --- /dev/null +++ b/hasura/migrations/1736532531529_notification_settings_to_null/down.sql @@ -0,0 +1,3 @@ +-- Could not auto-generate a down migration. +-- Please write an appropriate down migration for the SQL below: +-- update associations set notification_settings = '{}'; diff --git a/hasura/migrations/1736532531529_notification_settings_to_null/up.sql b/hasura/migrations/1736532531529_notification_settings_to_null/up.sql new file mode 100644 index 000000000..0badc8e0d --- /dev/null +++ b/hasura/migrations/1736532531529_notification_settings_to_null/up.sql @@ -0,0 +1 @@ +update associations set notification_settings = '{}'; diff --git a/hasura/migrations/1736532558976_alter_table_public_associations_alter_column_notification_settings/down.sql b/hasura/migrations/1736532558976_alter_table_public_associations_alter_column_notification_settings/down.sql new file mode 100644 index 000000000..a57d44af7 --- /dev/null +++ b/hasura/migrations/1736532558976_alter_table_public_associations_alter_column_notification_settings/down.sql @@ -0,0 +1 @@ +alter table "public"."associations" alter column "notification_settings" drop not null; diff --git a/hasura/migrations/1736532558976_alter_table_public_associations_alter_column_notification_settings/up.sql b/hasura/migrations/1736532558976_alter_table_public_associations_alter_column_notification_settings/up.sql new file mode 100644 index 000000000..ff8b9e509 --- /dev/null +++ b/hasura/migrations/1736532558976_alter_table_public_associations_alter_column_notification_settings/up.sql @@ -0,0 +1 @@ +alter table "public"."associations" alter column "notification_settings" set not null; diff --git a/hasura/migrations/1736532890968_notifications_json_empty/down.sql b/hasura/migrations/1736532890968_notifications_json_empty/down.sql new file mode 100644 index 000000000..8996c9f3e --- /dev/null +++ b/hasura/migrations/1736532890968_notifications_json_empty/down.sql @@ -0,0 +1,5 @@ +-- Could not auto-generate a down migration. +-- Please write an appropriate down migration for the SQL below: +-- update notifications set meta = '{}'; +-- update notifications set fcm_data = '{}'; +-- update notifications set ui_translation_meta = '{}'; diff --git a/hasura/migrations/1736532890968_notifications_json_empty/up.sql b/hasura/migrations/1736532890968_notifications_json_empty/up.sql new file mode 100644 index 000000000..3300e7e9e --- /dev/null +++ b/hasura/migrations/1736532890968_notifications_json_empty/up.sql @@ -0,0 +1,3 @@ +update notifications set meta = '{}'; +update notifications set fcm_data = '{}'; +update notifications set ui_translation_meta = '{}'; diff --git a/hasura/migrations/1736532914109_alter_table_public_notifications_alter_column_meta/down.sql b/hasura/migrations/1736532914109_alter_table_public_notifications_alter_column_meta/down.sql new file mode 100644 index 000000000..86844a82c --- /dev/null +++ b/hasura/migrations/1736532914109_alter_table_public_notifications_alter_column_meta/down.sql @@ -0,0 +1,2 @@ +alter table "public"."notifications" alter column "meta" drop not null; +ALTER TABLE "public"."notifications" ALTER COLUMN "meta" drop default; diff --git a/hasura/migrations/1736532914109_alter_table_public_notifications_alter_column_meta/up.sql b/hasura/migrations/1736532914109_alter_table_public_notifications_alter_column_meta/up.sql new file mode 100644 index 000000000..05e6a5b23 --- /dev/null +++ b/hasura/migrations/1736532914109_alter_table_public_notifications_alter_column_meta/up.sql @@ -0,0 +1,2 @@ +alter table "public"."notifications" alter column "meta" set default jsonb_build_object(); +alter table "public"."notifications" alter column "meta" set not null; diff --git a/hasura/migrations/1736532933220_alter_table_public_notifications_alter_column_fcm_data/down.sql b/hasura/migrations/1736532933220_alter_table_public_notifications_alter_column_fcm_data/down.sql new file mode 100644 index 000000000..f33b7161e --- /dev/null +++ b/hasura/migrations/1736532933220_alter_table_public_notifications_alter_column_fcm_data/down.sql @@ -0,0 +1,2 @@ +alter table "public"."notifications" alter column "fcm_data" drop not null; +ALTER TABLE "public"."notifications" ALTER COLUMN "fcm_data" drop default; diff --git a/hasura/migrations/1736532933220_alter_table_public_notifications_alter_column_fcm_data/up.sql b/hasura/migrations/1736532933220_alter_table_public_notifications_alter_column_fcm_data/up.sql new file mode 100644 index 000000000..5c0d753d9 --- /dev/null +++ b/hasura/migrations/1736532933220_alter_table_public_notifications_alter_column_fcm_data/up.sql @@ -0,0 +1,2 @@ +alter table "public"."notifications" alter column "fcm_data" set default jsonb_build_object(); +alter table "public"."notifications" alter column "fcm_data" set not null; diff --git a/hasura/migrations/1736532952372_alter_table_public_notifications_alter_column_ui_translation_meta/down.sql b/hasura/migrations/1736532952372_alter_table_public_notifications_alter_column_ui_translation_meta/down.sql new file mode 100644 index 000000000..d4a7ca3ef --- /dev/null +++ b/hasura/migrations/1736532952372_alter_table_public_notifications_alter_column_ui_translation_meta/down.sql @@ -0,0 +1,2 @@ +alter table "public"."notifications" alter column "ui_translation_meta" drop not null; +ALTER TABLE "public"."notifications" ALTER COLUMN "ui_translation_meta" drop default; diff --git a/hasura/migrations/1736532952372_alter_table_public_notifications_alter_column_ui_translation_meta/up.sql b/hasura/migrations/1736532952372_alter_table_public_notifications_alter_column_ui_translation_meta/up.sql new file mode 100644 index 000000000..221860724 --- /dev/null +++ b/hasura/migrations/1736532952372_alter_table_public_notifications_alter_column_ui_translation_meta/up.sql @@ -0,0 +1,2 @@ +alter table "public"."notifications" alter column "ui_translation_meta" set default jsonb_build_object(); +alter table "public"."notifications" alter column "ui_translation_meta" set not null; diff --git a/hasura/migrations/1736781880394_alter_table_public_notifications_alter_column_job_id/down.sql b/hasura/migrations/1736781880394_alter_table_public_notifications_alter_column_job_id/down.sql new file mode 100644 index 000000000..701336411 --- /dev/null +++ b/hasura/migrations/1736781880394_alter_table_public_notifications_alter_column_job_id/down.sql @@ -0,0 +1 @@ +alter table "public"."notifications" rename column "jobid" to "job_id"; diff --git a/hasura/migrations/1736781880394_alter_table_public_notifications_alter_column_job_id/up.sql b/hasura/migrations/1736781880394_alter_table_public_notifications_alter_column_job_id/up.sql new file mode 100644 index 000000000..ee6f4ba02 --- /dev/null +++ b/hasura/migrations/1736781880394_alter_table_public_notifications_alter_column_job_id/up.sql @@ -0,0 +1 @@ +alter table "public"."notifications" rename column "job_id" to "jobid"; diff --git a/hasura/migrations/1736781913160_alter_table_public_notifications_alter_column_association_id/down.sql b/hasura/migrations/1736781913160_alter_table_public_notifications_alter_column_association_id/down.sql new file mode 100644 index 000000000..ddf7bf683 --- /dev/null +++ b/hasura/migrations/1736781913160_alter_table_public_notifications_alter_column_association_id/down.sql @@ -0,0 +1 @@ +alter table "public"."notifications" rename column "associationid" to "association_id"; diff --git a/hasura/migrations/1736781913160_alter_table_public_notifications_alter_column_association_id/up.sql b/hasura/migrations/1736781913160_alter_table_public_notifications_alter_column_association_id/up.sql new file mode 100644 index 000000000..5238af59a --- /dev/null +++ b/hasura/migrations/1736781913160_alter_table_public_notifications_alter_column_association_id/up.sql @@ -0,0 +1 @@ +alter table "public"."notifications" rename column "association_id" to "associationid"; diff --git a/hasura/migrations/1736781949826_alter_table_public_job_watchers_alter_column_job_id/down.sql b/hasura/migrations/1736781949826_alter_table_public_job_watchers_alter_column_job_id/down.sql new file mode 100644 index 000000000..ff9c47c35 --- /dev/null +++ b/hasura/migrations/1736781949826_alter_table_public_job_watchers_alter_column_job_id/down.sql @@ -0,0 +1 @@ +alter table "public"."job_watchers" rename column "jobid" to "job_id"; diff --git a/hasura/migrations/1736781949826_alter_table_public_job_watchers_alter_column_job_id/up.sql b/hasura/migrations/1736781949826_alter_table_public_job_watchers_alter_column_job_id/up.sql new file mode 100644 index 000000000..af25f283a --- /dev/null +++ b/hasura/migrations/1736781949826_alter_table_public_job_watchers_alter_column_job_id/up.sql @@ -0,0 +1 @@ +alter table "public"."job_watchers" rename column "job_id" to "jobid"; diff --git a/server/email/tasksEmails.js b/server/email/tasksEmails.js index 6d787811a..7a05bcb05 100644 --- a/server/email/tasksEmails.js +++ b/server/email/tasksEmails.js @@ -142,27 +142,38 @@ const sendMail = (type, to, subject, html, taskIds, successCallback, requestInst * @returns {Promise<*>} */ const taskAssignedEmail = async (req, res) => { - // We have no event Data, bail + // 1. Check if we have new task data in the event body. if (!req?.body?.event?.data?.new) { return res.status(400).json({ message: "No data in the event body" }); } - const { new: newTask } = req.body.event.data; + const { new: newTask, old: oldTask } = req.body.event.data; - // This is not a new task, but a reassignment. - const dirty = req.body.event.data?.old && req.body.event.data?.old?.assigned_to; + // TODO: THIS IS HERE BECAUSE THE HANDLER NOW DOES 3 FIELDS, WILL NEED TO BE BUILT ON FOR NOTIFICATIONS + if (oldTask && oldTask.assigned_to === newTask.assigned_to) { + return res.status(200).json({ success: true, message: "assigned_to not changed" }); + } - //Query to get the employee assigned currently. + // 3. If we made it here, assigned_to changed (or oldTask is missing), + // so we continue with the rest of the logic. + + // Query to get the task with bodyshop data, assigned employee data, etc. const { tasks_by_pk } = await client.request(queries.QUERY_TASK_BY_ID, { id: newTask.id }); + // Format date/time with the correct timezone const dateLine = moment().tz(tasks_by_pk.bodyshop.timezone).format("M/DD/YYYY @ hh:mm a"); + // This determines if it was re-assigned (old task exists and had an assigned_to). + const dirty = oldTask && oldTask.assigned_to; + sendMail( "assigned", tasks_by_pk.assigned_to_employee.user_email, - `A ${formatPriority(newTask.priority)} priority task has been ${dirty ? "reassigned to" : "created for"} you - ${newTask.title}`, + `A ${formatPriority(newTask.priority)} priority task has been ${ + dirty ? "reassigned" : "created" + } for you - ${newTask.title}`, generateEmailTemplate( generateTemplateArgs( newTask.title, @@ -181,8 +192,8 @@ const taskAssignedEmail = async (req, res) => { tasks_by_pk.bodyshop.convenient_company ); - // We return success regardless because we don't want to block the event trigger. - res.status(200).json({ success: true }); + // Return success so we don't block the event trigger. + return res.status(200).json({ success: true }); }; /** diff --git a/server/notifications/eventHandlers/handeJobChange.js b/server/notifications/eventHandlers/handeJobChange.js deleted file mode 100644 index db38d5e87..000000000 --- a/server/notifications/eventHandlers/handeJobChange.js +++ /dev/null @@ -1,5 +0,0 @@ -const handleJobChange = (req, res) => { - return res.status(200).json({ message: "Job change handled." }); -}; - -module.exports = handleJobChange; diff --git a/server/notifications/eventHandlers/handeJobsChange.js b/server/notifications/eventHandlers/handeJobsChange.js new file mode 100644 index 000000000..9449f23c4 --- /dev/null +++ b/server/notifications/eventHandlers/handeJobsChange.js @@ -0,0 +1,5 @@ +const handleJobsChange = (req, res) => { + return res.status(200).json({ message: "Jobs change handled." }); +}; + +module.exports = handleJobsChange; diff --git a/server/notifications/eventHandlers/handleBillChange.js b/server/notifications/eventHandlers/handleBillChange.js deleted file mode 100644 index fcabafe85..000000000 --- a/server/notifications/eventHandlers/handleBillChange.js +++ /dev/null @@ -1,5 +0,0 @@ -const handleBillChange = (req, res) => { - return res.status(200).json({ message: "Bill change handled." }); -}; - -module.exports = handleBillChange; diff --git a/server/notifications/eventHandlers/handleBillsChange.js b/server/notifications/eventHandlers/handleBillsChange.js new file mode 100644 index 000000000..d444848f2 --- /dev/null +++ b/server/notifications/eventHandlers/handleBillsChange.js @@ -0,0 +1,5 @@ +const handleBillsChange = (req, res) => { + return res.status(200).json({ message: "Bills change handled." }); +}; + +module.exports = handleBillsChange; diff --git a/server/routes/notificationsRoutes.js b/server/routes/notificationsRoutes.js index a459b9a53..64228382b 100644 --- a/server/routes/notificationsRoutes.js +++ b/server/routes/notificationsRoutes.js @@ -2,11 +2,13 @@ const express = require("express"); const validateFirebaseIdTokenMiddleware = require("../middleware/validateFirebaseIdTokenMiddleware"); const { subscribe, unsubscribe, sendNotification } = require("../firebase/firebase-handler"); const eventAuthorizationMiddleware = require("../middleware/eventAuthorizationMIddleware"); -const handleJobChange = require("../notifications/eventHandlers/handeJobChange"); -const handleBillChange = require("../notifications/eventHandlers/handleBillChange"); + const handlePartsOrderChange = require("../notifications/eventHandlers/handlePartsOrderChange"); const handlePartsDispatchChange = require("../notifications/eventHandlers/handlePartsDispatchChange"); const handleTasksChange = require("../notifications/eventHandlers/handleTasksChange"); +const handleTimeTicketsChange = require("../notifications/eventHandlers/handleTimeTicketsChange"); +const handleJobsChange = require("../notifications/eventHandlers/handeJobsChange"); +const handleBillsChange = require("../notifications/eventHandlers/handleBillsChange"); const router = express.Router(); @@ -16,11 +18,11 @@ router.post("/unsubscribe", validateFirebaseIdTokenMiddleware, unsubscribe); router.post("/sendtestnotification", validateFirebaseIdTokenMiddleware, sendNotification); // Hasura Entry points for creating notifications -router.post("/events/handleJobChange", eventAuthorizationMiddleware, handleJobChange); -router.post("/events/handleBillChange", eventAuthorizationMiddleware, handleBillChange); +router.post("/events/handleJobsChange", eventAuthorizationMiddleware, handleJobsChange); +router.post("/events/handleBillsChange", eventAuthorizationMiddleware, handleBillsChange); router.post("/events/handlePartsOrderChange", eventAuthorizationMiddleware, handlePartsOrderChange); router.post("/events/handlePartsDispatchChange", eventAuthorizationMiddleware, handlePartsDispatchChange); router.post("/events/handleTasksChange", eventAuthorizationMiddleware, handleTasksChange); -router.post("/events/handleTimeTicketsChange", eventAuthorizationMiddleware, handleTasksChange); +router.post("/events/handleTimeTicketsChange", eventAuthorizationMiddleware, handleTimeTicketsChange); module.exports = router;