@aleonnet/healthcare-scheduler 0.1.21 → 0.1.24

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.
Files changed (41) hide show
  1. package/dist/database/adapters/SupabaseAdapter.d.ts.map +1 -1
  2. package/dist/database/adapters/SupabaseAdapter.js +6 -3
  3. package/dist/database/adapters/SupabaseAdapter.js.map +1 -1
  4. package/dist/database/repositories/ItemsRepository.d.ts.map +1 -1
  5. package/dist/database/repositories/ItemsRepository.js +21 -1
  6. package/dist/database/repositories/ItemsRepository.js.map +1 -1
  7. package/dist/database/repositories/OccurrencesRepository.d.ts.map +1 -1
  8. package/dist/database/repositories/OccurrencesRepository.js +14 -1
  9. package/dist/database/repositories/OccurrencesRepository.js.map +1 -1
  10. package/dist/index.d.ts +0 -1
  11. package/dist/index.d.ts.map +1 -1
  12. package/dist/index.js +1 -3
  13. package/dist/index.js.map +1 -1
  14. package/dist/plugins/InventoryPlugin.js +0 -1
  15. package/dist/plugins/InventoryPlugin.js.map +1 -1
  16. package/dist/plugins/SyncPluginEventDriven.d.ts.map +1 -1
  17. package/dist/plugins/SyncPluginEventDriven.js +19 -6
  18. package/dist/plugins/SyncPluginEventDriven.js.map +1 -1
  19. package/dist/plugins/gamification/GamificationPlugin.d.ts.map +1 -1
  20. package/dist/plugins/gamification/GamificationPlugin.js +4 -2
  21. package/dist/plugins/gamification/GamificationPlugin.js.map +1 -1
  22. package/dist/reconciler/WindowScheduler beta.d.ts +32 -0
  23. package/dist/reconciler/WindowScheduler beta.d.ts.map +1 -0
  24. package/dist/reconciler/WindowScheduler beta.js +416 -0
  25. package/dist/reconciler/WindowScheduler beta.js.map +1 -0
  26. package/dist/reconciler/WindowScheduler.d.ts.map +1 -1
  27. package/dist/reconciler/WindowScheduler.js +18 -8
  28. package/dist/reconciler/WindowScheduler.js.map +1 -1
  29. package/package.json +1 -1
  30. package/dist/plugins/SyncPluginPolling.d.ts +0 -24
  31. package/dist/plugins/SyncPluginPolling.d.ts.map +0 -1
  32. package/dist/plugins/SyncPluginPolling.js +0 -266
  33. package/dist/plugins/SyncPluginPolling.js.map +0 -1
  34. package/dist/plugins/gamification/__tests__/hysteresis.spec.d.ts +0 -2
  35. package/dist/plugins/gamification/__tests__/hysteresis.spec.d.ts.map +0 -1
  36. package/dist/plugins/gamification/__tests__/hysteresis.spec.js +0 -22
  37. package/dist/plugins/gamification/__tests__/hysteresis.spec.js.map +0 -1
  38. package/dist/services/MedicationsServiceCompat.d.ts +0 -24
  39. package/dist/services/MedicationsServiceCompat.d.ts.map +0 -1
  40. package/dist/services/MedicationsServiceCompat.js +0 -98
  41. package/dist/services/MedicationsServiceCompat.js.map +0 -1
@@ -0,0 +1,32 @@
1
+ import { PlansRepository, OccurrencesRepository } from '../database/repositories';
2
+ import { NotificationDriver } from '../core/types';
3
+ import { EventBus } from '../core/EventBus';
4
+ export declare class WindowScheduler {
5
+ private plansRepo;
6
+ private occurrencesRepo;
7
+ private notificationDriver;
8
+ private eventBus;
9
+ private groupSameTime;
10
+ private snoozeMinutes;
11
+ private static opQueue;
12
+ private runSerial;
13
+ constructor(plansRepo: PlansRepository, occurrencesRepo: OccurrencesRepository, notificationDriver: NotificationDriver, eventBus: EventBus);
14
+ setGroupSameTime(enabled: boolean): void;
15
+ setSnoozeMinutes(minutes: number): void;
16
+ private getReminderOffset;
17
+ fillWindow(options?: {
18
+ days?: number;
19
+ }): Promise<void>;
20
+ reconcileWithOS(options?: {
21
+ horizonDays?: number;
22
+ includePastDay?: boolean;
23
+ }): Promise<void>;
24
+ updateWindow(options?: {
25
+ days?: number;
26
+ }): Promise<void>;
27
+ private formatNotificationTitle;
28
+ private formatNotificationBody;
29
+ private getItemTypeEmoji;
30
+ private inferQtyUnit;
31
+ }
32
+ //# sourceMappingURL=WindowScheduler%20beta.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"WindowScheduler beta.d.ts","sourceRoot":"","sources":["../../src/reconciler/WindowScheduler beta.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,eAAe,EAAE,qBAAqB,EAAE,MAAM,0BAA0B,CAAC;AAGlF,OAAO,EAAE,kBAAkB,EAAc,MAAM,eAAe,CAAC;AAC/D,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAM5C,qBAAa,eAAe;IAWxB,OAAO,CAAC,SAAS;IACjB,OAAO,CAAC,eAAe;IACvB,OAAO,CAAC,kBAAkB;IAC1B,OAAO,CAAC,QAAQ;IAblB,OAAO,CAAC,aAAa,CAAkB;IACvC,OAAO,CAAC,aAAa,CAAc;IAEnC,OAAO,CAAC,MAAM,CAAC,OAAO,CAAmC;IACzD,OAAO,CAAC,SAAS;gBAMP,SAAS,EAAE,eAAe,EAC1B,eAAe,EAAE,qBAAqB,EACtC,kBAAkB,EAAE,kBAAkB,EACtC,QAAQ,EAAE,QAAQ;IAM5B,gBAAgB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI;IAOxC,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;YAOzB,iBAAiB;IAiBzB,UAAU,CAAC,OAAO,GAAE;QAAE,IAAI,CAAC,EAAE,MAAM,CAAA;KAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IA0E1D,eAAe,CAAC,OAAO,GAAE;QAAE,WAAW,CAAC,EAAE,MAAM,CAAC;QAAC,cAAc,CAAC,EAAE,OAAO,CAAA;KAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IA4ShG,YAAY,CAAC,OAAO,GAAE;QAAE,IAAI,CAAC,EAAE,MAAM,CAAA;KAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IAWlE,OAAO,CAAC,uBAAuB;IAW/B,OAAO,CAAC,sBAAsB;IAiB9B,OAAO,CAAC,gBAAgB;IAcxB,OAAO,CAAC,YAAY;CASrB"}
@@ -0,0 +1,416 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.WindowScheduler = void 0;
4
+ const expandPlan_1 = require("../planning/expandPlan");
5
+ const windowPlanner_1 = require("../planning/windowPlanner");
6
+ const timestamp_1 = require("../utils/timestamp");
7
+ class WindowScheduler {
8
+ runSerial(task) {
9
+ WindowScheduler.opQueue = WindowScheduler.opQueue.then(task, task);
10
+ return WindowScheduler.opQueue;
11
+ }
12
+ constructor(plansRepo, occurrencesRepo, notificationDriver, eventBus) {
13
+ this.plansRepo = plansRepo;
14
+ this.occurrencesRepo = occurrencesRepo;
15
+ this.notificationDriver = notificationDriver;
16
+ this.eventBus = eventBus;
17
+ this.groupSameTime = false;
18
+ this.snoozeMinutes = 15;
19
+ }
20
+ setGroupSameTime(enabled) {
21
+ this.groupSameTime = enabled;
22
+ }
23
+ setSnoozeMinutes(minutes) {
24
+ this.snoozeMinutes = minutes;
25
+ }
26
+ async getReminderOffset(planId) {
27
+ try {
28
+ const plan = await this.plansRepo.findById(planId);
29
+ if (plan && plan.meta && typeof plan.meta.reminder_offset === 'string') {
30
+ return plan.meta.reminder_offset;
31
+ }
32
+ }
33
+ catch (error) {
34
+ }
35
+ return undefined;
36
+ }
37
+ async fillWindow(options = {}) {
38
+ return await this.runSerial(async () => {
39
+ const { days = 14 } = options;
40
+ try {
41
+ const now = new Date();
42
+ const end = new Date(now.getTime());
43
+ end.setDate(end.getDate() + Math.max(0, days - 1));
44
+ const startKey = `${now.getFullYear()}-${String(now.getMonth() + 1).padStart(2, '0')}-${String(now.getDate()).padStart(2, '0')}`;
45
+ const endKey = `${end.getFullYear()}-${String(end.getMonth() + 1).padStart(2, '0')}-${String(end.getDate()).padStart(2, '0')}`;
46
+ console.log(`📅 Filling window: days=${days} (${startKey} → ${endKey})`);
47
+ const plans = await this.plansRepo.findActive(now);
48
+ if (!plans.length) {
49
+ console.log('📅 No active plans found');
50
+ return;
51
+ }
52
+ console.log(`📅 Found ${plans.length} active plans`);
53
+ for (const plan of plans) {
54
+ await this.occurrencesRepo.deleteByPlanIdAfter(plan.id, now.toISOString());
55
+ }
56
+ const allOccurrences = [];
57
+ for (const plan of plans) {
58
+ try {
59
+ const expanded = (0, expandPlan_1.expandPlan)(plan.schedule_rule, now);
60
+ const windowed = (0, windowPlanner_1.selectWindow)(expanded, { windowDays: days, maxPending: 1000 });
61
+ const dbOccurrences = windowed.map(occ => ({
62
+ id: `${plan.id}:${occ.scheduledAt}`,
63
+ plan_id: plan.id,
64
+ scheduled_at: occ.scheduledAt,
65
+ kind: (plan.item_type || 'MED'),
66
+ qty: occ.qty || 1
67
+ }));
68
+ allOccurrences.push(...dbOccurrences);
69
+ }
70
+ catch (error) {
71
+ console.error(`❌ Error expanding plan ${plan.id}:`, error);
72
+ }
73
+ }
74
+ if (allOccurrences.length) {
75
+ await this.occurrencesRepo.insertMany(allOccurrences);
76
+ console.log(`📅 ${allOccurrences.length} occurrences synced`);
77
+ }
78
+ this.eventBus.emit('window:filled', { count: allOccurrences.length });
79
+ }
80
+ catch (error) {
81
+ console.error('❌ Error filling window:', error);
82
+ throw error;
83
+ }
84
+ });
85
+ }
86
+ async reconcileWithOS(options = {}) {
87
+ return await this.runSerial(async () => {
88
+ const { horizonDays = 2, includePastDay = false } = options;
89
+ try {
90
+ const pendingOccs = await this.occurrencesRepo.getUpcomingWindow({
91
+ days: Math.max(1, horizonDays),
92
+ limit: 50,
93
+ pastDays: includePastDay ? 1 : 0
94
+ });
95
+ const pending = pendingOccs.filter(occ => occ.status === 'PENDING');
96
+ const scheduledNotifs = await this.notificationDriver.listScheduled();
97
+ console.log(`🔄 Reconciling (horizon=${horizonDays}d, cap=45, group=${this.groupSameTime ? 'on' : 'off'}): ${pending.length} pending, ${scheduledNotifs.length} scheduled in OS`);
98
+ const groups = new Map();
99
+ if (this.groupSameTime) {
100
+ for (const occ of pending) {
101
+ if (occ.kind !== 'MED')
102
+ continue;
103
+ const d = (0, timestamp_1.parseUTC)(occ.scheduled_at);
104
+ const key = `${occ.kind}:${d.getFullYear()}-${(d.getMonth() + 1).toString().padStart(2, '0')}-${d.getDate().toString().padStart(2, '0')}T${d.getHours().toString().padStart(2, '0')}:${d.getMinutes().toString().padStart(2, '0')}`;
105
+ if (!groups.has(key))
106
+ groups.set(key, []);
107
+ groups.get(key).push(occ);
108
+ }
109
+ }
110
+ const notifsByOccId = new Map();
111
+ const notifsByGroupKey = new Map();
112
+ const occIdsInScheduledGroups = new Set();
113
+ for (const notif of scheduledNotifs) {
114
+ const occId = notif.notification?.data?.occurrenceId;
115
+ if (occId) {
116
+ notifsByOccId.set(occId, notif.notification.id);
117
+ }
118
+ const gk = notif.notification?.data?.groupKey;
119
+ if (gk) {
120
+ let count = 0;
121
+ try {
122
+ const occIdsRaw = notif.notification?.data?.occurrenceIds;
123
+ const occIds = Array.isArray(occIdsRaw) ? occIdsRaw : (typeof occIdsRaw === 'string' ? (JSON.parse(occIdsRaw || '[]') || []) : []);
124
+ count = Array.isArray(occIds) ? occIds.length : 0;
125
+ if (Array.isArray(occIds)) {
126
+ for (const id of occIds)
127
+ occIdsInScheduledGroups.add(String(id));
128
+ }
129
+ }
130
+ catch { }
131
+ notifsByGroupKey.set(gk, { id: notif.notification?.id || '', count });
132
+ }
133
+ }
134
+ let scheduled = 0;
135
+ let cancelled = 0;
136
+ const now = new Date();
137
+ if (this.groupSameTime && groups.size > 0) {
138
+ for (const [key, occs] of groups) {
139
+ if (!occs || occs.length === 0)
140
+ continue;
141
+ const occ = occs.sort((a, b) => (0, timestamp_1.parseUTC)(a.scheduled_at).getTime() - (0, timestamp_1.parseUTC)(b.scheduled_at).getTime())[0];
142
+ const scheduledTime = (0, timestamp_1.parseUTC)(occ.scheduled_at);
143
+ const SAFETY_BUFFER_MS = 2000;
144
+ if (scheduledTime.getTime() <= now.getTime() + SAFETY_BUFFER_MS)
145
+ continue;
146
+ if (occs.length < 2) {
147
+ continue;
148
+ }
149
+ try {
150
+ const hh = scheduledTime.getHours().toString().padStart(2, '0');
151
+ const mm = scheduledTime.getMinutes().toString().padStart(2, '0');
152
+ const groupKey = key;
153
+ const legacyDailyKey = `${occ.kind}:HH:${hh}:${mm}`;
154
+ const names = occs.map((o) => o.item_name).filter(Boolean);
155
+ const namesShort = names.slice(0, 2).join(', ') + (names.length > 2 ? ` +${names.length - 2}` : '');
156
+ const title = `💊 ${occs.length} medicamentos agora`;
157
+ const body = namesShort ? `${hh}:${mm} • ${namesShort}` : `${hh}:${mm}`;
158
+ const existing = notifsByGroupKey.get(groupKey);
159
+ if (existing && Number(existing.count || 0) === occs.length) {
160
+ continue;
161
+ }
162
+ try {
163
+ await this.notificationDriver.cancelTriggerByGroup(groupKey);
164
+ }
165
+ catch { }
166
+ try {
167
+ await this.notificationDriver.cancelTriggerByGroup(legacyDailyKey);
168
+ }
169
+ catch { }
170
+ for (const o of occs) {
171
+ try {
172
+ await this.notificationDriver.cancelTriggerByOccurrence(o.id);
173
+ }
174
+ catch { }
175
+ }
176
+ await this.notificationDriver.scheduleGroupTrigger({
177
+ groupKey,
178
+ occurrenceIds: occs.map((o) => o.id),
179
+ itemType: occ.kind,
180
+ itemId: occ.item_id || occ.plan_id,
181
+ title,
182
+ body,
183
+ scheduledAt: scheduledTime,
184
+ snoozeMin: this.snoozeMinutes
185
+ });
186
+ scheduled++;
187
+ }
188
+ catch (error) {
189
+ console.error(`❌ Error scheduling group ${key}:`, error);
190
+ }
191
+ }
192
+ const groupedOccIds = new Set();
193
+ for (const occs of groups.values()) {
194
+ if (occs && occs.length >= 2) {
195
+ for (const o of occs)
196
+ groupedOccIds.add(o.id);
197
+ }
198
+ }
199
+ const remainder = pending.filter((o) => o.kind !== 'MED' || !groupedOccIds.has(o.id));
200
+ for (const occ of remainder.slice(0, 45)) {
201
+ const occId = occ.id;
202
+ const isScheduled = notifsByOccId.has(occId);
203
+ const scheduledTime = (0, timestamp_1.parseUTC)(occ.scheduled_at);
204
+ if (scheduledTime.getTime() <= now.getTime()) {
205
+ continue;
206
+ }
207
+ if (!isScheduled) {
208
+ try {
209
+ const reminderOffset = (occ.kind === 'APPT' || occ.kind === 'TEST')
210
+ ? await this.getReminderOffset(occ.plan_id)
211
+ : undefined;
212
+ await this.notificationDriver.scheduleTrigger({
213
+ occurrenceId: occId,
214
+ itemType: occ.kind,
215
+ itemId: occ.item_id || occ.plan_id,
216
+ title: this.formatNotificationTitle(occ),
217
+ body: this.formatNotificationBody(occ),
218
+ scheduledAt: scheduledTime,
219
+ snoozeMin: this.snoozeMinutes,
220
+ reminderOffset
221
+ });
222
+ scheduled++;
223
+ }
224
+ catch (error) {
225
+ console.error(`❌ Error scheduling ${occId}:`, error);
226
+ }
227
+ }
228
+ }
229
+ }
230
+ else {
231
+ for (const occ of pending.slice(0, 45)) {
232
+ const occId = occ.id;
233
+ const isScheduled = notifsByOccId.has(occId);
234
+ const scheduledTime = (0, timestamp_1.parseUTC)(occ.scheduled_at);
235
+ if (scheduledTime.getTime() <= now.getTime())
236
+ continue;
237
+ if (!isScheduled) {
238
+ try {
239
+ const reminderOffset = (occ.kind === 'APPT' || occ.kind === 'TEST')
240
+ ? await this.getReminderOffset(occ.plan_id)
241
+ : undefined;
242
+ await this.notificationDriver.scheduleTrigger({
243
+ occurrenceId: occId,
244
+ itemType: occ.kind,
245
+ itemId: occ.item_id || occ.plan_id,
246
+ title: this.formatNotificationTitle(occ),
247
+ body: this.formatNotificationBody(occ),
248
+ scheduledAt: scheduledTime,
249
+ snoozeMin: this.snoozeMinutes,
250
+ reminderOffset
251
+ });
252
+ scheduled++;
253
+ }
254
+ catch (error) {
255
+ console.error(`❌ Error scheduling ${occId}:`, error);
256
+ }
257
+ }
258
+ }
259
+ }
260
+ try {
261
+ if (this.groupSameTime) {
262
+ const validGroupKeys = new Set();
263
+ for (const key of groups.keys())
264
+ validGroupKeys.add(key);
265
+ for (const [gk] of notifsByGroupKey)
266
+ validGroupKeys.add(gk);
267
+ for (const [gk] of notifsByGroupKey) {
268
+ if (!validGroupKeys.has(gk)) {
269
+ try {
270
+ await this.notificationDriver.cancelTriggerByGroup(gk);
271
+ cancelled++;
272
+ }
273
+ catch { }
274
+ }
275
+ }
276
+ }
277
+ else {
278
+ for (const [gk] of notifsByGroupKey) {
279
+ try {
280
+ await this.notificationDriver.cancelTriggerByGroup(gk);
281
+ cancelled++;
282
+ }
283
+ catch { }
284
+ }
285
+ }
286
+ }
287
+ catch { }
288
+ try {
289
+ const snoozedToCheck = pendingOccs.filter(o => String(o.last_action || '').toUpperCase() === 'SNOOZED');
290
+ for (const occ of snoozedToCheck) {
291
+ if (occIdsInScheduledGroups.has(String(occ.id))) {
292
+ continue;
293
+ }
294
+ const lastAt = occ.last_action_at ? (0, timestamp_1.parseUTC)(occ.last_action_at) : null;
295
+ let snoozeMin = 0;
296
+ try {
297
+ const payload = occ.last_action_payload ? JSON.parse(occ.last_action_payload) : null;
298
+ snoozeMin = Number(payload?.snoozeMin || 0);
299
+ }
300
+ catch { }
301
+ if (!lastAt || !snoozeMin || Number.isNaN(snoozeMin))
302
+ continue;
303
+ const snoozeUntil = new Date(lastAt.getTime() + snoozeMin * 60 * 1000);
304
+ if (snoozeUntil.getTime() <= now.getTime())
305
+ continue;
306
+ const isScheduled = notifsByOccId.has(occ.id);
307
+ if (!isScheduled) {
308
+ try {
309
+ await this.notificationDriver.scheduleTrigger({
310
+ occurrenceId: occ.id,
311
+ itemType: occ.kind,
312
+ itemId: occ.item_id || occ.plan_id,
313
+ title: this.formatNotificationTitle(occ),
314
+ body: this.formatNotificationBody(occ),
315
+ scheduledAt: snoozeUntil,
316
+ snoozeMin: this.snoozeMinutes
317
+ });
318
+ scheduled++;
319
+ }
320
+ catch (e) {
321
+ console.error('❌ Error re-scheduling snooze', occ.id, e);
322
+ }
323
+ }
324
+ }
325
+ }
326
+ catch { }
327
+ const validOccIds = new Set(pending.map(occ => occ.id));
328
+ try {
329
+ const snoozedValid = pendingOccs.filter(o => String(o.last_action || '').toUpperCase() === 'SNOOZED');
330
+ for (const occ of snoozedValid) {
331
+ const lastAt = occ.last_action_at ? (0, timestamp_1.parseUTC)(occ.last_action_at) : null;
332
+ let snoozeMin = 0;
333
+ try {
334
+ const payload = occ.last_action_payload ? JSON.parse(occ.last_action_payload) : null;
335
+ snoozeMin = Number(payload?.snoozeMin || 0);
336
+ }
337
+ catch { }
338
+ if (!lastAt || !snoozeMin || Number.isNaN(snoozeMin))
339
+ continue;
340
+ const snoozeUntil = new Date(lastAt.getTime() + snoozeMin * 60 * 1000);
341
+ if (snoozeUntil.getTime() > now.getTime()) {
342
+ validOccIds.add(occ.id);
343
+ }
344
+ }
345
+ }
346
+ catch { }
347
+ for (const [occId] of notifsByOccId) {
348
+ if (!validOccIds.has(occId)) {
349
+ try {
350
+ await this.notificationDriver.cancelTriggerByOccurrence(occId);
351
+ cancelled++;
352
+ }
353
+ catch (error) {
354
+ console.error(`❌ Error canceling ${occId}:`, error);
355
+ }
356
+ }
357
+ }
358
+ console.log(`🔄 Reconciliation complete (horizon=${horizonDays}d, cap=45): ${scheduled} scheduled, ${cancelled} canceled`);
359
+ this.eventBus.emit('notifications:reconciled', { scheduled, cancelled });
360
+ }
361
+ catch (error) {
362
+ console.error('❌ Error in reconciliation:', error);
363
+ throw error;
364
+ }
365
+ });
366
+ }
367
+ async updateWindow(options = {}) {
368
+ await this.fillWindow(options);
369
+ await this.reconcileWithOS();
370
+ }
371
+ formatNotificationTitle(occ) {
372
+ const name = occ.item_name || 'Lembrete';
373
+ const dose = occ?.item_meta?.concentration ? ` ${occ.item_meta.concentration}` : '';
374
+ if (occ.kind === 'MED')
375
+ return `${name}${dose}`.trim();
376
+ return `${this.getItemTypeEmoji(occ.kind)} ${name}`.trim();
377
+ }
378
+ formatNotificationBody(occ) {
379
+ const time = (0, timestamp_1.parseUTC)(occ.scheduled_at).toLocaleTimeString('pt-BR', {
380
+ hour: '2-digit',
381
+ minute: '2-digit'
382
+ });
383
+ const qtyLabel = occ?.qty && occ.qty > 0 ? `${occ.qty} ${this.inferQtyUnit(occ)}` : null;
384
+ const parts = [];
385
+ if (qtyLabel)
386
+ parts.push(qtyLabel);
387
+ parts.push(time);
388
+ return parts.join(' • ');
389
+ }
390
+ getItemTypeEmoji(itemType) {
391
+ switch (itemType) {
392
+ case 'MED': return '💊';
393
+ case 'APPT': return '🏥';
394
+ case 'TEST': return '🔬';
395
+ case 'METRIC': return '📊';
396
+ default: return '⏰';
397
+ }
398
+ }
399
+ inferQtyUnit(occ) {
400
+ const form = String(occ?.item_meta?.form || '').toLowerCase();
401
+ if (!form)
402
+ return 'unidade';
403
+ if (form.includes('comprimido'))
404
+ return 'comprimido';
405
+ if (form.includes('cápsula'))
406
+ return 'cápsula';
407
+ if (form.includes('gota'))
408
+ return 'gota';
409
+ if (form.includes('ml'))
410
+ return 'ml';
411
+ return 'unidade';
412
+ }
413
+ }
414
+ exports.WindowScheduler = WindowScheduler;
415
+ WindowScheduler.opQueue = Promise.resolve();
416
+ //# sourceMappingURL=WindowScheduler%20beta.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"WindowScheduler beta.js","sourceRoot":"","sources":["../../src/reconciler/WindowScheduler beta.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"WindowScheduler.d.ts","sourceRoot":"","sources":["../../src/reconciler/WindowScheduler.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,eAAe,EAAE,qBAAqB,EAAE,MAAM,0BAA0B,CAAC;AAGlF,OAAO,EAAE,kBAAkB,EAAc,MAAM,eAAe,CAAC;AAC/D,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAM5C,qBAAa,eAAe;IAWxB,OAAO,CAAC,SAAS;IACjB,OAAO,CAAC,eAAe;IACvB,OAAO,CAAC,kBAAkB;IAC1B,OAAO,CAAC,QAAQ;IAblB,OAAO,CAAC,aAAa,CAAkB;IACvC,OAAO,CAAC,aAAa,CAAc;IAEnC,OAAO,CAAC,MAAM,CAAC,OAAO,CAAmC;IACzD,OAAO,CAAC,SAAS;gBAMP,SAAS,EAAE,eAAe,EAC1B,eAAe,EAAE,qBAAqB,EACtC,kBAAkB,EAAE,kBAAkB,EACtC,QAAQ,EAAE,QAAQ;IAM5B,gBAAgB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI;IAOxC,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;YAOzB,iBAAiB;IAiBzB,UAAU,CAAC,OAAO,GAAE;QAAE,IAAI,CAAC,EAAE,MAAM,CAAA;KAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IAwE1D,eAAe,CAAC,OAAO,GAAE;QAAE,WAAW,CAAC,EAAE,MAAM,CAAC;QAAC,cAAc,CAAC,EAAE,OAAO,CAAA;KAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IAqShG,YAAY,CAAC,OAAO,GAAE;QAAE,IAAI,CAAC,EAAE,MAAM,CAAA;KAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IAWlE,OAAO,CAAC,uBAAuB;IAW/B,OAAO,CAAC,sBAAsB;IAiB9B,OAAO,CAAC,gBAAgB;IAcxB,OAAO,CAAC,YAAY;CASrB"}
1
+ {"version":3,"file":"WindowScheduler.d.ts","sourceRoot":"","sources":["../../src/reconciler/WindowScheduler.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,eAAe,EAAE,qBAAqB,EAAE,MAAM,0BAA0B,CAAC;AAGlF,OAAO,EAAE,kBAAkB,EAAc,MAAM,eAAe,CAAC;AAC/D,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAM5C,qBAAa,eAAe;IAWxB,OAAO,CAAC,SAAS;IACjB,OAAO,CAAC,eAAe;IACvB,OAAO,CAAC,kBAAkB;IAC1B,OAAO,CAAC,QAAQ;IAblB,OAAO,CAAC,aAAa,CAAkB;IACvC,OAAO,CAAC,aAAa,CAAc;IAEnC,OAAO,CAAC,MAAM,CAAC,OAAO,CAAmC;IACzD,OAAO,CAAC,SAAS;gBAMP,SAAS,EAAE,eAAe,EAC1B,eAAe,EAAE,qBAAqB,EACtC,kBAAkB,EAAE,kBAAkB,EACtC,QAAQ,EAAE,QAAQ;IAM5B,gBAAgB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI;IAOxC,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;YAOzB,iBAAiB;IAiBzB,UAAU,CAAC,OAAO,GAAE;QAAE,IAAI,CAAC,EAAE,MAAM,CAAA;KAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IA0E1D,eAAe,CAAC,OAAO,GAAE;QAAE,WAAW,CAAC,EAAE,MAAM,CAAC;QAAC,cAAc,CAAC,EAAE,OAAO,CAAA;KAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IA4ShG,YAAY,CAAC,OAAO,GAAE;QAAE,IAAI,CAAC,EAAE,MAAM,CAAA;KAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IAWlE,OAAO,CAAC,uBAAuB;IAW/B,OAAO,CAAC,sBAAsB;IAiB9B,OAAO,CAAC,gBAAgB;IAcxB,OAAO,CAAC,YAAY;CASrB"}
@@ -38,8 +38,12 @@ class WindowScheduler {
38
38
  return await this.runSerial(async () => {
39
39
  const { days = 14 } = options;
40
40
  try {
41
- console.log(`📅 Filling ${days}-day window...`);
42
41
  const now = new Date();
42
+ const end = new Date(now.getTime());
43
+ end.setDate(end.getDate() + Math.max(0, days - 1));
44
+ const startKey = `${now.getFullYear()}-${String(now.getMonth() + 1).padStart(2, '0')}-${String(now.getDate()).padStart(2, '0')}`;
45
+ const endKey = `${end.getFullYear()}-${String(end.getMonth() + 1).padStart(2, '0')}-${String(end.getDate()).padStart(2, '0')}`;
46
+ console.log(`📅 Filling window: days=${days} (${startKey} → ${endKey})`);
43
47
  const plans = await this.plansRepo.findActive(now);
44
48
  if (!plans.length) {
45
49
  console.log('📅 No active plans found');
@@ -62,7 +66,6 @@ class WindowScheduler {
62
66
  qty: occ.qty || 1
63
67
  }));
64
68
  allOccurrences.push(...dbOccurrences);
65
- console.log(`📅 Plan ${plan.id}: ${dbOccurrences.length} occurrences`);
66
69
  }
67
70
  catch (error) {
68
71
  console.error(`❌ Error expanding plan ${plan.id}:`, error);
@@ -106,6 +109,7 @@ class WindowScheduler {
106
109
  }
107
110
  const notifsByOccId = new Map();
108
111
  const notifsByGroupKey = new Map();
112
+ const occIdsInScheduledGroups = new Set();
109
113
  for (const notif of scheduledNotifs) {
110
114
  const occId = notif.notification?.data?.occurrenceId;
111
115
  if (occId) {
@@ -118,6 +122,10 @@ class WindowScheduler {
118
122
  const occIdsRaw = notif.notification?.data?.occurrenceIds;
119
123
  const occIds = Array.isArray(occIdsRaw) ? occIdsRaw : (typeof occIdsRaw === 'string' ? (JSON.parse(occIdsRaw || '[]') || []) : []);
120
124
  count = Array.isArray(occIds) ? occIds.length : 0;
125
+ if (Array.isArray(occIds)) {
126
+ for (const id of occIds)
127
+ occIdsInScheduledGroups.add(String(id));
128
+ }
121
129
  }
122
130
  catch { }
123
131
  notifsByGroupKey.set(gk, { id: notif.notification?.id || '', count });
@@ -254,6 +262,8 @@ class WindowScheduler {
254
262
  const validGroupKeys = new Set();
255
263
  for (const key of groups.keys())
256
264
  validGroupKeys.add(key);
265
+ for (const [gk] of notifsByGroupKey)
266
+ validGroupKeys.add(gk);
257
267
  for (const [gk] of notifsByGroupKey) {
258
268
  if (!validGroupKeys.has(gk)) {
259
269
  try {
@@ -278,7 +288,10 @@ class WindowScheduler {
278
288
  try {
279
289
  const snoozedToCheck = pendingOccs.filter(o => String(o.last_action || '').toUpperCase() === 'SNOOZED');
280
290
  for (const occ of snoozedToCheck) {
281
- const lastAt = occ.last_action_at ? new Date(occ.last_action_at) : null;
291
+ if (occIdsInScheduledGroups.has(String(occ.id))) {
292
+ continue;
293
+ }
294
+ const lastAt = occ.last_action_at ? (0, timestamp_1.parseUTC)(occ.last_action_at) : null;
282
295
  let snoozeMin = 0;
283
296
  try {
284
297
  const payload = occ.last_action_payload ? JSON.parse(occ.last_action_payload) : null;
@@ -303,7 +316,6 @@ class WindowScheduler {
303
316
  snoozeMin: this.snoozeMinutes
304
317
  });
305
318
  scheduled++;
306
- console.log('🔁 Snooze re-scheduled by reconcile for', occ.id);
307
319
  }
308
320
  catch (e) {
309
321
  console.error('❌ Error re-scheduling snooze', occ.id, e);
@@ -316,7 +328,7 @@ class WindowScheduler {
316
328
  try {
317
329
  const snoozedValid = pendingOccs.filter(o => String(o.last_action || '').toUpperCase() === 'SNOOZED');
318
330
  for (const occ of snoozedValid) {
319
- const lastAt = occ.last_action_at ? new Date(occ.last_action_at) : null;
331
+ const lastAt = occ.last_action_at ? (0, timestamp_1.parseUTC)(occ.last_action_at) : null;
320
332
  let snoozeMin = 0;
321
333
  try {
322
334
  const payload = occ.last_action_payload ? JSON.parse(occ.last_action_payload) : null;
@@ -343,9 +355,7 @@ class WindowScheduler {
343
355
  }
344
356
  }
345
357
  }
346
- if (scheduled > 0 || cancelled > 0) {
347
- console.log(`🔄 Reconciliation complete (horizon=${horizonDays}d, cap=45): ${scheduled} scheduled, ${cancelled} canceled`);
348
- }
358
+ console.log(`🔄 Reconciliation complete (horizon=${horizonDays}d, cap=45): ${scheduled} scheduled, ${cancelled} canceled`);
349
359
  this.eventBus.emit('notifications:reconciled', { scheduled, cancelled });
350
360
  }
351
361
  catch (error) {