@almadar/std 16.181.0 → 16.183.0

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 (90) hide show
  1. package/behaviors/lolo/infra/atoms/std-calendar-sync.lolo +290 -0
  2. package/behaviors/lolo/infra/atoms/std-migration-job.lolo +2 -2
  3. package/behaviors/lolo/infra/atoms/std-notification-center.lolo +290 -0
  4. package/behaviors/lolo/infra/atoms/std-notify-on-event.lolo +238 -40
  5. package/behaviors/lolo/ui/core/atoms/std-esign-flow.lolo +180 -3
  6. package/behaviors/lolo/ui/core/molecules/ui-calendar-grid.lolo +6 -0
  7. package/behaviors/lolo/ui/core/organisms/ui-detail-panel.lolo +4 -4
  8. package/behaviors/lolo/ui/game/.hand-authored.json +1 -1
  9. package/behaviors/lolo/ui/game/atoms/std-fx-trail.lolo +63 -0
  10. package/behaviors/lolo/ui/game/atoms/std-gate-lock.lolo +96 -0
  11. package/behaviors/lolo/ui/game/atoms/std-lives.lolo +121 -0
  12. package/behaviors/lolo/ui/game/atoms/std-patrol-hazard.lolo +96 -0
  13. package/behaviors/lolo/ui/game/atoms/std-tutorial-overlay.lolo +164 -0
  14. package/behaviors/lolo/ui/game/atoms/ui-control-grid.lolo +5 -0
  15. package/behaviors/lolo/ui/game/atoms/ui-game-hud.lolo +5 -0
  16. package/behaviors/lolo/ui/game/templates/ui-game-shell.lolo +5 -5
  17. package/behaviors/lolo/ui/learning/atoms/std-learn-slope-probe.lolo +117 -0
  18. package/behaviors/lolo/ui/learning/atoms/ui-math-canvas.lolo +18 -0
  19. package/behaviors/registry/infra/atoms/std-calendar-sync.orb +1643 -0
  20. package/behaviors/registry/infra/atoms/std-migration-job.orb +2 -2
  21. package/behaviors/registry/infra/atoms/std-notification-center.orb +1621 -0
  22. package/behaviors/registry/infra/atoms/std-notify-on-event.orb +1734 -169
  23. package/behaviors/registry/ui/core/atoms/std-esign-flow.orb +846 -2
  24. package/behaviors/registry/ui/core/molecules/ui-calendar-grid.orb +9 -0
  25. package/behaviors/registry/ui/core/organisms/ui-detail-panel.orb +4 -2
  26. package/behaviors/registry/ui/game/atoms/std-fx-trail.orb +376 -0
  27. package/behaviors/registry/ui/game/atoms/std-gate-lock.orb +852 -0
  28. package/behaviors/registry/ui/game/atoms/std-lives.orb +739 -0
  29. package/behaviors/registry/ui/game/atoms/std-patrol-hazard.orb +768 -0
  30. package/behaviors/registry/ui/game/atoms/std-tutorial-overlay.orb +1060 -0
  31. package/behaviors/registry/ui/game/atoms/ui-control-grid.orb +13 -1
  32. package/behaviors/registry/ui/game/atoms/ui-game-hud.orb +13 -1
  33. package/behaviors/registry/ui/game/templates/ui-game-shell.orb +5 -5
  34. package/behaviors/registry/ui/learning/atoms/std-learn-slope-probe.orb +908 -0
  35. package/canonical-operators.json +21 -1
  36. package/dist/behaviors/exports-reader.js +9021 -3497
  37. package/dist/behaviors/functions/index.d.ts +1001 -10
  38. package/dist/behaviors/functions/index.js +18568 -13079
  39. package/dist/behaviors/index.d.ts +1 -1
  40. package/dist/behaviors/index.js +9022 -3498
  41. package/dist/behaviors/query.js +9021 -3497
  42. package/dist/behaviors-embeddings.hash.json +3 -3
  43. package/dist/behaviors-embeddings.json +347 -315
  44. package/dist/behaviors-registry.json +2694 -56
  45. package/dist/index.d.ts +3 -3
  46. package/dist/index.js +8502 -2941
  47. package/dist/knob-embeddings.hash.json +3 -3
  48. package/dist/knob-embeddings.json +1 -1
  49. package/dist/modules/anim.d.ts +1 -1
  50. package/dist/modules/array.d.ts +1 -1
  51. package/dist/modules/async.d.ts +1 -1
  52. package/dist/modules/behavior.d.ts +1 -1
  53. package/dist/modules/browser.d.ts +1 -1
  54. package/dist/modules/browser.js +21 -0
  55. package/dist/modules/composition.d.ts +1 -1
  56. package/dist/modules/contract.d.ts +1 -1
  57. package/dist/modules/core.d.ts +1 -1
  58. package/dist/modules/core.js +18 -2
  59. package/dist/modules/data.d.ts +1 -1
  60. package/dist/modules/ease.d.ts +1 -1
  61. package/dist/modules/format.d.ts +1 -1
  62. package/dist/modules/geo.d.ts +1 -1
  63. package/dist/modules/graph.d.ts +1 -1
  64. package/dist/modules/grid.d.ts +1 -1
  65. package/dist/modules/index.d.ts +1 -1
  66. package/dist/modules/index.js +39 -2
  67. package/dist/modules/integration.d.ts +1 -1
  68. package/dist/modules/llm.d.ts +1 -1
  69. package/dist/modules/math.d.ts +1 -1
  70. package/dist/modules/memory.d.ts +1 -1
  71. package/dist/modules/nn.d.ts +1 -1
  72. package/dist/modules/noise.d.ts +1 -1
  73. package/dist/modules/object.d.ts +1 -1
  74. package/dist/modules/os.d.ts +1 -1
  75. package/dist/modules/path.d.ts +1 -1
  76. package/dist/modules/prob.d.ts +1 -1
  77. package/dist/modules/session.d.ts +1 -1
  78. package/dist/modules/str.d.ts +1 -1
  79. package/dist/modules/tensor.d.ts +1 -1
  80. package/dist/modules/time.d.ts +1 -1
  81. package/dist/modules/trace.d.ts +1 -1
  82. package/dist/modules/train.d.ts +1 -1
  83. package/dist/modules/validate.d.ts +1 -1
  84. package/dist/modules/vector.d.ts +1 -1
  85. package/dist/modules/workspace.d.ts +1 -1
  86. package/dist/registry/factory-signatures.json +1 -1
  87. package/dist/registry.d.ts +1 -1
  88. package/dist/registry.js +39 -2
  89. package/dist/{types-DGJ6Y6nW.d.ts → types-BXWzEjFm.d.ts} +1 -1
  90. package/package.json +3 -3
@@ -0,0 +1,1621 @@
1
+ {
2
+ "description": "std-notification-center — per-user notification preferences, web-push subscriptions, and the digest drain for suppressed notifications. Owns the two owner-scoped stores std-notify-on-event consults at dispatch time: NotificationPreference rows (per event key: mode instant/digest/off, channel override, per-user quiet hours) and PushSubscription rows (captured via the browser/push-subscribe flow — the shared service worker + PushManager subscription, persisted as flat endpoint/p256dh/auth credentials). The DigestDrain trait is the delivery half of every suppression std-notify-on-event records: an hourly cron tick scans NotificationRecord audit rows left undispatched for digest/quiet-hours reasons and at least `minAgeHours` old, delivers each by email (the digest channel), and marks it dispatched — the reminder-scheduler self-driving scan loop verbatim. Compose alongside std-notify-on-event: the listener suppresses and records, this atom captures subscriptions, edits preferences, and drains.",
3
+ "ledger": {
4
+ "entries": {
5
+ "ent_01M0M65FFF0G1ZEE15D76BK6XK": {
6
+ "bakedName": "NotificationPreference",
7
+ "curName": "NotificationPreference",
8
+ "id": "ent_01M0M65FFF0G1ZEE15D76BK6XK",
9
+ "kind": "entity",
10
+ "owner": "workspace",
11
+ "renames": []
12
+ },
13
+ "ent_01M0M65FFFBR45A2QA3ZWP1HD4": {
14
+ "bakedName": "PushSubscription",
15
+ "curName": "PushSubscription",
16
+ "id": "ent_01M0M65FFFBR45A2QA3ZWP1HD4",
17
+ "kind": "entity",
18
+ "owner": "workspace",
19
+ "renames": []
20
+ },
21
+ "ent_01M0M65FFFQ3XBF85WBE2VSWMY": {
22
+ "bakedName": "NotificationRecord",
23
+ "curName": "NotificationRecord",
24
+ "id": "ent_01M0M65FFFQ3XBF85WBE2VSWMY",
25
+ "kind": "entity",
26
+ "owner": "workspace",
27
+ "renames": []
28
+ },
29
+ "ent_01M0M65FFFZGACVWJYWZ3AE6ZZ": {
30
+ "bakedName": "DigestRunView",
31
+ "curName": "DigestRunView",
32
+ "id": "ent_01M0M65FFFZGACVWJYWZ3AE6ZZ",
33
+ "kind": "entity",
34
+ "owner": "workspace",
35
+ "renames": []
36
+ },
37
+ "evt_01M0M65FFF0QM818V9HGCCN1VA": {
38
+ "bakedName": "DIGEST_STEPPED",
39
+ "curName": "DIGEST_STEPPED",
40
+ "id": "evt_01M0M65FFF0QM818V9HGCCN1VA",
41
+ "kind": "event",
42
+ "owner": "workspace",
43
+ "parent": "trt_01M0M65FFF9APPJEKH9Y561YA4",
44
+ "renames": []
45
+ },
46
+ "evt_01M0M65FFF1C1VHHNW8CYAE5W5": {
47
+ "bakedName": "SUBSCRIBE_PUSH",
48
+ "curName": "SUBSCRIBE_PUSH",
49
+ "id": "evt_01M0M65FFF1C1VHHNW8CYAE5W5",
50
+ "kind": "event",
51
+ "owner": "workspace",
52
+ "parent": "trt_01M0M65FFF4P6SDTP06Z8M22C2",
53
+ "renames": []
54
+ },
55
+ "evt_01M0M65FFF1K04JNAZHABZTEHE": {
56
+ "bakedName": "DIGEST_ITEM_SENT",
57
+ "curName": "DIGEST_ITEM_SENT",
58
+ "id": "evt_01M0M65FFF1K04JNAZHABZTEHE",
59
+ "kind": "event",
60
+ "owner": "workspace",
61
+ "parent": "trt_01M0M65FFF9APPJEKH9Y561YA4",
62
+ "renames": []
63
+ },
64
+ "evt_01M0M65FFF3VJFCFJW2MFTQ33R": {
65
+ "bakedName": "UPDATE_PREFERENCE",
66
+ "curName": "UPDATE_PREFERENCE",
67
+ "id": "evt_01M0M65FFF3VJFCFJW2MFTQ33R",
68
+ "kind": "event",
69
+ "owner": "workspace",
70
+ "parent": "trt_01M0M65FFFH69MBB0G62CE4NHC",
71
+ "renames": []
72
+ },
73
+ "evt_01M0M65FFF7XGSZAATT13F5G5Z": {
74
+ "bakedName": "PREFERENCE_SAVED",
75
+ "curName": "PREFERENCE_SAVED",
76
+ "id": "evt_01M0M65FFF7XGSZAATT13F5G5Z",
77
+ "kind": "event",
78
+ "owner": "workspace",
79
+ "parent": "trt_01M0M65FFFH69MBB0G62CE4NHC",
80
+ "renames": []
81
+ },
82
+ "evt_01M0M65FFFD1RTHPARJ5HZCKGZ": {
83
+ "bakedName": "SAVE_PREFERENCE",
84
+ "curName": "SAVE_PREFERENCE",
85
+ "id": "evt_01M0M65FFFD1RTHPARJ5HZCKGZ",
86
+ "kind": "event",
87
+ "owner": "workspace",
88
+ "parent": "trt_01M0M65FFFH69MBB0G62CE4NHC",
89
+ "renames": []
90
+ },
91
+ "evt_01M0M65FFFD96C401APVT4PSDX": {
92
+ "bakedName": "PUSH_SAVED",
93
+ "curName": "PUSH_SAVED",
94
+ "id": "evt_01M0M65FFFD96C401APVT4PSDX",
95
+ "kind": "event",
96
+ "owner": "workspace",
97
+ "parent": "trt_01M0M65FFF4P6SDTP06Z8M22C2",
98
+ "renames": []
99
+ },
100
+ "evt_01M0M65FFFG5RH4AMKM6PRC7D9": {
101
+ "bakedName": "PREFERENCE_SAVE_FAILED",
102
+ "curName": "PREFERENCE_SAVE_FAILED",
103
+ "id": "evt_01M0M65FFFG5RH4AMKM6PRC7D9",
104
+ "kind": "event",
105
+ "owner": "workspace",
106
+ "parent": "trt_01M0M65FFFH69MBB0G62CE4NHC",
107
+ "renames": []
108
+ },
109
+ "evt_01M0M65FFFGSKNV146RNQW7CGC": {
110
+ "bakedName": "DELETE_PREFERENCE",
111
+ "curName": "DELETE_PREFERENCE",
112
+ "id": "evt_01M0M65FFFGSKNV146RNQW7CGC",
113
+ "kind": "event",
114
+ "owner": "workspace",
115
+ "parent": "trt_01M0M65FFFH69MBB0G62CE4NHC",
116
+ "renames": []
117
+ },
118
+ "evt_01M0M65FFFKR8G9TZW4WES7CAT": {
119
+ "bakedName": "PUSH_SUBSCRIBED",
120
+ "curName": "PUSH_SUBSCRIBED",
121
+ "id": "evt_01M0M65FFFKR8G9TZW4WES7CAT",
122
+ "kind": "event",
123
+ "owner": "workspace",
124
+ "parent": "trt_01M0M65FFF4P6SDTP06Z8M22C2",
125
+ "renames": []
126
+ },
127
+ "evt_01M0M65FFFKTWQWBWKXQ33881V": {
128
+ "bakedName": "PUSH_SAVE_FAILED",
129
+ "curName": "PUSH_SAVE_FAILED",
130
+ "id": "evt_01M0M65FFFKTWQWBWKXQ33881V",
131
+ "kind": "event",
132
+ "owner": "workspace",
133
+ "parent": "trt_01M0M65FFF4P6SDTP06Z8M22C2",
134
+ "renames": []
135
+ },
136
+ "evt_01M0M65FFFS4TZ2J5V874NFENP": {
137
+ "bakedName": "PREFERENCE_DELETED",
138
+ "curName": "PREFERENCE_DELETED",
139
+ "id": "evt_01M0M65FFFS4TZ2J5V874NFENP",
140
+ "kind": "event",
141
+ "owner": "workspace",
142
+ "parent": "trt_01M0M65FFFH69MBB0G62CE4NHC",
143
+ "renames": []
144
+ },
145
+ "evt_01M0M65FFFTXQ7Y0YV9XY3X1A5": {
146
+ "bakedName": "DIGEST_FAILED",
147
+ "curName": "DIGEST_FAILED",
148
+ "id": "evt_01M0M65FFFTXQ7Y0YV9XY3X1A5",
149
+ "kind": "event",
150
+ "owner": "workspace",
151
+ "parent": "trt_01M0M65FFF9APPJEKH9Y561YA4",
152
+ "renames": []
153
+ },
154
+ "evt_01M0M65FFFW27HPBWGDZ9Z9RPC": {
155
+ "bakedName": "PUSH_SUBSCRIBE_FAILED",
156
+ "curName": "PUSH_SUBSCRIBE_FAILED",
157
+ "id": "evt_01M0M65FFFW27HPBWGDZ9Z9RPC",
158
+ "kind": "event",
159
+ "owner": "workspace",
160
+ "parent": "trt_01M0M65FFF4P6SDTP06Z8M22C2",
161
+ "renames": []
162
+ },
163
+ "evt_01M0M65FFFX5V7JGP2T5AXQS76": {
164
+ "bakedName": "DIGEST_ROWS_LOADED",
165
+ "curName": "DIGEST_ROWS_LOADED",
166
+ "id": "evt_01M0M65FFFX5V7JGP2T5AXQS76",
167
+ "kind": "event",
168
+ "owner": "workspace",
169
+ "parent": "trt_01M0M65FFF9APPJEKH9Y561YA4",
170
+ "renames": []
171
+ },
172
+ "orb_01M0M65FFF1A3816MJVC21AJN9": {
173
+ "bakedName": "NotificationCenterOrbital",
174
+ "curName": "NotificationCenterOrbital",
175
+ "id": "orb_01M0M65FFF1A3816MJVC21AJN9",
176
+ "kind": "orbital",
177
+ "owner": "workspace",
178
+ "renames": []
179
+ },
180
+ "pag_01M0M65FFF4BYKP02HV3REFA10": {
181
+ "bakedName": "PushSubscribePage",
182
+ "curName": "PushSubscribePage",
183
+ "id": "pag_01M0M65FFF4BYKP02HV3REFA10",
184
+ "kind": "page",
185
+ "owner": "workspace",
186
+ "renames": []
187
+ },
188
+ "pag_01M0M65FFFK9K643YBXKERZRMH": {
189
+ "bakedName": "NotificationPreferencesPage",
190
+ "curName": "NotificationPreferencesPage",
191
+ "id": "pag_01M0M65FFFK9K643YBXKERZRMH",
192
+ "kind": "page",
193
+ "owner": "workspace",
194
+ "renames": []
195
+ },
196
+ "pag_01M0M74SY2KDDK1TM4B3HQPZ99": {
197
+ "bakedName": "NotificationDigestPage",
198
+ "curName": "NotificationDigestPage",
199
+ "id": "pag_01M0M74SY2KDDK1TM4B3HQPZ99",
200
+ "kind": "page",
201
+ "owner": "workspace",
202
+ "renames": []
203
+ },
204
+ "trt_01M0M65FFF4P6SDTP06Z8M22C2": {
205
+ "bakedName": "PushSubscriber",
206
+ "curName": "PushSubscriber",
207
+ "id": "trt_01M0M65FFF4P6SDTP06Z8M22C2",
208
+ "kind": "trait",
209
+ "owner": "workspace",
210
+ "renames": []
211
+ },
212
+ "trt_01M0M65FFF9APPJEKH9Y561YA4": {
213
+ "bakedName": "DigestDrain",
214
+ "curName": "DigestDrain",
215
+ "id": "trt_01M0M65FFF9APPJEKH9Y561YA4",
216
+ "kind": "trait",
217
+ "owner": "workspace",
218
+ "renames": []
219
+ },
220
+ "trt_01M0M65FFFH69MBB0G62CE4NHC": {
221
+ "bakedName": "PreferenceEditor",
222
+ "curName": "PreferenceEditor",
223
+ "id": "trt_01M0M65FFFH69MBB0G62CE4NHC",
224
+ "kind": "trait",
225
+ "owner": "workspace",
226
+ "renames": []
227
+ }
228
+ },
229
+ "schemaVersion": 1
230
+ },
231
+ "name": "std-notification-center",
232
+ "orbitals": [
233
+ {
234
+ "auxiliaryEntities": [
235
+ {
236
+ "collection": "pushSubscriptions",
237
+ "fields": [
238
+ {
239
+ "name": "id",
240
+ "required": true,
241
+ "type": "string"
242
+ },
243
+ {
244
+ "default": "",
245
+ "description": "Owner of this browser push subscription. Owner-scoped access predicates belong to the binding organism's [identity] roster, as with NotificationPreference.",
246
+ "name": "userId",
247
+ "synonyms": "user, owner, account",
248
+ "type": "string"
249
+ },
250
+ {
251
+ "default": "",
252
+ "description": "Push service endpoint URL for this subscription.",
253
+ "name": "endpoint",
254
+ "synonyms": "push url, subscription endpoint",
255
+ "type": "string"
256
+ },
257
+ {
258
+ "default": "",
259
+ "description": "Client public key (p256dh) of the subscription.",
260
+ "name": "p256dh",
261
+ "synonyms": "public key",
262
+ "type": "string"
263
+ },
264
+ {
265
+ "default": "",
266
+ "description": "Auth secret of the subscription.",
267
+ "name": "auth",
268
+ "synonyms": "auth secret",
269
+ "type": "string"
270
+ },
271
+ {
272
+ "default": 0.0,
273
+ "description": "When this subscription was captured.",
274
+ "name": "createdAt",
275
+ "synonyms": "subscribed at, created",
276
+ "type": "number"
277
+ },
278
+ {
279
+ "default": "",
280
+ "description": "Scratch: last subscribe-flow failure shown to the user; blank = none.",
281
+ "name": "lastError",
282
+ "synonyms": "subscribe error, failure reason",
283
+ "type": "string"
284
+ }
285
+ ],
286
+ "id": "ent_01M0M65FFFBR45A2QA3ZWP1HD4",
287
+ "name": "PushSubscription",
288
+ "persistence": "persistent"
289
+ },
290
+ {
291
+ "collection": "notifications",
292
+ "fields": [
293
+ {
294
+ "name": "id",
295
+ "required": true,
296
+ "type": "string"
297
+ },
298
+ {
299
+ "default": "",
300
+ "description": "The identifier of the entity receiving the notification.",
301
+ "name": "recipient",
302
+ "synonyms": "user, target, receiver, destination",
303
+ "type": "string"
304
+ },
305
+ {
306
+ "default": "in-app",
307
+ "description": "The delivery method for the notification (e.g., email, SMS, in-app).",
308
+ "name": "channel",
309
+ "synonyms": "delivery, medium, type",
310
+ "type": "string"
311
+ },
312
+ {
313
+ "default": "",
314
+ "description": "The content of the notification message.",
315
+ "name": "message",
316
+ "synonyms": "text, content, body",
317
+ "type": "string"
318
+ },
319
+ {
320
+ "default": "info",
321
+ "description": "Indicates the importance or urgency level of the notification.",
322
+ "name": "severity",
323
+ "synonyms": "priority, level, importance",
324
+ "type": "string"
325
+ },
326
+ {
327
+ "default": false,
328
+ "description": "Indicates whether the notification has been successfully sent.",
329
+ "name": "dispatched",
330
+ "synonyms": "sent, delivered, status",
331
+ "type": "boolean"
332
+ },
333
+ {
334
+ "default": "",
335
+ "description": "Suppression reason or delivery failure detail when dispatched is false.",
336
+ "name": "error",
337
+ "synonyms": "error message, failure reason, dispatch error",
338
+ "type": "string"
339
+ },
340
+ {
341
+ "default": 0.0,
342
+ "description": "Timestamp indicating when the notification record was created.",
343
+ "name": "recordedAt",
344
+ "synonyms": "creation time, timestamp, date, when",
345
+ "type": "number"
346
+ }
347
+ ],
348
+ "id": "ent_01M0M65FFFQ3XBF85WBE2VSWMY",
349
+ "name": "NotificationRecord",
350
+ "persistence": "persistent"
351
+ },
352
+ {
353
+ "fields": [
354
+ {
355
+ "name": "id",
356
+ "required": true,
357
+ "type": "string"
358
+ },
359
+ {
360
+ "default": "",
361
+ "description": "Scratch: id of the audit row the drain loop is currently delivering.",
362
+ "name": "headId",
363
+ "synonyms": "current id, cursor",
364
+ "type": "string"
365
+ },
366
+ {
367
+ "default": "",
368
+ "description": "Scratch: recipient of the row being delivered.",
369
+ "name": "headRecipient",
370
+ "synonyms": "current recipient",
371
+ "type": "string"
372
+ },
373
+ {
374
+ "default": "",
375
+ "description": "Scratch: message of the row being delivered.",
376
+ "name": "headMessage",
377
+ "synonyms": "current message",
378
+ "type": "string"
379
+ },
380
+ {
381
+ "default": 0.0,
382
+ "description": "Number of rows delivered in the current drain cycle.",
383
+ "name": "drainedCount",
384
+ "synonyms": "delivered count, processed",
385
+ "type": "number"
386
+ },
387
+ {
388
+ "default": "",
389
+ "description": "Last drain failure; blank = none.",
390
+ "name": "lastError",
391
+ "synonyms": "drain error, failure",
392
+ "type": "string"
393
+ }
394
+ ],
395
+ "id": "ent_01M0M65FFFZGACVWJYWZ3AE6ZZ",
396
+ "name": "DigestRunView",
397
+ "persistence": "runtime"
398
+ }
399
+ ],
400
+ "entity": {
401
+ "collection": "notificationPreferences",
402
+ "fields": [
403
+ {
404
+ "name": "id",
405
+ "required": true,
406
+ "type": "string"
407
+ },
408
+ {
409
+ "default": "",
410
+ "description": "Owner of this preference row — rows are meant to be private to their owner. Access predicates need an [identity] roster, so the binding organism (which declares one) owns the @read/@update scoping; the generic atom cannot.",
411
+ "name": "userId",
412
+ "synonyms": "user, owner, account",
413
+ "type": "string"
414
+ },
415
+ {
416
+ "default": "",
417
+ "description": "Event key this preference applies to (matches a listener's eventKey); blank = all events.",
418
+ "name": "eventType",
419
+ "synonyms": "event, trigger, subscription, topic",
420
+ "type": "string"
421
+ },
422
+ {
423
+ "default": "instant",
424
+ "description": "Delivery mode: instant (default), digest (deferred to the drain cycle), or off (muted).",
425
+ "name": "mode",
426
+ "synonyms": "delivery mode, frequency, cadence, mute, defer",
427
+ "type": "string",
428
+ "values": [
429
+ "instant",
430
+ "digest",
431
+ "off"
432
+ ]
433
+ },
434
+ {
435
+ "default": "",
436
+ "description": "Channel override for this user (in-app/email/sms/push/webhook); blank = the listener's configured channel.",
437
+ "name": "channel",
438
+ "synonyms": "preferred channel, delivery method",
439
+ "type": "string"
440
+ },
441
+ {
442
+ "default": 0.0,
443
+ "description": "Per-user quiet-hours start (hour 0-23); equal to quietEndHour = disabled.",
444
+ "name": "quietStartHour",
445
+ "synonyms": "quiet start, do not disturb from",
446
+ "type": "number"
447
+ },
448
+ {
449
+ "default": 0.0,
450
+ "description": "Per-user quiet-hours end (hour 0-23); equal to quietStartHour = disabled.",
451
+ "name": "quietEndHour",
452
+ "synonyms": "quiet end, do not disturb until",
453
+ "type": "number"
454
+ }
455
+ ],
456
+ "id": "ent_01M0M65FFF0G1ZEE15D76BK6XK",
457
+ "name": "NotificationPreference",
458
+ "persistence": "persistent"
459
+ },
460
+ "id": "orb_01M0M65FFF1A3816MJVC21AJN9",
461
+ "name": "NotificationCenterOrbital",
462
+ "pages": [
463
+ {
464
+ "id": "pag_01M0M65FFFK9K643YBXKERZRMH",
465
+ "name": "NotificationPreferencesPage",
466
+ "path": "/notifications/preferences",
467
+ "traits": [
468
+ {
469
+ "ref": "PreferenceEditor",
470
+ "refId": "trt_01M0M65FFFH69MBB0G62CE4NHC"
471
+ }
472
+ ]
473
+ },
474
+ {
475
+ "id": "pag_01M0M65FFF4BYKP02HV3REFA10",
476
+ "name": "PushSubscribePage",
477
+ "path": "/notifications/subscribe",
478
+ "traits": [
479
+ {
480
+ "ref": "PushSubscriber",
481
+ "refId": "trt_01M0M65FFF4P6SDTP06Z8M22C2"
482
+ }
483
+ ]
484
+ },
485
+ {
486
+ "id": "pag_01M0M74SY2KDDK1TM4B3HQPZ99",
487
+ "name": "NotificationDigestPage",
488
+ "path": "/notifications/digest",
489
+ "traits": [
490
+ {
491
+ "ref": "DigestDrain",
492
+ "refId": "trt_01M0M65FFF9APPJEKH9Y561YA4"
493
+ }
494
+ ]
495
+ }
496
+ ],
497
+ "traits": [
498
+ {
499
+ "category": "lifecycle",
500
+ "emits": [
501
+ {
502
+ "description": "browser/push-subscribe resolved with the flat subscription credentials in `result`",
503
+ "event": "PUSH_SUBSCRIBED",
504
+ "eventId": "evt_01M0M65FFFKR8G9TZW4WES7CAT",
505
+ "payloadSchema": [
506
+ {
507
+ "name": "result",
508
+ "properties": [
509
+ {
510
+ "name": "endpoint",
511
+ "type": "string"
512
+ },
513
+ {
514
+ "name": "p256dh",
515
+ "type": "string"
516
+ },
517
+ {
518
+ "name": "auth",
519
+ "type": "string"
520
+ }
521
+ ],
522
+ "type": "object"
523
+ }
524
+ ],
525
+ "tier": "secondary"
526
+ },
527
+ {
528
+ "description": "Push API unavailable, permission denied, or the host has no VAPID key",
529
+ "event": "PUSH_SUBSCRIBE_FAILED",
530
+ "eventId": "evt_01M0M65FFFW27HPBWGDZ9Z9RPC",
531
+ "payloadSchema": [
532
+ {
533
+ "name": "error",
534
+ "required": true,
535
+ "type": "string"
536
+ }
537
+ ],
538
+ "tier": "secondary"
539
+ },
540
+ {
541
+ "description": "Subscription row persisted for the current user",
542
+ "event": "PUSH_SAVED",
543
+ "eventId": "evt_01M0M65FFFD96C401APVT4PSDX",
544
+ "payloadSchema": [
545
+ {
546
+ "name": "id",
547
+ "required": true,
548
+ "type": "string"
549
+ }
550
+ ],
551
+ "tier": "secondary"
552
+ },
553
+ {
554
+ "description": "Persisting the subscription row failed",
555
+ "event": "PUSH_SAVE_FAILED",
556
+ "eventId": "evt_01M0M65FFFKTWQWBWKXQ33881V",
557
+ "payloadSchema": [
558
+ {
559
+ "name": "error",
560
+ "required": true,
561
+ "type": "string"
562
+ }
563
+ ],
564
+ "tier": "secondary"
565
+ }
566
+ ],
567
+ "entityRefIds": {
568
+ "PushSubscription": "ent_01M0M65FFFBR45A2QA3ZWP1HD4"
569
+ },
570
+ "id": "trt_01M0M65FFF4P6SDTP06Z8M22C2",
571
+ "linkedEntity": "PushSubscription",
572
+ "linkedEntityId": "ent_01M0M65FFFBR45A2QA3ZWP1HD4",
573
+ "name": "PushSubscriber",
574
+ "scope": "instance",
575
+ "stateMachine": {
576
+ "events": [
577
+ {
578
+ "id": "evt_01M0M65FFF1C1VHHNW8CYAE5W5",
579
+ "key": "SUBSCRIBE_PUSH",
580
+ "name": "Subscribe Push"
581
+ },
582
+ {
583
+ "description": "browser/push-subscribe resolved with the flat subscription credentials in `result`",
584
+ "id": "evt_01M0M65FFFKR8G9TZW4WES7CAT",
585
+ "key": "PUSH_SUBSCRIBED",
586
+ "name": "Push Subscribed",
587
+ "payloadSchema": [
588
+ {
589
+ "name": "result",
590
+ "properties": [
591
+ {
592
+ "name": "endpoint",
593
+ "type": "string"
594
+ },
595
+ {
596
+ "name": "p256dh",
597
+ "type": "string"
598
+ },
599
+ {
600
+ "name": "auth",
601
+ "type": "string"
602
+ }
603
+ ],
604
+ "type": "object"
605
+ }
606
+ ],
607
+ "tier": "secondary"
608
+ },
609
+ {
610
+ "description": "Subscription row persisted for the current user",
611
+ "id": "evt_01M0M65FFFD96C401APVT4PSDX",
612
+ "key": "PUSH_SAVED",
613
+ "name": "Push Saved",
614
+ "payloadSchema": [
615
+ {
616
+ "name": "id",
617
+ "required": true,
618
+ "type": "string"
619
+ }
620
+ ],
621
+ "tier": "secondary"
622
+ },
623
+ {
624
+ "description": "Push API unavailable, permission denied, or the host has no VAPID key",
625
+ "id": "evt_01M0M65FFFW27HPBWGDZ9Z9RPC",
626
+ "key": "PUSH_SUBSCRIBE_FAILED",
627
+ "name": "Push Subscribe Failed",
628
+ "payloadSchema": [
629
+ {
630
+ "name": "error",
631
+ "required": true,
632
+ "type": "string"
633
+ }
634
+ ],
635
+ "tier": "secondary"
636
+ },
637
+ {
638
+ "description": "Persisting the subscription row failed",
639
+ "id": "evt_01M0M65FFFKTWQWBWKXQ33881V",
640
+ "key": "PUSH_SAVE_FAILED",
641
+ "name": "Push Save Failed",
642
+ "payloadSchema": [
643
+ {
644
+ "name": "error",
645
+ "required": true,
646
+ "type": "string"
647
+ }
648
+ ],
649
+ "tier": "secondary"
650
+ }
651
+ ],
652
+ "states": [
653
+ {
654
+ "isInitial": true,
655
+ "name": "idle"
656
+ }
657
+ ],
658
+ "transitions": [
659
+ {
660
+ "effects": [
661
+ [
662
+ "browser/push-subscribe",
663
+ {
664
+ "emit": {
665
+ "failure": "PUSH_SUBSCRIBE_FAILED",
666
+ "success": "PUSH_SUBSCRIBED"
667
+ }
668
+ }
669
+ ]
670
+ ],
671
+ "event": "SUBSCRIBE_PUSH",
672
+ "eventId": "evt_01M0M65FFF1C1VHHNW8CYAE5W5",
673
+ "from": "idle",
674
+ "to": "idle"
675
+ },
676
+ {
677
+ "effects": [
678
+ [
679
+ "set",
680
+ "@entity.lastError",
681
+ ""
682
+ ],
683
+ [
684
+ "persist",
685
+ "create",
686
+ "PushSubscription",
687
+ {
688
+ "auth": "@payload.result.auth",
689
+ "createdAt": "@now",
690
+ "endpoint": "@payload.result.endpoint",
691
+ "p256dh": "@payload.result.p256dh",
692
+ "userId": "@user.id"
693
+ },
694
+ {
695
+ "emit": {
696
+ "failure": "PUSH_SAVE_FAILED",
697
+ "success": "PUSH_SAVED"
698
+ }
699
+ }
700
+ ]
701
+ ],
702
+ "event": "PUSH_SUBSCRIBED",
703
+ "eventId": "evt_01M0M65FFFKR8G9TZW4WES7CAT",
704
+ "from": "idle",
705
+ "to": "idle"
706
+ },
707
+ {
708
+ "effects": [
709
+ [
710
+ "notify",
711
+ "success",
712
+ "Push notifications enabled on this browser"
713
+ ]
714
+ ],
715
+ "event": "PUSH_SAVED",
716
+ "eventId": "evt_01M0M65FFFD96C401APVT4PSDX",
717
+ "from": "idle",
718
+ "to": "idle"
719
+ },
720
+ {
721
+ "effects": [
722
+ [
723
+ "set",
724
+ "@entity.lastError",
725
+ "@payload.error"
726
+ ],
727
+ [
728
+ "notify",
729
+ "warning",
730
+ "Could not enable push notifications"
731
+ ]
732
+ ],
733
+ "event": "PUSH_SUBSCRIBE_FAILED",
734
+ "eventId": "evt_01M0M65FFFW27HPBWGDZ9Z9RPC",
735
+ "from": "idle",
736
+ "to": "idle"
737
+ },
738
+ {
739
+ "effects": [
740
+ [
741
+ "set",
742
+ "@entity.lastError",
743
+ "@payload.error"
744
+ ],
745
+ [
746
+ "notify",
747
+ "warning",
748
+ "Could not save the push subscription"
749
+ ]
750
+ ],
751
+ "event": "PUSH_SAVE_FAILED",
752
+ "eventId": "evt_01M0M65FFFKTWQWBWKXQ33881V",
753
+ "from": "idle",
754
+ "to": "idle"
755
+ }
756
+ ]
757
+ }
758
+ },
759
+ {
760
+ "category": "lifecycle",
761
+ "emits": [
762
+ {
763
+ "description": "Preference row persisted",
764
+ "event": "PREFERENCE_SAVED",
765
+ "eventId": "evt_01M0M65FFF7XGSZAATT13F5G5Z",
766
+ "payloadSchema": [
767
+ {
768
+ "name": "id",
769
+ "required": true,
770
+ "type": "string"
771
+ }
772
+ ],
773
+ "tier": "secondary"
774
+ },
775
+ {
776
+ "description": "Preference row removed",
777
+ "event": "PREFERENCE_DELETED",
778
+ "eventId": "evt_01M0M65FFFS4TZ2J5V874NFENP",
779
+ "payloadSchema": [
780
+ {
781
+ "name": "id",
782
+ "required": true,
783
+ "type": "string"
784
+ }
785
+ ],
786
+ "tier": "secondary"
787
+ },
788
+ {
789
+ "description": "Preference persist failed",
790
+ "event": "PREFERENCE_SAVE_FAILED",
791
+ "eventId": "evt_01M0M65FFFG5RH4AMKM6PRC7D9",
792
+ "payloadSchema": [
793
+ {
794
+ "name": "error",
795
+ "required": true,
796
+ "type": "string"
797
+ }
798
+ ],
799
+ "tier": "secondary"
800
+ }
801
+ ],
802
+ "entityRefIds": {
803
+ "NotificationPreference": "ent_01M0M65FFF0G1ZEE15D76BK6XK"
804
+ },
805
+ "id": "trt_01M0M65FFFH69MBB0G62CE4NHC",
806
+ "linkedEntity": "NotificationPreference",
807
+ "linkedEntityId": "ent_01M0M65FFF0G1ZEE15D76BK6XK",
808
+ "name": "PreferenceEditor",
809
+ "scope": "instance",
810
+ "stateMachine": {
811
+ "events": [
812
+ {
813
+ "id": "evt_01M0M65FFFD1RTHPARJ5HZCKGZ",
814
+ "key": "SAVE_PREFERENCE",
815
+ "name": "Save Preference",
816
+ "payloadSchema": [
817
+ {
818
+ "name": "eventType",
819
+ "type": "string"
820
+ },
821
+ {
822
+ "name": "mode",
823
+ "type": "string"
824
+ },
825
+ {
826
+ "name": "channel",
827
+ "type": "string"
828
+ },
829
+ {
830
+ "name": "quietStartHour",
831
+ "type": "number"
832
+ },
833
+ {
834
+ "name": "quietEndHour",
835
+ "type": "number"
836
+ }
837
+ ]
838
+ },
839
+ {
840
+ "id": "evt_01M0M65FFF3VJFCFJW2MFTQ33R",
841
+ "key": "UPDATE_PREFERENCE",
842
+ "name": "Update Preference",
843
+ "payloadSchema": [
844
+ {
845
+ "name": "id",
846
+ "type": "string"
847
+ },
848
+ {
849
+ "name": "eventType",
850
+ "type": "string"
851
+ },
852
+ {
853
+ "name": "mode",
854
+ "type": "string"
855
+ },
856
+ {
857
+ "name": "channel",
858
+ "type": "string"
859
+ },
860
+ {
861
+ "name": "quietStartHour",
862
+ "type": "number"
863
+ },
864
+ {
865
+ "name": "quietEndHour",
866
+ "type": "number"
867
+ }
868
+ ]
869
+ },
870
+ {
871
+ "id": "evt_01M0M65FFFGSKNV146RNQW7CGC",
872
+ "key": "DELETE_PREFERENCE",
873
+ "name": "Delete Preference",
874
+ "payloadSchema": [
875
+ {
876
+ "name": "id",
877
+ "type": "string"
878
+ }
879
+ ]
880
+ },
881
+ {
882
+ "description": "Preference row persisted",
883
+ "id": "evt_01M0M65FFF7XGSZAATT13F5G5Z",
884
+ "key": "PREFERENCE_SAVED",
885
+ "name": "Preference Saved",
886
+ "payloadSchema": [
887
+ {
888
+ "name": "id",
889
+ "required": true,
890
+ "type": "string"
891
+ }
892
+ ],
893
+ "tier": "secondary"
894
+ },
895
+ {
896
+ "description": "Preference row removed",
897
+ "id": "evt_01M0M65FFFS4TZ2J5V874NFENP",
898
+ "key": "PREFERENCE_DELETED",
899
+ "name": "Preference Deleted",
900
+ "payloadSchema": [
901
+ {
902
+ "name": "id",
903
+ "required": true,
904
+ "type": "string"
905
+ }
906
+ ],
907
+ "tier": "secondary"
908
+ },
909
+ {
910
+ "description": "Preference persist failed",
911
+ "id": "evt_01M0M65FFFG5RH4AMKM6PRC7D9",
912
+ "key": "PREFERENCE_SAVE_FAILED",
913
+ "name": "Preference Save Failed",
914
+ "payloadSchema": [
915
+ {
916
+ "name": "error",
917
+ "required": true,
918
+ "type": "string"
919
+ }
920
+ ],
921
+ "tier": "secondary"
922
+ }
923
+ ],
924
+ "states": [
925
+ {
926
+ "isInitial": true,
927
+ "name": "idle"
928
+ }
929
+ ],
930
+ "transitions": [
931
+ {
932
+ "effects": [
933
+ [
934
+ "persist",
935
+ "create",
936
+ "NotificationPreference",
937
+ {
938
+ "channel": "@payload.channel",
939
+ "eventType": "@payload.eventType",
940
+ "mode": "@payload.mode",
941
+ "quietEndHour": "@payload.quietEndHour",
942
+ "quietStartHour": "@payload.quietStartHour",
943
+ "userId": "@user.id"
944
+ },
945
+ {
946
+ "emit": {
947
+ "failure": "PREFERENCE_SAVE_FAILED",
948
+ "success": "PREFERENCE_SAVED"
949
+ }
950
+ }
951
+ ]
952
+ ],
953
+ "event": "SAVE_PREFERENCE",
954
+ "eventId": "evt_01M0M65FFFD1RTHPARJ5HZCKGZ",
955
+ "from": "idle",
956
+ "to": "idle"
957
+ },
958
+ {
959
+ "effects": [
960
+ [
961
+ "persist",
962
+ "update",
963
+ "NotificationPreference",
964
+ {
965
+ "channel": "@payload.channel",
966
+ "eventType": "@payload.eventType",
967
+ "id": "@payload.id",
968
+ "mode": "@payload.mode",
969
+ "quietEndHour": "@payload.quietEndHour",
970
+ "quietStartHour": "@payload.quietStartHour"
971
+ },
972
+ {
973
+ "emit": {
974
+ "failure": "PREFERENCE_SAVE_FAILED",
975
+ "success": "PREFERENCE_SAVED"
976
+ }
977
+ }
978
+ ]
979
+ ],
980
+ "event": "UPDATE_PREFERENCE",
981
+ "eventId": "evt_01M0M65FFF3VJFCFJW2MFTQ33R",
982
+ "from": "idle",
983
+ "to": "idle"
984
+ },
985
+ {
986
+ "effects": [
987
+ [
988
+ "persist",
989
+ "delete",
990
+ "NotificationPreference",
991
+ "@payload.id",
992
+ {
993
+ "emit": {
994
+ "failure": "PREFERENCE_SAVE_FAILED",
995
+ "success": "PREFERENCE_DELETED"
996
+ }
997
+ }
998
+ ]
999
+ ],
1000
+ "event": "DELETE_PREFERENCE",
1001
+ "eventId": "evt_01M0M65FFFGSKNV146RNQW7CGC",
1002
+ "from": "idle",
1003
+ "to": "idle"
1004
+ },
1005
+ {
1006
+ "effects": [
1007
+ [
1008
+ "notify",
1009
+ "success",
1010
+ "Notification preference saved"
1011
+ ]
1012
+ ],
1013
+ "event": "PREFERENCE_SAVED",
1014
+ "eventId": "evt_01M0M65FFF7XGSZAATT13F5G5Z",
1015
+ "from": "idle",
1016
+ "to": "idle"
1017
+ },
1018
+ {
1019
+ "effects": [
1020
+ [
1021
+ "notify",
1022
+ "info",
1023
+ "Notification preference removed"
1024
+ ]
1025
+ ],
1026
+ "event": "PREFERENCE_DELETED",
1027
+ "eventId": "evt_01M0M65FFFS4TZ2J5V874NFENP",
1028
+ "from": "idle",
1029
+ "to": "idle"
1030
+ },
1031
+ {
1032
+ "effects": [
1033
+ [
1034
+ "notify",
1035
+ "warning",
1036
+ "Could not save the notification preference"
1037
+ ]
1038
+ ],
1039
+ "event": "PREFERENCE_SAVE_FAILED",
1040
+ "eventId": "evt_01M0M65FFFG5RH4AMKM6PRC7D9",
1041
+ "from": "idle",
1042
+ "to": "idle"
1043
+ }
1044
+ ]
1045
+ }
1046
+ },
1047
+ {
1048
+ "category": "lifecycle",
1049
+ "config": {
1050
+ "digestEnabled": {
1051
+ "default": false,
1052
+ "description": "Drain suppressed notifications (digest-deferred and quiet-hours audit rows) on the hourly cycle. Off by default.",
1053
+ "label": "Deliver digests",
1054
+ "synonyms": "enable digest, digest mode, batch notifications, daily summary, drain suppressed",
1055
+ "tier": "infra",
1056
+ "type": "boolean"
1057
+ },
1058
+ "digestSubject": {
1059
+ "default": "Notification digest",
1060
+ "description": "Subject line for drained digest deliveries.",
1061
+ "label": "Digest email subject",
1062
+ "synonyms": "digest title, summary subject, email subject",
1063
+ "tier": "presentation",
1064
+ "type": "string"
1065
+ },
1066
+ "minAgeHours": {
1067
+ "default": 1.0,
1068
+ "description": "Only drain audit rows at least this many hours old, so quiet-hours suppressions are not redelivered inside their window.",
1069
+ "label": "Minimum age (hours)",
1070
+ "synonyms": "delay, drain delay, hold for, batch window",
1071
+ "tier": "infra",
1072
+ "type": "number"
1073
+ }
1074
+ },
1075
+ "emits": [
1076
+ {
1077
+ "description": "Undispatched digest/quiet-hours audit rows past minAgeHours, oldest batch first",
1078
+ "event": "DIGEST_ROWS_LOADED",
1079
+ "eventId": "evt_01M0M65FFFX5V7JGP2T5AXQS76",
1080
+ "payloadSchema": [
1081
+ {
1082
+ "name": "data",
1083
+ "type": "[NotifRow]"
1084
+ }
1085
+ ],
1086
+ "tier": "secondary"
1087
+ },
1088
+ {
1089
+ "description": "email.send result for the current digest row",
1090
+ "event": "DIGEST_ITEM_SENT",
1091
+ "eventId": "evt_01M0M65FFF1K04JNAZHABZTEHE",
1092
+ "payloadSchema": [
1093
+ {
1094
+ "name": "id",
1095
+ "required": true,
1096
+ "type": "string"
1097
+ },
1098
+ {
1099
+ "name": "status",
1100
+ "required": true,
1101
+ "type": "string"
1102
+ }
1103
+ ],
1104
+ "tier": "secondary"
1105
+ },
1106
+ {
1107
+ "description": "Current row marked dispatched; drives the next loop pass",
1108
+ "event": "DIGEST_STEPPED",
1109
+ "eventId": "evt_01M0M65FFF0QM818V9HGCCN1VA",
1110
+ "payloadSchema": [
1111
+ {
1112
+ "name": "id",
1113
+ "required": true,
1114
+ "type": "string"
1115
+ }
1116
+ ],
1117
+ "tier": "secondary"
1118
+ },
1119
+ {
1120
+ "description": "Digest scan / delivery / persist failed — the cycle stops until the next tick",
1121
+ "event": "DIGEST_FAILED",
1122
+ "eventId": "evt_01M0M65FFFTXQ7Y0YV9XY3X1A5",
1123
+ "payloadSchema": [
1124
+ {
1125
+ "name": "error",
1126
+ "required": true,
1127
+ "type": "string"
1128
+ }
1129
+ ],
1130
+ "tier": "secondary"
1131
+ }
1132
+ ],
1133
+ "entityRefIds": {
1134
+ "DigestRunView": "ent_01M0M65FFFZGACVWJYWZ3AE6ZZ",
1135
+ "NotificationRecord": "ent_01M0M65FFFQ3XBF85WBE2VSWMY"
1136
+ },
1137
+ "id": "trt_01M0M65FFF9APPJEKH9Y561YA4",
1138
+ "linkedEntity": "DigestRunView",
1139
+ "linkedEntityId": "ent_01M0M65FFFZGACVWJYWZ3AE6ZZ",
1140
+ "name": "DigestDrain",
1141
+ "scope": "instance",
1142
+ "stateMachine": {
1143
+ "events": [
1144
+ {
1145
+ "description": "Undispatched digest/quiet-hours audit rows past minAgeHours, oldest batch first",
1146
+ "id": "evt_01M0M65FFFX5V7JGP2T5AXQS76",
1147
+ "key": "DIGEST_ROWS_LOADED",
1148
+ "name": "Digest Rows Loaded",
1149
+ "payloadSchema": [
1150
+ {
1151
+ "name": "data",
1152
+ "properties": [
1153
+ {
1154
+ "name": "id",
1155
+ "type": "string"
1156
+ },
1157
+ {
1158
+ "name": "recipient",
1159
+ "type": "string"
1160
+ },
1161
+ {
1162
+ "name": "channel",
1163
+ "type": "string"
1164
+ },
1165
+ {
1166
+ "name": "message",
1167
+ "type": "string"
1168
+ },
1169
+ {
1170
+ "name": "severity",
1171
+ "type": "string"
1172
+ },
1173
+ {
1174
+ "name": "dispatched",
1175
+ "type": "boolean"
1176
+ },
1177
+ {
1178
+ "name": "error",
1179
+ "type": "string"
1180
+ },
1181
+ {
1182
+ "name": "recordedAt",
1183
+ "type": "number"
1184
+ }
1185
+ ],
1186
+ "type": "[object]"
1187
+ }
1188
+ ],
1189
+ "tier": "secondary"
1190
+ },
1191
+ {
1192
+ "description": "Digest scan / delivery / persist failed — the cycle stops until the next tick",
1193
+ "id": "evt_01M0M65FFFTXQ7Y0YV9XY3X1A5",
1194
+ "key": "DIGEST_FAILED",
1195
+ "name": "Digest Failed",
1196
+ "payloadSchema": [
1197
+ {
1198
+ "name": "error",
1199
+ "required": true,
1200
+ "type": "string"
1201
+ }
1202
+ ],
1203
+ "tier": "secondary"
1204
+ },
1205
+ {
1206
+ "description": "email.send result for the current digest row",
1207
+ "id": "evt_01M0M65FFF1K04JNAZHABZTEHE",
1208
+ "key": "DIGEST_ITEM_SENT",
1209
+ "name": "Digest Item Sent",
1210
+ "payloadSchema": [
1211
+ {
1212
+ "name": "id",
1213
+ "required": true,
1214
+ "type": "string"
1215
+ },
1216
+ {
1217
+ "name": "status",
1218
+ "required": true,
1219
+ "type": "string"
1220
+ }
1221
+ ],
1222
+ "tier": "secondary"
1223
+ },
1224
+ {
1225
+ "description": "Current row marked dispatched; drives the next loop pass",
1226
+ "id": "evt_01M0M65FFF0QM818V9HGCCN1VA",
1227
+ "key": "DIGEST_STEPPED",
1228
+ "name": "Digest Stepped",
1229
+ "payloadSchema": [
1230
+ {
1231
+ "name": "id",
1232
+ "required": true,
1233
+ "type": "string"
1234
+ }
1235
+ ],
1236
+ "tier": "secondary"
1237
+ }
1238
+ ],
1239
+ "states": [
1240
+ {
1241
+ "isInitial": true,
1242
+ "name": "idle"
1243
+ },
1244
+ {
1245
+ "name": "draining"
1246
+ }
1247
+ ],
1248
+ "transitions": [
1249
+ {
1250
+ "effects": [
1251
+ [
1252
+ "set",
1253
+ "@entity.headId",
1254
+ [
1255
+ "object/get",
1256
+ [
1257
+ "array/first",
1258
+ "@payload.data"
1259
+ ],
1260
+ "id"
1261
+ ]
1262
+ ],
1263
+ [
1264
+ "set",
1265
+ "@entity.headRecipient",
1266
+ [
1267
+ "object/get",
1268
+ [
1269
+ "array/first",
1270
+ "@payload.data"
1271
+ ],
1272
+ "recipient"
1273
+ ]
1274
+ ],
1275
+ [
1276
+ "set",
1277
+ "@entity.headMessage",
1278
+ [
1279
+ "object/get",
1280
+ [
1281
+ "array/first",
1282
+ "@payload.data"
1283
+ ],
1284
+ "message"
1285
+ ]
1286
+ ],
1287
+ [
1288
+ "call-service",
1289
+ "email",
1290
+ "send",
1291
+ {
1292
+ "body": "@entity.headMessage",
1293
+ "from": "",
1294
+ "subject": "@config.digestSubject",
1295
+ "to": "@entity.headRecipient"
1296
+ },
1297
+ {
1298
+ "emit": {
1299
+ "failure": "DIGEST_FAILED",
1300
+ "success": "DIGEST_ITEM_SENT"
1301
+ }
1302
+ }
1303
+ ]
1304
+ ],
1305
+ "event": "DIGEST_ROWS_LOADED",
1306
+ "eventId": "evt_01M0M65FFFX5V7JGP2T5AXQS76",
1307
+ "from": "idle",
1308
+ "guard": [
1309
+ "and",
1310
+ "@config.digestEnabled",
1311
+ [
1312
+ ">",
1313
+ [
1314
+ "array/len",
1315
+ "@payload.data"
1316
+ ],
1317
+ 0.0
1318
+ ]
1319
+ ],
1320
+ "to": "draining"
1321
+ },
1322
+ {
1323
+ "event": "DIGEST_ROWS_LOADED",
1324
+ "eventId": "evt_01M0M65FFFX5V7JGP2T5AXQS76",
1325
+ "from": "idle",
1326
+ "guard": [
1327
+ "=",
1328
+ [
1329
+ "array/len",
1330
+ "@payload.data"
1331
+ ],
1332
+ 0.0
1333
+ ],
1334
+ "to": "idle"
1335
+ },
1336
+ {
1337
+ "effects": [
1338
+ [
1339
+ "set",
1340
+ "@entity.lastError",
1341
+ "@payload.error"
1342
+ ]
1343
+ ],
1344
+ "event": "DIGEST_FAILED",
1345
+ "eventId": "evt_01M0M65FFFTXQ7Y0YV9XY3X1A5",
1346
+ "from": "idle",
1347
+ "to": "idle"
1348
+ },
1349
+ {
1350
+ "effects": [
1351
+ [
1352
+ "set",
1353
+ "@entity.drainedCount",
1354
+ [
1355
+ "+",
1356
+ "@entity.drainedCount",
1357
+ 1.0
1358
+ ]
1359
+ ],
1360
+ [
1361
+ "persist",
1362
+ "update",
1363
+ "NotificationRecord",
1364
+ {
1365
+ "dispatched": true,
1366
+ "id": "@entity.headId"
1367
+ },
1368
+ {
1369
+ "emit": {
1370
+ "failure": "DIGEST_FAILED",
1371
+ "success": "DIGEST_STEPPED"
1372
+ }
1373
+ }
1374
+ ]
1375
+ ],
1376
+ "event": "DIGEST_ITEM_SENT",
1377
+ "eventId": "evt_01M0M65FFF1K04JNAZHABZTEHE",
1378
+ "from": "draining",
1379
+ "to": "draining"
1380
+ },
1381
+ {
1382
+ "effects": [
1383
+ [
1384
+ "fetch",
1385
+ "NotificationRecord",
1386
+ {
1387
+ "emit": {
1388
+ "failure": "DIGEST_FAILED",
1389
+ "success": "DIGEST_ROWS_LOADED"
1390
+ },
1391
+ "filter": [
1392
+ "and",
1393
+ [
1394
+ "=",
1395
+ [
1396
+ "object/get",
1397
+ "@entity",
1398
+ "dispatched"
1399
+ ],
1400
+ false
1401
+ ],
1402
+ [
1403
+ "or",
1404
+ [
1405
+ "=",
1406
+ [
1407
+ "object/get",
1408
+ "@entity",
1409
+ "error"
1410
+ ],
1411
+ "digest-deferred"
1412
+ ],
1413
+ [
1414
+ "=",
1415
+ [
1416
+ "object/get",
1417
+ "@entity",
1418
+ "error"
1419
+ ],
1420
+ "quiet-hours"
1421
+ ]
1422
+ ],
1423
+ [
1424
+ "<",
1425
+ [
1426
+ "object/get",
1427
+ "@entity",
1428
+ "recordedAt"
1429
+ ],
1430
+ [
1431
+ "-",
1432
+ "@now",
1433
+ [
1434
+ "*",
1435
+ "@config.minAgeHours",
1436
+ 3600000.0
1437
+ ]
1438
+ ]
1439
+ ]
1440
+ ]
1441
+ }
1442
+ ]
1443
+ ],
1444
+ "event": "DIGEST_STEPPED",
1445
+ "eventId": "evt_01M0M65FFF0QM818V9HGCCN1VA",
1446
+ "from": "draining",
1447
+ "to": "draining"
1448
+ },
1449
+ {
1450
+ "effects": [
1451
+ [
1452
+ "set",
1453
+ "@entity.headId",
1454
+ [
1455
+ "object/get",
1456
+ [
1457
+ "array/first",
1458
+ "@payload.data"
1459
+ ],
1460
+ "id"
1461
+ ]
1462
+ ],
1463
+ [
1464
+ "set",
1465
+ "@entity.headRecipient",
1466
+ [
1467
+ "object/get",
1468
+ [
1469
+ "array/first",
1470
+ "@payload.data"
1471
+ ],
1472
+ "recipient"
1473
+ ]
1474
+ ],
1475
+ [
1476
+ "set",
1477
+ "@entity.headMessage",
1478
+ [
1479
+ "object/get",
1480
+ [
1481
+ "array/first",
1482
+ "@payload.data"
1483
+ ],
1484
+ "message"
1485
+ ]
1486
+ ],
1487
+ [
1488
+ "call-service",
1489
+ "email",
1490
+ "send",
1491
+ {
1492
+ "body": "@entity.headMessage",
1493
+ "from": "",
1494
+ "subject": "@config.digestSubject",
1495
+ "to": "@entity.headRecipient"
1496
+ },
1497
+ {
1498
+ "emit": {
1499
+ "failure": "DIGEST_FAILED",
1500
+ "success": "DIGEST_ITEM_SENT"
1501
+ }
1502
+ }
1503
+ ]
1504
+ ],
1505
+ "event": "DIGEST_ROWS_LOADED",
1506
+ "eventId": "evt_01M0M65FFFX5V7JGP2T5AXQS76",
1507
+ "from": "draining",
1508
+ "guard": [
1509
+ ">",
1510
+ [
1511
+ "array/len",
1512
+ "@payload.data"
1513
+ ],
1514
+ 0.0
1515
+ ],
1516
+ "to": "draining"
1517
+ },
1518
+ {
1519
+ "event": "DIGEST_ROWS_LOADED",
1520
+ "eventId": "evt_01M0M65FFFX5V7JGP2T5AXQS76",
1521
+ "from": "draining",
1522
+ "guard": [
1523
+ "=",
1524
+ [
1525
+ "array/len",
1526
+ "@payload.data"
1527
+ ],
1528
+ 0.0
1529
+ ],
1530
+ "to": "idle"
1531
+ },
1532
+ {
1533
+ "effects": [
1534
+ [
1535
+ "set",
1536
+ "@entity.lastError",
1537
+ "@payload.error"
1538
+ ]
1539
+ ],
1540
+ "event": "DIGEST_FAILED",
1541
+ "eventId": "evt_01M0M65FFFTXQ7Y0YV9XY3X1A5",
1542
+ "from": "draining",
1543
+ "to": "idle"
1544
+ }
1545
+ ]
1546
+ },
1547
+ "ticks": [
1548
+ {
1549
+ "effects": [
1550
+ [
1551
+ "fetch",
1552
+ "NotificationRecord",
1553
+ {
1554
+ "emit": {
1555
+ "failure": "DIGEST_FAILED",
1556
+ "success": "DIGEST_ROWS_LOADED"
1557
+ },
1558
+ "filter": [
1559
+ "and",
1560
+ [
1561
+ "=",
1562
+ [
1563
+ "object/get",
1564
+ "@entity",
1565
+ "dispatched"
1566
+ ],
1567
+ false
1568
+ ],
1569
+ [
1570
+ "or",
1571
+ [
1572
+ "=",
1573
+ [
1574
+ "object/get",
1575
+ "@entity",
1576
+ "error"
1577
+ ],
1578
+ "digest-deferred"
1579
+ ],
1580
+ [
1581
+ "=",
1582
+ [
1583
+ "object/get",
1584
+ "@entity",
1585
+ "error"
1586
+ ],
1587
+ "quiet-hours"
1588
+ ]
1589
+ ],
1590
+ [
1591
+ "<",
1592
+ [
1593
+ "object/get",
1594
+ "@entity",
1595
+ "recordedAt"
1596
+ ],
1597
+ [
1598
+ "-",
1599
+ "@now",
1600
+ [
1601
+ "*",
1602
+ "@config.minAgeHours",
1603
+ 3600000.0
1604
+ ]
1605
+ ]
1606
+ ]
1607
+ ]
1608
+ }
1609
+ ]
1610
+ ],
1611
+ "interval": "0 * * * *",
1612
+ "name": "digestCycle"
1613
+ }
1614
+ ]
1615
+ }
1616
+ ]
1617
+ }
1618
+ ],
1619
+ "schemaVersion": 1,
1620
+ "version": "1.0.0"
1621
+ }