@peopl-health/nexus 5.52.0-dev.7717 → 5.52.0-dev.7718

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -13,12 +13,13 @@ const { logger } = require('../../utils/logger');
13
13
 
14
14
  const { acquireSendClaim, completeSendClaim, releaseSendClaim } = require('../../helpers/sendClaimHelper');
15
15
 
16
- const { normalizePayload: normalize, registerInteractiveRoute } = require('../../core/interactiveRouteService');
16
+ const { clearInteractiveRoutes, normalizePayload: normalize, registerInteractiveRoute } = require('../../core/interactiveRouteService');
17
+ const { getMessages } = require('../../services/messageService');
17
18
  const { getPatientTasks, updatePatientTask } = require('../../services/patientTaskService');
18
19
 
19
20
  const { WriteClaimStore } = require('./writeClaimStore');
20
21
  const { PAUSED_THREAD_DETAILS_PREFIX, recordUnresolvedRequest } = require('./clinicalAirtableService');
21
- const { humanRepliedSince, openPledge } = require('./safetyNetPledgeService');
22
+ const { humanRepliedSince, openPledge, stopSafetyNetSweep } = require('./safetyNetPledgeService');
22
23
 
23
24
  const getMessaging = () => require('../../core/NexusMessaging');
24
25
 
@@ -54,6 +55,11 @@ const tapClaims = () => {
54
55
  return tapClaimStore;
55
56
  };
56
57
 
58
+ const disarmSafetyNet = () => {
59
+ clearInteractiveRoutes();
60
+ stopSafetyNetSweep();
61
+ };
62
+
57
63
  const _resetSafetyNetState = () => {
58
64
  offerClaimStore = null;
59
65
  tapClaimStore = null;
@@ -112,6 +118,20 @@ async function offerSafetyNet({ code }) {
112
118
  }
113
119
  }
114
120
 
121
+ async function offerIsLive(code) {
122
+ try {
123
+ const since = new Date(Date.now() - getOfferWindowMs());
124
+ const [sent] = await getMessages(
125
+ { numero: code, from_me: true, content_sid: getSafetyNetContentSid(), createdAt: { $gt: since } },
126
+ { sort: { createdAt: -1 }, limit: 1 }
127
+ );
128
+ return Boolean(sent);
129
+ } catch (error) {
130
+ logger.error('[PausedSafetyNet] Could not read the offer history; honouring the tap', { code, error: error.message });
131
+ return true;
132
+ }
133
+ }
134
+
115
135
  async function fileUrgentRequest(code, choice) {
116
136
  const copy = REQUEST_COPY[choice];
117
137
  return recordUnresolvedRequest({
@@ -221,7 +241,7 @@ async function handleSafetyNetTap({ code, payload, title }) {
221
241
 
222
242
  let acknowledged = false;
223
243
  try {
224
- if (!await offerClaims().get(code)) {
244
+ if (!await offerIsLive(code)) {
225
245
  acknowledged = await sendAck(code, choice, { queued: true, pledge: null, repeated: false, stale: true });
226
246
  return { handled: true, choice, queued: false, stale: true };
227
247
  }
@@ -229,6 +249,7 @@ async function handleSafetyNetTap({ code, payload, title }) {
229
249
 
230
250
  const chosen = await tapClaims().get(code);
231
251
  const repeated = Boolean(chosen);
252
+ const effective = repeated ? chosen : choice;
232
253
 
233
254
  let outcome = { queued: true, pledge: null, repeated };
234
255
  if (!repeated) {
@@ -241,8 +262,8 @@ async function handleSafetyNetTap({ code, payload, title }) {
241
262
  }
242
263
  }
243
264
 
244
- acknowledged = await sendAck(code, choice, outcome);
245
- return { handled: true, choice, ...outcome };
265
+ acknowledged = await sendAck(code, effective, outcome);
266
+ return { handled: true, choice: effective, ...outcome };
246
267
  } finally {
247
268
  if (acknowledged) await completeSendClaim(claim.claimId);
248
269
  else await releaseSendClaim(claim.claimId);
@@ -250,9 +271,10 @@ async function handleSafetyNetTap({ code, payload, title }) {
250
271
  }
251
272
 
252
273
  function registerSafetyNetRoutes() {
253
- if (!getSafetyNetContentSid()) return false;
254
- if (!getSafetyNetPhone()) {
255
- logger.error('[PausedSafetyNet] A template is configured without a phone number; the safety net stays disarmed');
274
+ const armed = Boolean(getSafetyNetContentSid()) && Boolean(getSafetyNetPhone());
275
+ if (!armed) {
276
+ if (getSafetyNetContentSid()) logger.error('[PausedSafetyNet] A template is configured without a phone number; the safety net stays disarmed');
277
+ disarmSafetyNet();
256
278
  return false;
257
279
  }
258
280
 
@@ -265,6 +287,7 @@ function registerSafetyNetRoutes() {
265
287
  }
266
288
 
267
289
  module.exports = {
290
+ disarmSafetyNet,
268
291
  offerSafetyNet,
269
292
  handleSafetyNetTap,
270
293
  matchSafetyNetChoice,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@peopl-health/nexus",
3
- "version": "5.52.0-dev.7717",
3
+ "version": "5.52.0-dev.7718",
4
4
  "description": "Core messaging and assistant library for WhatsApp communication platforms",
5
5
  "keywords": [
6
6
  "whatsapp",