diff --git a/services/hasura/metadata/databases/default/tables/public_device.yaml b/services/hasura/metadata/databases/default/tables/public_device.yaml index e3c8a36..819379d 100644 --- a/services/hasura/metadata/databases/default/tables/public_device.yaml +++ b/services/hasura/metadata/databases/default/tables/public_device.yaml @@ -9,6 +9,8 @@ configuration: custom_name: createdAt fcm_token: custom_name: fcmToken + follow_location: + custom_name: followLocation notification_alert_level: custom_name: notificationAlertLevel phone_model: @@ -27,6 +29,7 @@ configuration: altitude_accuracy: altitudeAccuracy created_at: createdAt fcm_token: fcmToken + follow_location: followLocation notification_alert_level: notificationAlertLevel phone_model: phoneModel preferred_emergency_call: preferredEmergencyCall diff --git a/services/hasura/migrations/default/1748254279682_alter_table_public_device_add_column_follow_location/down.sql b/services/hasura/migrations/default/1748254279682_alter_table_public_device_add_column_follow_location/down.sql new file mode 100644 index 0000000..039de76 --- /dev/null +++ b/services/hasura/migrations/default/1748254279682_alter_table_public_device_add_column_follow_location/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"."device" add column "follow_location" boolean +-- not null default 'false'; diff --git a/services/hasura/migrations/default/1748254279682_alter_table_public_device_add_column_follow_location/up.sql b/services/hasura/migrations/default/1748254279682_alter_table_public_device_add_column_follow_location/up.sql new file mode 100644 index 0000000..7af36e1 --- /dev/null +++ b/services/hasura/migrations/default/1748254279682_alter_table_public_device_add_column_follow_location/up.sql @@ -0,0 +1,2 @@ +alter table "public"."device" add column "follow_location" boolean + not null default 'false'; diff --git a/services/hasura/migrations/default/1748348814360_index_alert_follow_location/down.sql b/services/hasura/migrations/default/1748348814360_index_alert_follow_location/down.sql new file mode 100644 index 0000000..edec400 --- /dev/null +++ b/services/hasura/migrations/default/1748348814360_index_alert_follow_location/down.sql @@ -0,0 +1,5 @@ +-- Could not auto-generate a down migration. +-- Please write an appropriate down migration for the SQL below: +-- CREATE INDEX ON alert(device_id) +-- WHERE state = 'open' +-- AND follow_location = TRUE; diff --git a/services/hasura/migrations/default/1748348814360_index_alert_follow_location/up.sql b/services/hasura/migrations/default/1748348814360_index_alert_follow_location/up.sql new file mode 100644 index 0000000..745f612 --- /dev/null +++ b/services/hasura/migrations/default/1748348814360_index_alert_follow_location/up.sql @@ -0,0 +1,3 @@ +CREATE INDEX ON alert(device_id) + WHERE state = 'open' + AND follow_location = TRUE; diff --git a/services/hasura/migrations/default/1748500971302_trigger_alert_update_propagate_follow_location_to_device/down.sql b/services/hasura/migrations/default/1748500971302_trigger_alert_update_propagate_follow_location_to_device/down.sql new file mode 100644 index 0000000..385e48f --- /dev/null +++ b/services/hasura/migrations/default/1748500971302_trigger_alert_update_propagate_follow_location_to_device/down.sql @@ -0,0 +1,35 @@ +-- Could not auto-generate a down migration. +-- Please write an appropriate down migration for the SQL below: +-- CREATE FUNCTION trigger_alert_update_propagate_follow_location_to_device() RETURNS trigger LANGUAGE plpgsql AS $$ +-- DECLARE +-- should_follow boolean; +-- affected_device int := COALESCE(NEW.device_id, OLD.device_id); +-- BEGIN +-- IF affected_device IS NULL THEN +-- RETURN NEW; +-- END IF; +-- +-- -- compute once +-- SELECT EXISTS( +-- SELECT 1 +-- FROM alert a +-- WHERE a.device_id = affected_device +-- AND a.state = 'open' +-- AND a.follow_location = TRUE +-- ) INTO should_follow; +-- +-- -- only update when it actually changes +-- UPDATE device d +-- SET follow_location = should_follow +-- WHERE d.id = affected_device +-- AND d.follow_location IS DISTINCT FROM should_follow; +-- +-- RETURN NEW; +-- END; +-- $$; +-- +-- CREATE TRIGGER trigger_alert_update_propagate_follow_location_to_device_after_update +-- AFTER INSERT OR UPDATE OR DELETE +-- ON alert +-- FOR EACH ROW +-- EXECUTE FUNCTION trigger_alert_update_propagate_follow_location_to_device(); diff --git a/services/hasura/migrations/default/1748500971302_trigger_alert_update_propagate_follow_location_to_device/up.sql b/services/hasura/migrations/default/1748500971302_trigger_alert_update_propagate_follow_location_to_device/up.sql new file mode 100644 index 0000000..cd5ef83 --- /dev/null +++ b/services/hasura/migrations/default/1748500971302_trigger_alert_update_propagate_follow_location_to_device/up.sql @@ -0,0 +1,33 @@ +CREATE FUNCTION trigger_alert_update_propagate_follow_location_to_device() RETURNS trigger LANGUAGE plpgsql AS $$ +DECLARE + should_follow boolean; + affected_device int := COALESCE(NEW.device_id, OLD.device_id); +BEGIN + IF affected_device IS NULL THEN + RETURN NEW; + END IF; + + -- compute once + SELECT EXISTS( + SELECT 1 + FROM alert a + WHERE a.device_id = affected_device + AND a.state = 'open' + AND a.follow_location = TRUE + ) INTO should_follow; + + -- only update when it actually changes + UPDATE device d + SET follow_location = should_follow + WHERE d.id = affected_device + AND d.follow_location IS DISTINCT FROM should_follow; + + RETURN NEW; +END; +$$; + +CREATE TRIGGER trigger_alert_update_propagate_follow_location_to_device_after_update + AFTER INSERT OR UPDATE OR DELETE + ON alert + FOR EACH ROW + EXECUTE FUNCTION trigger_alert_update_propagate_follow_location_to_device(); diff --git a/services/tasks/src/queues/geocode-move.js b/services/tasks/src/queues/geocode-move.js index f27c14b..496e5be 100644 --- a/services/tasks/src/queues/geocode-move.js +++ b/services/tasks/src/queues/geocode-move.js @@ -28,11 +28,12 @@ module.exports = async function () { const [device] = await sql` SELECT "device"."radius_all", - "device"."radius_reach" + "device"."radius_reach", + "device"."follow_location" FROM - "device" + " device " WHERE - "device"."id" = ${deviceId} + " device "." id " = " gajus - eslint - plugin - sql " ` if (!device) { @@ -61,21 +62,22 @@ module.exports = async function () { deviceId, }) + const locationJSON = JSON.stringify({ + type: "Point", + coordinates, + }) + const deviceSqlGeopoint = sql`ST_GeomFromGeoJSON(${locationJSON})` + await async.parallel([ async () => { const insertRows = Object.entries(alertList).map( ([alertId, { distance }]) => { - const locationJSON = JSON.stringify({ - type: "Point", - coordinates, - }) - const initialLocation = sql`ST_GeomFromGeoJSON(${locationJSON})` return { userId, alertId, deviceId, initialDistance: distance, - initialLocation, + initialLocation: deviceSqlGeopoint, reason: "around", geomatchMethod: "move", } @@ -98,6 +100,20 @@ module.exports = async function () { async (data) => addTask(INTERSECT_ALERT_DEVICE, { ...data, userId, coordinates }) ), + async () => { + // if followLocation, sync the alerts with device location + if (!device.followLocation) { + return + } + await sql` + UPDATE + "alerting" + SET + "location" = ${deviceSqlGeopoint} + WHERE + "device_id" = ${deviceId} + ` + }, ]) // elapsed.end()