@nativesquare/soma 0.18.0 → 0.18.1

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.
@@ -45,7 +45,11 @@ import { transformMenstrualCycleTracking } from "./transform/menstrualCycleTrack
45
45
  * and transforms each activity. Does not write to the database.
46
46
  */
47
47
  export const processActivityPushPayload = internalAction({
48
- args: { payload: v.any() },
48
+ args: {
49
+ payload: v.any(),
50
+ // Only consumed by push processors; ping processors ignore it.
51
+ rawPassthrough: v.optional(v.boolean()),
52
+ },
49
53
  handler: async (ctx, args) => {
50
54
  const { activities } = garminActivityPushPayloadSchema.parse(args.payload);
51
55
  const items = [];
@@ -85,7 +89,9 @@ export const processActivityPushPayload = internalAction({
85
89
  }
86
90
  for (const item of userItems) {
87
91
  try {
88
- const data = transformActivity(item);
92
+ const data = args.rawPassthrough
93
+ ? item
94
+ : transformActivity(item);
89
95
  items.push({ connectionId: connection._id, userId: connection.userId, data });
90
96
  }
91
97
  catch (err) {
@@ -106,7 +112,11 @@ export const processActivityPushPayload = internalAction({
106
112
  * Stub — acknowledges the notification without fetching data.
107
113
  */
108
114
  export const processActivityPingPayload = internalAction({
109
- args: { payload: v.any() },
115
+ args: {
116
+ payload: v.any(),
117
+ // Only consumed by push processors; ping processors ignore it.
118
+ rawPassthrough: v.optional(v.boolean()),
119
+ },
110
120
  handler: async (_ctx, args) => {
111
121
  const { activities } = garminActivityPingPayloadSchema.parse(args.payload);
112
122
  console.log(`[garmin:webhook:activities] Ping mode not yet implemented, acknowledging ${activities.length} items`);
@@ -121,7 +131,11 @@ export const processActivityPingPayload = internalAction({
121
131
  * Does not write to the database.
122
132
  */
123
133
  export const processActivityDetailsPushPayload = internalAction({
124
- args: { payload: v.any() },
134
+ args: {
135
+ payload: v.any(),
136
+ // Only consumed by push processors; ping processors ignore it.
137
+ rawPassthrough: v.optional(v.boolean()),
138
+ },
125
139
  handler: async (ctx, args) => {
126
140
  const { activityDetails } = garminActivityDetailsPushPayloadSchema.parse(args.payload);
127
141
  const items = [];
@@ -161,7 +175,9 @@ export const processActivityDetailsPushPayload = internalAction({
161
175
  }
162
176
  for (const item of userItems) {
163
177
  try {
164
- const data = transformActivityDetails(item);
178
+ const data = args.rawPassthrough
179
+ ? item
180
+ : transformActivityDetails(item);
165
181
  items.push({ connectionId: connection._id, userId: connection.userId, data });
166
182
  }
167
183
  catch (err) {
@@ -182,7 +198,11 @@ export const processActivityDetailsPushPayload = internalAction({
182
198
  * Stub — acknowledges the notification without fetching data.
183
199
  */
184
200
  export const processActivityDetailsPingPayload = internalAction({
185
- args: { payload: v.any() },
201
+ args: {
202
+ payload: v.any(),
203
+ // Only consumed by push processors; ping processors ignore it.
204
+ rawPassthrough: v.optional(v.boolean()),
205
+ },
186
206
  handler: async (_ctx, args) => {
187
207
  const { activityDetails } = garminActivityDetailsPingPayloadSchema.parse(args.payload);
188
208
  console.log(`[garmin:webhook:activityDetails] Ping mode not yet implemented, acknowledging ${activityDetails.length} items`);
@@ -196,7 +216,11 @@ export const processActivityDetailsPingPayload = internalAction({
196
216
  * and transforms each activity. Does not write to the database.
197
217
  */
198
218
  export const processManuallyUpdatedActivitiesPushPayload = internalAction({
199
- args: { payload: v.any() },
219
+ args: {
220
+ payload: v.any(),
221
+ // Only consumed by push processors; ping processors ignore it.
222
+ rawPassthrough: v.optional(v.boolean()),
223
+ },
200
224
  handler: async (ctx, args) => {
201
225
  const { manuallyUpdatedActivities } = garminManuallyUpdatedActivitiesPushPayloadSchema.parse(args.payload);
202
226
  const items = [];
@@ -236,7 +260,9 @@ export const processManuallyUpdatedActivitiesPushPayload = internalAction({
236
260
  }
237
261
  for (const item of userItems) {
238
262
  try {
239
- const data = transformManuallyUpdatedActivity(item);
263
+ const data = args.rawPassthrough
264
+ ? item
265
+ : transformManuallyUpdatedActivity(item);
240
266
  items.push({ connectionId: connection._id, userId: connection.userId, data });
241
267
  }
242
268
  catch (err) {
@@ -257,7 +283,11 @@ export const processManuallyUpdatedActivitiesPushPayload = internalAction({
257
283
  * Stub — acknowledges the notification without fetching data.
258
284
  */
259
285
  export const processManuallyUpdatedActivitiesPingPayload = internalAction({
260
- args: { payload: v.any() },
286
+ args: {
287
+ payload: v.any(),
288
+ // Only consumed by push processors; ping processors ignore it.
289
+ rawPassthrough: v.optional(v.boolean()),
290
+ },
261
291
  handler: async (_ctx, args) => {
262
292
  const { manuallyUpdatedActivities } = garminManuallyUpdatedActivitiesPingPayloadSchema.parse(args.payload);
263
293
  console.log(`[garmin:webhook:manuallyUpdatedActivities] Ping mode not yet implemented, acknowledging ${manuallyUpdatedActivities.length} items`);
@@ -272,7 +302,11 @@ export const processManuallyUpdatedActivitiesPingPayload = internalAction({
272
302
  * Does not write to the database.
273
303
  */
274
304
  export const processMoveIQPushPayload = internalAction({
275
- args: { payload: v.any() },
305
+ args: {
306
+ payload: v.any(),
307
+ // Only consumed by push processors; ping processors ignore it.
308
+ rawPassthrough: v.optional(v.boolean()),
309
+ },
276
310
  handler: async (ctx, args) => {
277
311
  const { moveIQActivities } = garminMoveIQPushPayloadSchema.parse(args.payload);
278
312
  const items = [];
@@ -312,7 +346,9 @@ export const processMoveIQPushPayload = internalAction({
312
346
  }
313
347
  for (const item of userItems) {
314
348
  try {
315
- const data = transformMoveIQ(item);
349
+ const data = args.rawPassthrough
350
+ ? item
351
+ : transformMoveIQ(item);
316
352
  items.push({ connectionId: connection._id, userId: connection.userId, data });
317
353
  }
318
354
  catch (err) {
@@ -333,7 +369,11 @@ export const processMoveIQPushPayload = internalAction({
333
369
  * Stub — acknowledges the notification without fetching data.
334
370
  */
335
371
  export const processMoveIQPingPayload = internalAction({
336
- args: { payload: v.any() },
372
+ args: {
373
+ payload: v.any(),
374
+ // Only consumed by push processors; ping processors ignore it.
375
+ rawPassthrough: v.optional(v.boolean()),
376
+ },
337
377
  handler: async (_ctx, args) => {
338
378
  const { moveIQActivities } = garminMoveIQPingPayloadSchema.parse(args.payload);
339
379
  console.log(`[garmin:webhook:moveIQ] Ping mode not yet implemented, acknowledging ${moveIQActivities.length} items`);
@@ -347,7 +387,11 @@ export const processMoveIQPingPayload = internalAction({
347
387
  * and transforms each record. Does not write to the database.
348
388
  */
349
389
  export const processBloodPressurePushPayload = internalAction({
350
- args: { payload: v.any() },
390
+ args: {
391
+ payload: v.any(),
392
+ // Only consumed by push processors; ping processors ignore it.
393
+ rawPassthrough: v.optional(v.boolean()),
394
+ },
351
395
  handler: async (ctx, args) => {
352
396
  const { bloodPressures } = garminBloodPressurePushPayloadSchema.parse(args.payload);
353
397
  const items = [];
@@ -387,7 +431,9 @@ export const processBloodPressurePushPayload = internalAction({
387
431
  }
388
432
  for (const item of userItems) {
389
433
  try {
390
- const data = transformBloodPressure(item);
434
+ const data = args.rawPassthrough
435
+ ? item
436
+ : transformBloodPressure(item);
391
437
  if (data == null)
392
438
  continue;
393
439
  items.push({ connectionId: connection._id, userId: connection.userId, data });
@@ -410,7 +456,11 @@ export const processBloodPressurePushPayload = internalAction({
410
456
  * Stub — acknowledges the notification without fetching data.
411
457
  */
412
458
  export const processBloodPressurePingPayload = internalAction({
413
- args: { payload: v.any() },
459
+ args: {
460
+ payload: v.any(),
461
+ // Only consumed by push processors; ping processors ignore it.
462
+ rawPassthrough: v.optional(v.boolean()),
463
+ },
414
464
  handler: async (_ctx, args) => {
415
465
  const { bloodPressures } = garminBloodPressurePingPayloadSchema.parse(args.payload);
416
466
  console.log(`[garmin:webhook:bloodPressures] Ping mode not yet implemented, acknowledging ${bloodPressures.length} items`);
@@ -424,7 +474,11 @@ export const processBloodPressurePingPayload = internalAction({
424
474
  * and transforms each record. Does not write to the database.
425
475
  */
426
476
  export const processBodyCompositionsPushPayload = internalAction({
427
- args: { payload: v.any() },
477
+ args: {
478
+ payload: v.any(),
479
+ // Only consumed by push processors; ping processors ignore it.
480
+ rawPassthrough: v.optional(v.boolean()),
481
+ },
428
482
  handler: async (ctx, args) => {
429
483
  const { bodyComps } = garminBodyCompositionsPushPayloadSchema.parse(args.payload);
430
484
  const items = [];
@@ -464,7 +518,9 @@ export const processBodyCompositionsPushPayload = internalAction({
464
518
  }
465
519
  for (const item of userItems) {
466
520
  try {
467
- const data = transformBodyComposition(item);
521
+ const data = args.rawPassthrough
522
+ ? item
523
+ : transformBodyComposition(item);
468
524
  if (data == null)
469
525
  continue;
470
526
  items.push({ connectionId: connection._id, userId: connection.userId, data });
@@ -487,7 +543,11 @@ export const processBodyCompositionsPushPayload = internalAction({
487
543
  * Stub — acknowledges the notification without fetching data.
488
544
  */
489
545
  export const processBodyCompositionsPingPayload = internalAction({
490
- args: { payload: v.any() },
546
+ args: {
547
+ payload: v.any(),
548
+ // Only consumed by push processors; ping processors ignore it.
549
+ rawPassthrough: v.optional(v.boolean()),
550
+ },
491
551
  handler: async (_ctx, args) => {
492
552
  const { bodyComps } = garminBodyCompositionsPingPayloadSchema.parse(args.payload);
493
553
  console.log(`[garmin:webhook:bodyCompositions] Ping mode not yet implemented, acknowledging ${bodyComps.length} items`);
@@ -501,7 +561,11 @@ export const processBodyCompositionsPingPayload = internalAction({
501
561
  * and transforms each record. Does not write to the database.
502
562
  */
503
563
  export const processDailiesPushPayload = internalAction({
504
- args: { payload: v.any() },
564
+ args: {
565
+ payload: v.any(),
566
+ // Only consumed by push processors; ping processors ignore it.
567
+ rawPassthrough: v.optional(v.boolean()),
568
+ },
505
569
  handler: async (ctx, args) => {
506
570
  const { dailies } = garminDailiesPushPayloadSchema.parse(args.payload);
507
571
  const items = [];
@@ -541,7 +605,9 @@ export const processDailiesPushPayload = internalAction({
541
605
  }
542
606
  for (const item of userItems) {
543
607
  try {
544
- const data = transformDailies(item);
608
+ const data = args.rawPassthrough
609
+ ? item
610
+ : transformDailies(item);
545
611
  if (data == null)
546
612
  continue;
547
613
  items.push({ connectionId: connection._id, userId: connection.userId, data });
@@ -564,7 +630,11 @@ export const processDailiesPushPayload = internalAction({
564
630
  * Stub — acknowledges the notification without fetching data.
565
631
  */
566
632
  export const processDailiesPingPayload = internalAction({
567
- args: { payload: v.any() },
633
+ args: {
634
+ payload: v.any(),
635
+ // Only consumed by push processors; ping processors ignore it.
636
+ rawPassthrough: v.optional(v.boolean()),
637
+ },
568
638
  handler: async (_ctx, args) => {
569
639
  const { dailies } = garminDailiesPingPayloadSchema.parse(args.payload);
570
640
  console.log(`[garmin:webhook:dailies] Ping mode not yet implemented, acknowledging ${dailies.length} items`);
@@ -578,7 +648,11 @@ export const processDailiesPingPayload = internalAction({
578
648
  * and transforms each record. Does not write to the database.
579
649
  */
580
650
  export const processHealthSnapshotPushPayload = internalAction({
581
- args: { payload: v.any() },
651
+ args: {
652
+ payload: v.any(),
653
+ // Only consumed by push processors; ping processors ignore it.
654
+ rawPassthrough: v.optional(v.boolean()),
655
+ },
582
656
  handler: async (ctx, args) => {
583
657
  const { healthSnapshot } = garminHealthSnapshotPushPayloadSchema.parse(args.payload);
584
658
  const items = [];
@@ -618,7 +692,9 @@ export const processHealthSnapshotPushPayload = internalAction({
618
692
  }
619
693
  for (const item of userItems) {
620
694
  try {
621
- const data = transformHealthSnapshot(item);
695
+ const data = args.rawPassthrough
696
+ ? item
697
+ : transformHealthSnapshot(item);
622
698
  if (data == null)
623
699
  continue;
624
700
  items.push({ connectionId: connection._id, userId: connection.userId, data });
@@ -641,7 +717,11 @@ export const processHealthSnapshotPushPayload = internalAction({
641
717
  * Stub — acknowledges the notification without fetching data.
642
718
  */
643
719
  export const processHealthSnapshotPingPayload = internalAction({
644
- args: { payload: v.any() },
720
+ args: {
721
+ payload: v.any(),
722
+ // Only consumed by push processors; ping processors ignore it.
723
+ rawPassthrough: v.optional(v.boolean()),
724
+ },
645
725
  handler: async (_ctx, args) => {
646
726
  const { healthSnapshot } = garminHealthSnapshotPingPayloadSchema.parse(args.payload);
647
727
  console.log(`[garmin:webhook:healthSnapshot] Ping mode not yet implemented, acknowledging ${healthSnapshot.length} items`);
@@ -655,7 +735,11 @@ export const processHealthSnapshotPingPayload = internalAction({
655
735
  * and transforms each record. Does not write to the database.
656
736
  */
657
737
  export const processHRVSummaryPushPayload = internalAction({
658
- args: { payload: v.any() },
738
+ args: {
739
+ payload: v.any(),
740
+ // Only consumed by push processors; ping processors ignore it.
741
+ rawPassthrough: v.optional(v.boolean()),
742
+ },
659
743
  handler: async (ctx, args) => {
660
744
  const { hrv } = garminHRVSummaryPushPayloadSchema.parse(args.payload);
661
745
  const items = [];
@@ -695,7 +779,9 @@ export const processHRVSummaryPushPayload = internalAction({
695
779
  }
696
780
  for (const item of userItems) {
697
781
  try {
698
- const data = transformHRVSummary(item);
782
+ const data = args.rawPassthrough
783
+ ? item
784
+ : transformHRVSummary(item);
699
785
  if (data == null)
700
786
  continue;
701
787
  items.push({ connectionId: connection._id, userId: connection.userId, data });
@@ -718,7 +804,11 @@ export const processHRVSummaryPushPayload = internalAction({
718
804
  * Stub — acknowledges the notification without fetching data.
719
805
  */
720
806
  export const processHRVSummaryPingPayload = internalAction({
721
- args: { payload: v.any() },
807
+ args: {
808
+ payload: v.any(),
809
+ // Only consumed by push processors; ping processors ignore it.
810
+ rawPassthrough: v.optional(v.boolean()),
811
+ },
722
812
  handler: async (_ctx, args) => {
723
813
  const { hrv } = garminHRVSummaryPingPayloadSchema.parse(args.payload);
724
814
  console.log(`[garmin:webhook:hrvSummary] Ping mode not yet implemented, acknowledging ${hrv.length} items`);
@@ -732,7 +822,11 @@ export const processHRVSummaryPingPayload = internalAction({
732
822
  * resolves connections, and transforms each record. Does not write to the database.
733
823
  */
734
824
  export const processEpochPushPayload = internalAction({
735
- args: { payload: v.any() },
825
+ args: {
826
+ payload: v.any(),
827
+ // Only consumed by push processors; ping processors ignore it.
828
+ rawPassthrough: v.optional(v.boolean()),
829
+ },
736
830
  handler: async (ctx, args) => {
737
831
  const { epochs } = garminEpochPushPayloadSchema.parse(args.payload);
738
832
  const items = [];
@@ -772,7 +866,9 @@ export const processEpochPushPayload = internalAction({
772
866
  }
773
867
  for (const item of userItems) {
774
868
  try {
775
- const data = transformEpoch(item);
869
+ const data = args.rawPassthrough
870
+ ? item
871
+ : transformEpoch(item);
776
872
  if (data == null)
777
873
  continue;
778
874
  items.push({ connectionId: connection._id, userId: connection.userId, data });
@@ -795,7 +891,11 @@ export const processEpochPushPayload = internalAction({
795
891
  * Stub — acknowledges the notification without fetching data.
796
892
  */
797
893
  export const processEpochPingPayload = internalAction({
798
- args: { payload: v.any() },
894
+ args: {
895
+ payload: v.any(),
896
+ // Only consumed by push processors; ping processors ignore it.
897
+ rawPassthrough: v.optional(v.boolean()),
898
+ },
799
899
  handler: async (_ctx, args) => {
800
900
  const { epochs } = garminEpochPingPayloadSchema.parse(args.payload);
801
901
  console.log(`[garmin:webhook:epochs] Ping mode not yet implemented, acknowledging ${epochs.length} items`);
@@ -809,7 +909,11 @@ export const processEpochPingPayload = internalAction({
809
909
  * and transforms each record. Does not write to the database.
810
910
  */
811
911
  export const processPulseOxPushPayload = internalAction({
812
- args: { payload: v.any() },
912
+ args: {
913
+ payload: v.any(),
914
+ // Only consumed by push processors; ping processors ignore it.
915
+ rawPassthrough: v.optional(v.boolean()),
916
+ },
813
917
  handler: async (ctx, args) => {
814
918
  const { pulseox } = garminPulseOxPushPayloadSchema.parse(args.payload);
815
919
  const items = [];
@@ -849,7 +953,9 @@ export const processPulseOxPushPayload = internalAction({
849
953
  }
850
954
  for (const item of userItems) {
851
955
  try {
852
- const data = transformPulseOx(item);
956
+ const data = args.rawPassthrough
957
+ ? item
958
+ : transformPulseOx(item);
853
959
  if (data == null)
854
960
  continue;
855
961
  items.push({ connectionId: connection._id, userId: connection.userId, data });
@@ -872,7 +978,11 @@ export const processPulseOxPushPayload = internalAction({
872
978
  * Stub — acknowledges the notification without fetching data.
873
979
  */
874
980
  export const processPulseOxPingPayload = internalAction({
875
- args: { payload: v.any() },
981
+ args: {
982
+ payload: v.any(),
983
+ // Only consumed by push processors; ping processors ignore it.
984
+ rawPassthrough: v.optional(v.boolean()),
985
+ },
876
986
  handler: async (_ctx, args) => {
877
987
  const { pulseox } = garminPulseOxPingPayloadSchema.parse(args.payload);
878
988
  console.log(`[garmin:webhook:pulseOx] Ping mode not yet implemented, acknowledging ${pulseox.length} items`);
@@ -886,7 +996,11 @@ export const processPulseOxPingPayload = internalAction({
886
996
  * and transforms each record. Does not write to the database.
887
997
  */
888
998
  export const processRespirationPushPayload = internalAction({
889
- args: { payload: v.any() },
999
+ args: {
1000
+ payload: v.any(),
1001
+ // Only consumed by push processors; ping processors ignore it.
1002
+ rawPassthrough: v.optional(v.boolean()),
1003
+ },
890
1004
  handler: async (ctx, args) => {
891
1005
  const { allDayRespiration } = garminRespirationPushPayloadSchema.parse(args.payload);
892
1006
  const items = [];
@@ -926,7 +1040,9 @@ export const processRespirationPushPayload = internalAction({
926
1040
  }
927
1041
  for (const item of userItems) {
928
1042
  try {
929
- const data = transformRespiration(item);
1043
+ const data = args.rawPassthrough
1044
+ ? item
1045
+ : transformRespiration(item);
930
1046
  if (data == null)
931
1047
  continue;
932
1048
  items.push({ connectionId: connection._id, userId: connection.userId, data });
@@ -949,7 +1065,11 @@ export const processRespirationPushPayload = internalAction({
949
1065
  * Stub — acknowledges the notification without fetching data.
950
1066
  */
951
1067
  export const processRespirationPingPayload = internalAction({
952
- args: { payload: v.any() },
1068
+ args: {
1069
+ payload: v.any(),
1070
+ // Only consumed by push processors; ping processors ignore it.
1071
+ rawPassthrough: v.optional(v.boolean()),
1072
+ },
953
1073
  handler: async (_ctx, args) => {
954
1074
  const { allDayRespiration } = garminRespirationPingPayloadSchema.parse(args.payload);
955
1075
  console.log(`[garmin:webhook:respiration] Ping mode not yet implemented, acknowledging ${allDayRespiration.length} items`);
@@ -963,7 +1083,11 @@ export const processRespirationPingPayload = internalAction({
963
1083
  * and transforms each record. Does not write to the database.
964
1084
  */
965
1085
  export const processStressPushPayload = internalAction({
966
- args: { payload: v.any() },
1086
+ args: {
1087
+ payload: v.any(),
1088
+ // Only consumed by push processors; ping processors ignore it.
1089
+ rawPassthrough: v.optional(v.boolean()),
1090
+ },
967
1091
  handler: async (ctx, args) => {
968
1092
  const { stressDetails } = garminStressPushPayloadSchema.parse(args.payload);
969
1093
  const items = [];
@@ -1003,7 +1127,9 @@ export const processStressPushPayload = internalAction({
1003
1127
  }
1004
1128
  for (const item of userItems) {
1005
1129
  try {
1006
- const data = transformStress(item);
1130
+ const data = args.rawPassthrough
1131
+ ? item
1132
+ : transformStress(item);
1007
1133
  if (data == null)
1008
1134
  continue;
1009
1135
  items.push({ connectionId: connection._id, userId: connection.userId, data });
@@ -1026,7 +1152,11 @@ export const processStressPushPayload = internalAction({
1026
1152
  * Stub — acknowledges the notification without fetching data.
1027
1153
  */
1028
1154
  export const processStressPingPayload = internalAction({
1029
- args: { payload: v.any() },
1155
+ args: {
1156
+ payload: v.any(),
1157
+ // Only consumed by push processors; ping processors ignore it.
1158
+ rawPassthrough: v.optional(v.boolean()),
1159
+ },
1030
1160
  handler: async (_ctx, args) => {
1031
1161
  const { stressDetails } = garminStressPingPayloadSchema.parse(args.payload);
1032
1162
  console.log(`[garmin:webhook:stressDetails] Ping mode not yet implemented, acknowledging ${stressDetails.length} items`);
@@ -1040,7 +1170,11 @@ export const processStressPingPayload = internalAction({
1040
1170
  * and transforms each record. Does not write to the database.
1041
1171
  */
1042
1172
  export const processSkinTemperaturePushPayload = internalAction({
1043
- args: { payload: v.any() },
1173
+ args: {
1174
+ payload: v.any(),
1175
+ // Only consumed by push processors; ping processors ignore it.
1176
+ rawPassthrough: v.optional(v.boolean()),
1177
+ },
1044
1178
  handler: async (ctx, args) => {
1045
1179
  const { skinTemp } = garminSkinTemperaturePushPayloadSchema.parse(args.payload);
1046
1180
  const items = [];
@@ -1080,7 +1214,9 @@ export const processSkinTemperaturePushPayload = internalAction({
1080
1214
  }
1081
1215
  for (const item of userItems) {
1082
1216
  try {
1083
- const data = transformSkinTemperature(item);
1217
+ const data = args.rawPassthrough
1218
+ ? item
1219
+ : transformSkinTemperature(item);
1084
1220
  if (data == null)
1085
1221
  continue;
1086
1222
  items.push({ connectionId: connection._id, userId: connection.userId, data });
@@ -1103,7 +1239,11 @@ export const processSkinTemperaturePushPayload = internalAction({
1103
1239
  * Stub — acknowledges the notification without fetching data.
1104
1240
  */
1105
1241
  export const processSkinTemperaturePingPayload = internalAction({
1106
- args: { payload: v.any() },
1242
+ args: {
1243
+ payload: v.any(),
1244
+ // Only consumed by push processors; ping processors ignore it.
1245
+ rawPassthrough: v.optional(v.boolean()),
1246
+ },
1107
1247
  handler: async (_ctx, args) => {
1108
1248
  const { skinTemp } = garminSkinTemperaturePingPayloadSchema.parse(args.payload);
1109
1249
  console.log(`[garmin:webhook:skinTemperature] Ping mode not yet implemented, acknowledging ${skinTemp.length} items`);
@@ -1117,7 +1257,11 @@ export const processSkinTemperaturePingPayload = internalAction({
1117
1257
  * and transforms each sleep record. Does not write to the database.
1118
1258
  */
1119
1259
  export const processSleepsPushPayload = internalAction({
1120
- args: { payload: v.any() },
1260
+ args: {
1261
+ payload: v.any(),
1262
+ // Only consumed by push processors; ping processors ignore it.
1263
+ rawPassthrough: v.optional(v.boolean()),
1264
+ },
1121
1265
  handler: async (ctx, args) => {
1122
1266
  const { sleeps } = garminSleepsPushPayloadSchema.parse(args.payload);
1123
1267
  const items = [];
@@ -1157,7 +1301,9 @@ export const processSleepsPushPayload = internalAction({
1157
1301
  }
1158
1302
  for (const item of userItems) {
1159
1303
  try {
1160
- const data = transformSleeps(item);
1304
+ const data = args.rawPassthrough
1305
+ ? item
1306
+ : transformSleeps(item);
1161
1307
  items.push({ connectionId: connection._id, userId: connection.userId, data });
1162
1308
  }
1163
1309
  catch (err) {
@@ -1178,7 +1324,11 @@ export const processSleepsPushPayload = internalAction({
1178
1324
  * Stub — acknowledges the notification without fetching data.
1179
1325
  */
1180
1326
  export const processSleepsPingPayload = internalAction({
1181
- args: { payload: v.any() },
1327
+ args: {
1328
+ payload: v.any(),
1329
+ // Only consumed by push processors; ping processors ignore it.
1330
+ rawPassthrough: v.optional(v.boolean()),
1331
+ },
1182
1332
  handler: async (_ctx, args) => {
1183
1333
  const { sleeps } = garminSleepsPingPayloadSchema.parse(args.payload);
1184
1334
  console.log(`[garmin:webhook:sleeps] Ping mode not yet implemented, acknowledging ${sleeps.length} items`);
@@ -1192,7 +1342,11 @@ export const processSleepsPingPayload = internalAction({
1192
1342
  * and transforms each user metrics record. Does not write to the database.
1193
1343
  */
1194
1344
  export const processUserMetricsPushPayload = internalAction({
1195
- args: { payload: v.any() },
1345
+ args: {
1346
+ payload: v.any(),
1347
+ // Only consumed by push processors; ping processors ignore it.
1348
+ rawPassthrough: v.optional(v.boolean()),
1349
+ },
1196
1350
  handler: async (ctx, args) => {
1197
1351
  const { userMetrics } = garminUserMetricsPushPayloadSchema.parse(args.payload);
1198
1352
  const items = [];
@@ -1232,7 +1386,9 @@ export const processUserMetricsPushPayload = internalAction({
1232
1386
  }
1233
1387
  for (const item of userItems) {
1234
1388
  try {
1235
- const data = transformUserMetrics(item);
1389
+ const data = args.rawPassthrough
1390
+ ? item
1391
+ : transformUserMetrics(item);
1236
1392
  if (data == null)
1237
1393
  continue;
1238
1394
  items.push({ connectionId: connection._id, userId: connection.userId, data });
@@ -1255,7 +1411,11 @@ export const processUserMetricsPushPayload = internalAction({
1255
1411
  * Stub — acknowledges the notification without fetching data.
1256
1412
  */
1257
1413
  export const processUserMetricsPingPayload = internalAction({
1258
- args: { payload: v.any() },
1414
+ args: {
1415
+ payload: v.any(),
1416
+ // Only consumed by push processors; ping processors ignore it.
1417
+ rawPassthrough: v.optional(v.boolean()),
1418
+ },
1259
1419
  handler: async (_ctx, args) => {
1260
1420
  const { userMetrics } = garminUserMetricsPingPayloadSchema.parse(args.payload);
1261
1421
  console.log(`[garmin:webhook:userMetrics] Ping mode not yet implemented, acknowledging ${userMetrics.length} items`);
@@ -1269,7 +1429,11 @@ export const processUserMetricsPingPayload = internalAction({
1269
1429
  * and transforms each record. Does not write to the database.
1270
1430
  */
1271
1431
  export const processMenstrualCycleTrackingPushPayload = internalAction({
1272
- args: { payload: v.any() },
1432
+ args: {
1433
+ payload: v.any(),
1434
+ // Only consumed by push processors; ping processors ignore it.
1435
+ rawPassthrough: v.optional(v.boolean()),
1436
+ },
1273
1437
  handler: async (ctx, args) => {
1274
1438
  const { mct } = garminMenstrualCycleTrackingPushPayloadSchema.parse(args.payload);
1275
1439
  const items = [];
@@ -1309,7 +1473,9 @@ export const processMenstrualCycleTrackingPushPayload = internalAction({
1309
1473
  }
1310
1474
  for (const item of userItems) {
1311
1475
  try {
1312
- const data = transformMenstrualCycleTracking(item);
1476
+ const data = args.rawPassthrough
1477
+ ? item
1478
+ : transformMenstrualCycleTracking(item);
1313
1479
  items.push({ connectionId: connection._id, userId: connection.userId, data });
1314
1480
  }
1315
1481
  catch (err) {
@@ -1330,7 +1496,11 @@ export const processMenstrualCycleTrackingPushPayload = internalAction({
1330
1496
  * Stub — acknowledges the notification without fetching data.
1331
1497
  */
1332
1498
  export const processMenstrualCycleTrackingPingPayload = internalAction({
1333
- args: { payload: v.any() },
1499
+ args: {
1500
+ payload: v.any(),
1501
+ // Only consumed by push processors; ping processors ignore it.
1502
+ rawPassthrough: v.optional(v.boolean()),
1503
+ },
1334
1504
  handler: async (_ctx, args) => {
1335
1505
  const { mct } = garminMenstrualCycleTrackingPingPayloadSchema.parse(args.payload);
1336
1506
  console.log(`[garmin:webhook:menstrualCycleTracking] Ping mode not yet implemented, acknowledging ${mct.length} items`);