@ketch.to/schema 0.0.0-stage → 0.1.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.
- package/README.md +11 -2
- package/card.schema.json +601 -0
- package/dist/card.schema.json +601 -0
- package/dist/fixtures/index.d.ts +27 -0
- package/dist/fixtures/index.js +120 -0
- package/dist/src/duration.d.ts +7 -0
- package/dist/src/duration.js +21 -0
- package/dist/src/index.d.ts +4 -0
- package/dist/src/index.js +4 -0
- package/dist/src/presets.d.ts +22 -0
- package/dist/src/presets.js +56 -0
- package/dist/src/types.d.ts +139 -0
- package/dist/src/types.js +9 -0
- package/dist/src/validate.d.ts +505 -0
- package/dist/src/validate.js +92 -0
- package/package.json +47 -4
package/README.md
CHANGED
|
@@ -1,3 +1,12 @@
|
|
|
1
|
-
#
|
|
1
|
+
# @ketch.to/schema
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
The card schema for [Ketch](https://ketch.to): JSON Schema (draft 2020-12), TypeScript types, validators and kind presets.
|
|
4
|
+
|
|
5
|
+
```ts
|
|
6
|
+
import { validateNewCard, withKindDefaults, type NewCard } from "@ketch.to/schema";
|
|
7
|
+
|
|
8
|
+
const result = validateNewCard({ title: "Reply to Shaina's marketing plan", kind: "do" });
|
|
9
|
+
if (!result.ok) console.error(result.errors);
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
The raw schema is exported as `@ketch.to/schema/card.schema.json`, and example cards for every kind as `@ketch.to/schema/fixtures`.
|
package/card.schema.json
ADDED
|
@@ -0,0 +1,601 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "https://ketch.to/schemas/card.json",
|
|
4
|
+
"title": "Ketch card schema",
|
|
5
|
+
"description": "The one data structure in Ketch. A card is a question an agent asks a person; it has exactly one outcome.",
|
|
6
|
+
"$defs": {
|
|
7
|
+
"Duration": {
|
|
8
|
+
"type": "string",
|
|
9
|
+
"description": "Relative duration: <integer><unit>, unit one of m (minutes), h (hours), d (days), w (weeks).",
|
|
10
|
+
"pattern": "^[1-9][0-9]{0,4}[mhdw]$",
|
|
11
|
+
"examples": [
|
|
12
|
+
"1h",
|
|
13
|
+
"3d",
|
|
14
|
+
"14d",
|
|
15
|
+
"2w"
|
|
16
|
+
]
|
|
17
|
+
},
|
|
18
|
+
"CardId": {
|
|
19
|
+
"type": "string",
|
|
20
|
+
"pattern": "^card_[0-9A-HJKMNP-TV-Z]{26}$",
|
|
21
|
+
"description": "Server-assigned. 'card_' + ULID."
|
|
22
|
+
},
|
|
23
|
+
"ActionId": {
|
|
24
|
+
"type": "string",
|
|
25
|
+
"pattern": "^[a-z][a-z0-9_]{0,31}$",
|
|
26
|
+
"description": "Producer-chosen id, echoed back in the outcome. 'snooze' and 'not_good' are reserved and always available."
|
|
27
|
+
},
|
|
28
|
+
"ActionStyle": {
|
|
29
|
+
"type": "string",
|
|
30
|
+
"enum": [
|
|
31
|
+
"positive",
|
|
32
|
+
"snooze",
|
|
33
|
+
"neutral"
|
|
34
|
+
],
|
|
35
|
+
"description": "positive: swipe-right target, accent colour. snooze: tap = 1h, hold = day slider. neutral: plain button."
|
|
36
|
+
},
|
|
37
|
+
"Action": {
|
|
38
|
+
"type": "object",
|
|
39
|
+
"additionalProperties": false,
|
|
40
|
+
"required": [
|
|
41
|
+
"id",
|
|
42
|
+
"label"
|
|
43
|
+
],
|
|
44
|
+
"properties": {
|
|
45
|
+
"id": {
|
|
46
|
+
"$ref": "#/$defs/ActionId"
|
|
47
|
+
},
|
|
48
|
+
"label": {
|
|
49
|
+
"type": "string",
|
|
50
|
+
"minLength": 1,
|
|
51
|
+
"maxLength": 24
|
|
52
|
+
},
|
|
53
|
+
"style": {
|
|
54
|
+
"$ref": "#/$defs/ActionStyle",
|
|
55
|
+
"default": "neutral"
|
|
56
|
+
},
|
|
57
|
+
"input": {
|
|
58
|
+
"type": "string",
|
|
59
|
+
"enum": [
|
|
60
|
+
"optional",
|
|
61
|
+
"required"
|
|
62
|
+
],
|
|
63
|
+
"description": "Open a text sheet before posting this action."
|
|
64
|
+
},
|
|
65
|
+
"snooze_for": {
|
|
66
|
+
"$ref": "#/$defs/Duration",
|
|
67
|
+
"description": "Only for style 'snooze': the default snooze on tap. Defaults to 1h."
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
},
|
|
71
|
+
"Actions": {
|
|
72
|
+
"type": "array",
|
|
73
|
+
"minItems": 1,
|
|
74
|
+
"maxItems": 4,
|
|
75
|
+
"items": {
|
|
76
|
+
"$ref": "#/$defs/Action"
|
|
77
|
+
}
|
|
78
|
+
},
|
|
79
|
+
"Source": {
|
|
80
|
+
"type": "object",
|
|
81
|
+
"additionalProperties": false,
|
|
82
|
+
"properties": {
|
|
83
|
+
"app": {
|
|
84
|
+
"type": "string",
|
|
85
|
+
"minLength": 1,
|
|
86
|
+
"maxLength": 40,
|
|
87
|
+
"description": "Defaults to the API key's name."
|
|
88
|
+
},
|
|
89
|
+
"context": {
|
|
90
|
+
"type": "string",
|
|
91
|
+
"minLength": 1,
|
|
92
|
+
"maxLength": 120
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
},
|
|
96
|
+
"Input": {
|
|
97
|
+
"type": "object",
|
|
98
|
+
"additionalProperties": false,
|
|
99
|
+
"properties": {
|
|
100
|
+
"placeholder": {
|
|
101
|
+
"type": "string",
|
|
102
|
+
"maxLength": 80
|
|
103
|
+
},
|
|
104
|
+
"spawns": {
|
|
105
|
+
"type": "boolean",
|
|
106
|
+
"default": false,
|
|
107
|
+
"description": "Each entry the person types becomes a new card (event card.spawned)."
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
},
|
|
111
|
+
"Recurrence": {
|
|
112
|
+
"type": "object",
|
|
113
|
+
"additionalProperties": false,
|
|
114
|
+
"required": [
|
|
115
|
+
"every"
|
|
116
|
+
],
|
|
117
|
+
"properties": {
|
|
118
|
+
"every": {
|
|
119
|
+
"$ref": "#/$defs/Duration"
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
},
|
|
123
|
+
"Kind": {
|
|
124
|
+
"type": "string",
|
|
125
|
+
"enum": [
|
|
126
|
+
"do",
|
|
127
|
+
"choose",
|
|
128
|
+
"checkin",
|
|
129
|
+
"decide",
|
|
130
|
+
"read",
|
|
131
|
+
"recap"
|
|
132
|
+
],
|
|
133
|
+
"description": "Preset. Fills in default actions (and recurrence/input for some) when the producer omits them. Never requires app code."
|
|
134
|
+
},
|
|
135
|
+
"Priority": {
|
|
136
|
+
"type": "integer",
|
|
137
|
+
"minimum": 1,
|
|
138
|
+
"maximum": 5,
|
|
139
|
+
"default": 3,
|
|
140
|
+
"description": "1 urgent … 5 ambient. ≤2 pushes a notification."
|
|
141
|
+
},
|
|
142
|
+
"Link": {
|
|
143
|
+
"type": "string",
|
|
144
|
+
"pattern": "^(https://|shortcuts://)[^\\s]+$",
|
|
145
|
+
"maxLength": 2048,
|
|
146
|
+
"description": "Opened with the system. https:// or shortcuts:// only."
|
|
147
|
+
},
|
|
148
|
+
"Meta": {
|
|
149
|
+
"type": "object",
|
|
150
|
+
"description": "Producer's own bag. Echoed back untouched in webhooks and outcomes."
|
|
151
|
+
},
|
|
152
|
+
"CardFields": {
|
|
153
|
+
"type": "object",
|
|
154
|
+
"properties": {
|
|
155
|
+
"title": {
|
|
156
|
+
"type": "string",
|
|
157
|
+
"minLength": 1,
|
|
158
|
+
"maxLength": 140
|
|
159
|
+
},
|
|
160
|
+
"body": {
|
|
161
|
+
"type": "string",
|
|
162
|
+
"maxLength": 4000,
|
|
163
|
+
"description": "Plain text or light markdown."
|
|
164
|
+
},
|
|
165
|
+
"source": {
|
|
166
|
+
"$ref": "#/$defs/Source"
|
|
167
|
+
},
|
|
168
|
+
"link": {
|
|
169
|
+
"$ref": "#/$defs/Link"
|
|
170
|
+
},
|
|
171
|
+
"priority": {
|
|
172
|
+
"$ref": "#/$defs/Priority"
|
|
173
|
+
},
|
|
174
|
+
"kind": {
|
|
175
|
+
"$ref": "#/$defs/Kind",
|
|
176
|
+
"default": "do"
|
|
177
|
+
},
|
|
178
|
+
"actions": {
|
|
179
|
+
"$ref": "#/$defs/Actions"
|
|
180
|
+
},
|
|
181
|
+
"input": {
|
|
182
|
+
"$ref": "#/$defs/Input"
|
|
183
|
+
},
|
|
184
|
+
"recurrence": {
|
|
185
|
+
"$ref": "#/$defs/Recurrence"
|
|
186
|
+
},
|
|
187
|
+
"show_after": {
|
|
188
|
+
"type": [
|
|
189
|
+
"string",
|
|
190
|
+
"null"
|
|
191
|
+
],
|
|
192
|
+
"format": "date-time",
|
|
193
|
+
"description": "Hidden until then. Snooze writes this."
|
|
194
|
+
},
|
|
195
|
+
"expires_at": {
|
|
196
|
+
"type": [
|
|
197
|
+
"string",
|
|
198
|
+
"null"
|
|
199
|
+
],
|
|
200
|
+
"format": "date-time",
|
|
201
|
+
"description": "Retired automatically with outcome action 'expired'."
|
|
202
|
+
},
|
|
203
|
+
"meta": {
|
|
204
|
+
"$ref": "#/$defs/Meta"
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
},
|
|
208
|
+
"NewCard": {
|
|
209
|
+
"description": "What a producer POSTs. Everything but title is optional; kind fills in actions.",
|
|
210
|
+
"allOf": [
|
|
211
|
+
{
|
|
212
|
+
"$ref": "#/$defs/CardFields"
|
|
213
|
+
}
|
|
214
|
+
],
|
|
215
|
+
"type": "object",
|
|
216
|
+
"additionalProperties": false,
|
|
217
|
+
"required": [
|
|
218
|
+
"title"
|
|
219
|
+
],
|
|
220
|
+
"properties": {
|
|
221
|
+
"title": true,
|
|
222
|
+
"body": true,
|
|
223
|
+
"source": true,
|
|
224
|
+
"link": true,
|
|
225
|
+
"priority": true,
|
|
226
|
+
"kind": true,
|
|
227
|
+
"actions": true,
|
|
228
|
+
"input": true,
|
|
229
|
+
"recurrence": true,
|
|
230
|
+
"show_after": true,
|
|
231
|
+
"expires_at": true,
|
|
232
|
+
"meta": true
|
|
233
|
+
}
|
|
234
|
+
},
|
|
235
|
+
"CardPatch": {
|
|
236
|
+
"description": "What PATCH /cards/:id accepts. Producer-side edits only.",
|
|
237
|
+
"type": "object",
|
|
238
|
+
"additionalProperties": false,
|
|
239
|
+
"minProperties": 1,
|
|
240
|
+
"properties": {
|
|
241
|
+
"title": {
|
|
242
|
+
"type": "string",
|
|
243
|
+
"minLength": 1,
|
|
244
|
+
"maxLength": 140
|
|
245
|
+
},
|
|
246
|
+
"body": {
|
|
247
|
+
"type": [
|
|
248
|
+
"string",
|
|
249
|
+
"null"
|
|
250
|
+
],
|
|
251
|
+
"maxLength": 4000
|
|
252
|
+
},
|
|
253
|
+
"actions": {
|
|
254
|
+
"$ref": "#/$defs/Actions"
|
|
255
|
+
},
|
|
256
|
+
"show_after": {
|
|
257
|
+
"type": [
|
|
258
|
+
"string",
|
|
259
|
+
"null"
|
|
260
|
+
],
|
|
261
|
+
"format": "date-time"
|
|
262
|
+
},
|
|
263
|
+
"priority": {
|
|
264
|
+
"$ref": "#/$defs/Priority"
|
|
265
|
+
},
|
|
266
|
+
"link": {
|
|
267
|
+
"anyOf": [
|
|
268
|
+
{
|
|
269
|
+
"$ref": "#/$defs/Link"
|
|
270
|
+
},
|
|
271
|
+
{
|
|
272
|
+
"type": "null"
|
|
273
|
+
}
|
|
274
|
+
]
|
|
275
|
+
},
|
|
276
|
+
"expires_at": {
|
|
277
|
+
"type": [
|
|
278
|
+
"string",
|
|
279
|
+
"null"
|
|
280
|
+
],
|
|
281
|
+
"format": "date-time"
|
|
282
|
+
},
|
|
283
|
+
"meta": {
|
|
284
|
+
"$ref": "#/$defs/Meta"
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
},
|
|
288
|
+
"Status": {
|
|
289
|
+
"type": "string",
|
|
290
|
+
"enum": [
|
|
291
|
+
"open",
|
|
292
|
+
"snoozed",
|
|
293
|
+
"done"
|
|
294
|
+
],
|
|
295
|
+
"description": "open: in the queue. snoozed: open but show_after is in the future. done: retired (acted, deleted or expired)."
|
|
296
|
+
},
|
|
297
|
+
"Outcome": {
|
|
298
|
+
"type": "object",
|
|
299
|
+
"additionalProperties": false,
|
|
300
|
+
"required": [
|
|
301
|
+
"action",
|
|
302
|
+
"text",
|
|
303
|
+
"at",
|
|
304
|
+
"snoozed_until"
|
|
305
|
+
],
|
|
306
|
+
"properties": {
|
|
307
|
+
"action": {
|
|
308
|
+
"$ref": "#/$defs/ActionId"
|
|
309
|
+
},
|
|
310
|
+
"text": {
|
|
311
|
+
"type": [
|
|
312
|
+
"string",
|
|
313
|
+
"null"
|
|
314
|
+
],
|
|
315
|
+
"maxLength": 4000
|
|
316
|
+
},
|
|
317
|
+
"at": {
|
|
318
|
+
"type": "string",
|
|
319
|
+
"format": "date-time"
|
|
320
|
+
},
|
|
321
|
+
"snoozed_until": {
|
|
322
|
+
"type": [
|
|
323
|
+
"string",
|
|
324
|
+
"null"
|
|
325
|
+
],
|
|
326
|
+
"format": "date-time"
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
},
|
|
330
|
+
"OutcomeInput": {
|
|
331
|
+
"description": "What the app POSTs to /cards/:id/outcome. One per card (snoozes excepted).",
|
|
332
|
+
"type": "object",
|
|
333
|
+
"additionalProperties": false,
|
|
334
|
+
"required": [
|
|
335
|
+
"action"
|
|
336
|
+
],
|
|
337
|
+
"properties": {
|
|
338
|
+
"action": {
|
|
339
|
+
"$ref": "#/$defs/ActionId"
|
|
340
|
+
},
|
|
341
|
+
"text": {
|
|
342
|
+
"type": [
|
|
343
|
+
"string",
|
|
344
|
+
"null"
|
|
345
|
+
],
|
|
346
|
+
"maxLength": 4000
|
|
347
|
+
},
|
|
348
|
+
"snoozed_until": {
|
|
349
|
+
"type": [
|
|
350
|
+
"string",
|
|
351
|
+
"null"
|
|
352
|
+
],
|
|
353
|
+
"format": "date-time",
|
|
354
|
+
"description": "Required when action is 'snooze' (or any snooze-style action)."
|
|
355
|
+
},
|
|
356
|
+
"spawn": {
|
|
357
|
+
"type": "array",
|
|
358
|
+
"maxItems": 20,
|
|
359
|
+
"items": {
|
|
360
|
+
"type": "string",
|
|
361
|
+
"minLength": 1,
|
|
362
|
+
"maxLength": 140
|
|
363
|
+
},
|
|
364
|
+
"description": "Titles of new cards to create from the card's spawning input."
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
},
|
|
368
|
+
"Card": {
|
|
369
|
+
"description": "A card as the server returns it.",
|
|
370
|
+
"allOf": [
|
|
371
|
+
{
|
|
372
|
+
"$ref": "#/$defs/CardFields"
|
|
373
|
+
}
|
|
374
|
+
],
|
|
375
|
+
"type": "object",
|
|
376
|
+
"additionalProperties": false,
|
|
377
|
+
"required": [
|
|
378
|
+
"id",
|
|
379
|
+
"title",
|
|
380
|
+
"source",
|
|
381
|
+
"priority",
|
|
382
|
+
"kind",
|
|
383
|
+
"actions",
|
|
384
|
+
"status",
|
|
385
|
+
"created_at",
|
|
386
|
+
"updated_at"
|
|
387
|
+
],
|
|
388
|
+
"properties": {
|
|
389
|
+
"id": {
|
|
390
|
+
"$ref": "#/$defs/CardId"
|
|
391
|
+
},
|
|
392
|
+
"title": true,
|
|
393
|
+
"body": true,
|
|
394
|
+
"link": true,
|
|
395
|
+
"priority": true,
|
|
396
|
+
"kind": true,
|
|
397
|
+
"actions": true,
|
|
398
|
+
"input": true,
|
|
399
|
+
"recurrence": true,
|
|
400
|
+
"show_after": true,
|
|
401
|
+
"expires_at": true,
|
|
402
|
+
"meta": true,
|
|
403
|
+
"source": {
|
|
404
|
+
"type": "object",
|
|
405
|
+
"additionalProperties": false,
|
|
406
|
+
"required": [
|
|
407
|
+
"app"
|
|
408
|
+
],
|
|
409
|
+
"properties": {
|
|
410
|
+
"app": {
|
|
411
|
+
"type": "string",
|
|
412
|
+
"minLength": 1,
|
|
413
|
+
"maxLength": 40
|
|
414
|
+
},
|
|
415
|
+
"context": {
|
|
416
|
+
"type": "string",
|
|
417
|
+
"minLength": 1,
|
|
418
|
+
"maxLength": 120
|
|
419
|
+
}
|
|
420
|
+
}
|
|
421
|
+
},
|
|
422
|
+
"status": {
|
|
423
|
+
"$ref": "#/$defs/Status"
|
|
424
|
+
},
|
|
425
|
+
"parent_id": {
|
|
426
|
+
"anyOf": [
|
|
427
|
+
{
|
|
428
|
+
"$ref": "#/$defs/CardId"
|
|
429
|
+
},
|
|
430
|
+
{
|
|
431
|
+
"type": "null"
|
|
432
|
+
}
|
|
433
|
+
],
|
|
434
|
+
"description": "Set on cards spawned from another card's input."
|
|
435
|
+
},
|
|
436
|
+
"outcome": {
|
|
437
|
+
"anyOf": [
|
|
438
|
+
{
|
|
439
|
+
"$ref": "#/$defs/Outcome"
|
|
440
|
+
},
|
|
441
|
+
{
|
|
442
|
+
"type": "null"
|
|
443
|
+
}
|
|
444
|
+
],
|
|
445
|
+
"description": "The last outcome, if any. Recurring cards keep their latest."
|
|
446
|
+
},
|
|
447
|
+
"created_at": {
|
|
448
|
+
"type": "string",
|
|
449
|
+
"format": "date-time"
|
|
450
|
+
},
|
|
451
|
+
"updated_at": {
|
|
452
|
+
"type": "string",
|
|
453
|
+
"format": "date-time"
|
|
454
|
+
},
|
|
455
|
+
"retired_at": {
|
|
456
|
+
"type": [
|
|
457
|
+
"string",
|
|
458
|
+
"null"
|
|
459
|
+
],
|
|
460
|
+
"format": "date-time"
|
|
461
|
+
}
|
|
462
|
+
}
|
|
463
|
+
},
|
|
464
|
+
"WebhookEvent": {
|
|
465
|
+
"type": "string",
|
|
466
|
+
"enum": [
|
|
467
|
+
"card.acted",
|
|
468
|
+
"card.snoozed",
|
|
469
|
+
"card.spawned"
|
|
470
|
+
]
|
|
471
|
+
},
|
|
472
|
+
"NewWebhook": {
|
|
473
|
+
"type": "object",
|
|
474
|
+
"additionalProperties": false,
|
|
475
|
+
"required": [
|
|
476
|
+
"url",
|
|
477
|
+
"secret",
|
|
478
|
+
"events"
|
|
479
|
+
],
|
|
480
|
+
"properties": {
|
|
481
|
+
"url": {
|
|
482
|
+
"type": "string",
|
|
483
|
+
"pattern": "^https?://[^\\s]+$",
|
|
484
|
+
"maxLength": 2048
|
|
485
|
+
},
|
|
486
|
+
"secret": {
|
|
487
|
+
"type": "string",
|
|
488
|
+
"minLength": 16,
|
|
489
|
+
"maxLength": 256
|
|
490
|
+
},
|
|
491
|
+
"events": {
|
|
492
|
+
"type": "array",
|
|
493
|
+
"minItems": 1,
|
|
494
|
+
"uniqueItems": true,
|
|
495
|
+
"items": {
|
|
496
|
+
"$ref": "#/$defs/WebhookEvent"
|
|
497
|
+
}
|
|
498
|
+
}
|
|
499
|
+
}
|
|
500
|
+
},
|
|
501
|
+
"Webhook": {
|
|
502
|
+
"type": "object",
|
|
503
|
+
"additionalProperties": false,
|
|
504
|
+
"required": [
|
|
505
|
+
"id",
|
|
506
|
+
"url",
|
|
507
|
+
"events",
|
|
508
|
+
"created_at"
|
|
509
|
+
],
|
|
510
|
+
"properties": {
|
|
511
|
+
"id": {
|
|
512
|
+
"type": "string",
|
|
513
|
+
"pattern": "^wh_[0-9A-HJKMNP-TV-Z]{26}$"
|
|
514
|
+
},
|
|
515
|
+
"url": {
|
|
516
|
+
"type": "string"
|
|
517
|
+
},
|
|
518
|
+
"events": {
|
|
519
|
+
"type": "array",
|
|
520
|
+
"items": {
|
|
521
|
+
"$ref": "#/$defs/WebhookEvent"
|
|
522
|
+
}
|
|
523
|
+
},
|
|
524
|
+
"created_at": {
|
|
525
|
+
"type": "string",
|
|
526
|
+
"format": "date-time"
|
|
527
|
+
}
|
|
528
|
+
}
|
|
529
|
+
},
|
|
530
|
+
"WebhookPayload": {
|
|
531
|
+
"description": "Body of every webhook POST. HMAC-SHA256 hex of the raw body, keyed with the webhook secret, in X-Ketch-Signature.",
|
|
532
|
+
"type": "object",
|
|
533
|
+
"additionalProperties": false,
|
|
534
|
+
"required": [
|
|
535
|
+
"id",
|
|
536
|
+
"event",
|
|
537
|
+
"at"
|
|
538
|
+
],
|
|
539
|
+
"properties": {
|
|
540
|
+
"id": {
|
|
541
|
+
"type": "string",
|
|
542
|
+
"description": "Delivery id. Same id on every retry; use it to dedupe."
|
|
543
|
+
},
|
|
544
|
+
"event": {
|
|
545
|
+
"$ref": "#/$defs/WebhookEvent"
|
|
546
|
+
},
|
|
547
|
+
"at": {
|
|
548
|
+
"type": "string",
|
|
549
|
+
"format": "date-time"
|
|
550
|
+
},
|
|
551
|
+
"card": {
|
|
552
|
+
"$ref": "#/$defs/Card"
|
|
553
|
+
},
|
|
554
|
+
"outcome": {
|
|
555
|
+
"$ref": "#/$defs/Outcome"
|
|
556
|
+
},
|
|
557
|
+
"parent": {
|
|
558
|
+
"$ref": "#/$defs/Card"
|
|
559
|
+
}
|
|
560
|
+
},
|
|
561
|
+
"oneOf": [
|
|
562
|
+
{
|
|
563
|
+
"properties": {
|
|
564
|
+
"event": {
|
|
565
|
+
"const": "card.acted"
|
|
566
|
+
},
|
|
567
|
+
"parent": false
|
|
568
|
+
},
|
|
569
|
+
"required": [
|
|
570
|
+
"card",
|
|
571
|
+
"outcome"
|
|
572
|
+
]
|
|
573
|
+
},
|
|
574
|
+
{
|
|
575
|
+
"properties": {
|
|
576
|
+
"event": {
|
|
577
|
+
"const": "card.snoozed"
|
|
578
|
+
},
|
|
579
|
+
"parent": false
|
|
580
|
+
},
|
|
581
|
+
"required": [
|
|
582
|
+
"card",
|
|
583
|
+
"outcome"
|
|
584
|
+
]
|
|
585
|
+
},
|
|
586
|
+
{
|
|
587
|
+
"properties": {
|
|
588
|
+
"event": {
|
|
589
|
+
"const": "card.spawned"
|
|
590
|
+
},
|
|
591
|
+
"outcome": false
|
|
592
|
+
},
|
|
593
|
+
"required": [
|
|
594
|
+
"parent",
|
|
595
|
+
"card"
|
|
596
|
+
]
|
|
597
|
+
}
|
|
598
|
+
]
|
|
599
|
+
}
|
|
600
|
+
}
|
|
601
|
+
}
|