@peopl-health/nexus 5.69.0-dev.12623 → 5.69.0-dev.12624

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.
@@ -210,16 +210,25 @@ function buildCandidates(rows, { now, cadence = 'daily', mode = 'continuity' })
210
210
  return { candidates, targetDays, weekday, cadence, mode };
211
211
  }
212
212
 
213
+ function firstWord(value) {
214
+ return String(value || '').trim().split(/\s+/)[0];
215
+ }
216
+
213
217
  function buildScopeCandidates({ threads, excludedCodes }) {
218
+ const threadsByCode = new Map();
219
+ for (const thread of threads) threadsByCode.set(thread.code, [...(threadsByCode.get(thread.code) || []), thread]);
220
+
214
221
  const candidates = [];
215
- for (const thread of new Map(threads.map((t) => [t.code, t])).values()) {
216
- const name = String(thread.nombre || '').trim().split(/\s+/)[0];
217
- if (excludedCodes.has(thread.code) || !name) continue;
222
+ for (const [code, docs] of threadsByCode) {
223
+ const [thread] = docs.sort((a, b) => String(a._id).localeCompare(String(b._id)));
224
+ const name = firstWord(thread.nombre);
225
+ const names = new Set(docs.map((doc) => firstWord(doc.nombre).toLowerCase()));
226
+ if (excludedCodes.has(code) || !name || names.size !== 1 || !thread.patient_id) continue;
218
227
  candidates.push({
219
228
  source: SCOPE_SOURCE,
220
- patientId: thread.patient_id || null,
229
+ patientId: thread.patient_id,
221
230
  recordId: String(thread._id),
222
- code: thread.code,
231
+ code,
223
232
  name,
224
233
  reason: 'no_triage_history',
225
234
  rows: [],
@@ -286,7 +295,7 @@ async function rejectionReason(candidate, {
286
295
  } = {}) {
287
296
  const opsReason = opsOptedOut(candidate, { now });
288
297
  if (opsReason) return opsReason;
289
- if (await Thread.exists({ code: candidate.code, outreachOptOut: true })) return 'patient_follow_up_disabled';
298
+ if (await Thread.exists({ code: candidate.code, outreachOptOut: true })) return 'outreach_opt_out';
290
299
  if (await botIsPaused(candidate.code, { label: '[outreachSweep]' })) return 'bot_paused';
291
300
  if (!includePreviouslySwept) {
292
301
  const sweptReason = candidate.source === SCOPE_SOURCE
@@ -412,9 +421,8 @@ async function enrichBrief(candidate) {
412
421
  // contentSid and no idempotency key, so nothing downstream would catch a duplicate.
413
422
  async function claimCandidate({ candidate, weekdayLabel, dryRun, now }) {
414
423
  if (dryRun) return true;
415
- if (candidate.source === SCOPE_SOURCE) {
416
- return (await sweepClaims.acquire(sweepClaimKey(candidate, now))) === 'acquired';
417
- }
424
+ if ((await sweepClaims.acquire(sweepClaimKey(candidate, now))) !== 'acquired') return false;
425
+ if (candidate.source === SCOPE_SOURCE) return true;
418
426
  try {
419
427
  const claimed = await airtableService.updateRecordByFilter(
420
428
  Symptoms_ID,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@peopl-health/nexus",
3
- "version": "5.69.0-dev.12623",
3
+ "version": "5.69.0-dev.12624",
4
4
  "description": "Core messaging and assistant library for WhatsApp communication platforms",
5
5
  "keywords": [
6
6
  "whatsapp",