@substrat-run/engine-booking 0.5.3 → 0.6.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.
@@ -0,0 +1,701 @@
1
+ /**
2
+ * The booking engine's declared operation surface (#707/#738/#865).
3
+ *
4
+ * ## Why this file exists now
5
+ *
6
+ * It used to not. `index.ts` carried an `OPERATIONS` map of handlers and a note
7
+ * explaining that the map was "the only description of this engine's operation
8
+ * surface", which is why the lifecycle had to live at the bottom of the same
9
+ * file. That note is deleted along with the arrangement it described: a
10
+ * DECLARATION imports only `entities.ts` and `schemas.ts`, so nothing here
11
+ * reaches back into the implementation and there is no cycle to dodge.
12
+ *
13
+ * The immediate reason is #865: `entityCheckConformanceSuite` derives its
14
+ * behavioural pair from `permission` and `input`, and seven of this engine's
15
+ * checks narrow to a reservation. Undeclared, they were not merely untested but
16
+ * undeclarable — `ctx.check(PERM.confirm, reservationRef(id))` and
17
+ * `ctx.check(PERM.confirm)` are the same to a compiler, and the second lets
18
+ * anyone holding `booking:confirm` anywhere in the scope confirm anyone's
19
+ * reservation.
20
+ *
21
+ * What is deliberately NOT here is `http`. An engine is entity-agnostic and owns
22
+ * no URL shape: a padel club calls a reservation a court booking and a clinic
23
+ * calls it an appointment, and both are right. The path is the composing
24
+ * vertical's decision, declared with `defineEngineRoutes` against these names.
25
+ *
26
+ * ## The node checks are a fact, not an omission
27
+ *
28
+ * Four operations check at the NODE while taking a `reservationId`, and that
29
+ * asymmetry is deliberate enough to be worth naming: `booking/expire` sweeps a
30
+ * lapsed hold and `booking/start` / `booking/complete` / `booking/no-show` are
31
+ * service-desk verbs. Each is staff work over whatever reservation is in front
32
+ * of them, not a participant reaching their own booking — so the authority is
33
+ * scope-wide and a narrowed grant would not widen to cover it. `booking/get`
34
+ * and the five participant-facing mutations narrow, because there a grant on
35
+ * one reservation is the whole of someone's access.
36
+ */
37
+ import { z } from '@substrat-run/contracts';
38
+ /** The keys these operations check. Mirrors `PERM` in index.ts. */
39
+ export declare const BOOKING_PERMISSIONS: readonly ['booking:create', 'booking:read', 'booking:hold', 'booking:confirm', 'booking:cancel', 'booking:move', 'booking:complete', 'booking:manage-resources'];
40
+ export declare const bookingOperations: {
41
+ readonly 'booking/create-resource': {
42
+ readonly summary: "Register a bookable resource";
43
+ readonly permission: "booking:manage-resources";
44
+ readonly input: z.ZodObject<{
45
+ kind: z.ZodString;
46
+ name: z.ZodString;
47
+ capacity: z.ZodOptional<z.ZodNumber>;
48
+ }, z.core.$strip>;
49
+ readonly output: z.ZodObject<{
50
+ id: z.ZodString;
51
+ kind: z.ZodString;
52
+ name: z.ZodString;
53
+ capacity: z.ZodNumber;
54
+ active: z.ZodBoolean;
55
+ createdAt: z.ZodString;
56
+ }, z.core.$strip>;
57
+ };
58
+ readonly 'booking/set-resource-active': {
59
+ readonly summary: "Take a resource in or out of service";
60
+ readonly permission: "booking:manage-resources";
61
+ readonly input: z.ZodObject<{
62
+ resourceId: z.ZodString;
63
+ active: z.ZodBoolean;
64
+ }, z.core.$strip>;
65
+ readonly output: z.ZodObject<{
66
+ id: z.ZodString;
67
+ kind: z.ZodString;
68
+ name: z.ZodString;
69
+ capacity: z.ZodNumber;
70
+ active: z.ZodBoolean;
71
+ createdAt: z.ZodString;
72
+ }, z.core.$strip>;
73
+ };
74
+ readonly 'booking/list-resources': {
75
+ readonly summary: "Bookable resources, by name";
76
+ readonly permission: "booking:read";
77
+ readonly input: z.ZodObject<{
78
+ kind: z.ZodOptional<z.ZodString>;
79
+ }, z.core.$strip>;
80
+ readonly inputOptional: true;
81
+ readonly output: z.ZodObject<{
82
+ id: z.ZodString;
83
+ kind: z.ZodString;
84
+ name: z.ZodString;
85
+ capacity: z.ZodNumber;
86
+ active: z.ZodBoolean;
87
+ createdAt: z.ZodString;
88
+ }, z.core.$strip>;
89
+ readonly paged: {
90
+ readonly over: {
91
+ readonly entity: "resource";
92
+ readonly sortable: readonly ["name", "kind", "created_at"];
93
+ readonly filterable: readonly ["kind", "active"];
94
+ };
95
+ };
96
+ };
97
+ readonly 'booking/hold': {
98
+ readonly summary: "Place a tentative hold on a slot";
99
+ readonly permission: "booking:hold";
100
+ readonly input: z.ZodObject<{
101
+ resourceId: z.ZodString;
102
+ startsAt: z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>;
103
+ endsAt: z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>;
104
+ expiresAt: z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>;
105
+ quantity: z.ZodOptional<z.ZodNumber>;
106
+ fillTarget: z.ZodOptional<z.ZodNumber>;
107
+ note: z.ZodOptional<z.ZodString>;
108
+ now: z.ZodOptional<z.ZodString>;
109
+ }, z.core.$strip>;
110
+ readonly output: z.ZodObject<{
111
+ id: z.ZodString;
112
+ resourceId: z.ZodString;
113
+ startsAt: z.ZodString;
114
+ endsAt: z.ZodString;
115
+ state: z.ZodEnum<{
116
+ cancelled: "cancelled";
117
+ completed: "completed";
118
+ confirmed: "confirmed";
119
+ expired: "expired";
120
+ held: "held";
121
+ in_service: "in_service";
122
+ no_show: "no_show";
123
+ }>;
124
+ effectiveState: z.ZodEnum<{
125
+ cancelled: "cancelled";
126
+ completed: "completed";
127
+ confirmed: "confirmed";
128
+ expired: "expired";
129
+ held: "held";
130
+ in_service: "in_service";
131
+ no_show: "no_show";
132
+ }>;
133
+ quantity: z.ZodNumber;
134
+ expiresAt: z.ZodNullable<z.ZodString>;
135
+ fillTarget: z.ZodNullable<z.ZodNumber>;
136
+ note: z.ZodNullable<z.ZodString>;
137
+ createdBy: z.ZodString;
138
+ createdAt: z.ZodString;
139
+ }, z.core.$strip>;
140
+ };
141
+ readonly 'booking/confirm': {
142
+ readonly summary: "Confirm a held reservation";
143
+ readonly permission: {
144
+ readonly key: "booking:cancel" | "booking:complete" | "booking:confirm" | "booking:create" | "booking:hold" | "booking:manage-resources" | "booking:move" | "booking:read";
145
+ readonly entity: 'reservation';
146
+ readonly idFrom: 'reservationId';
147
+ };
148
+ readonly input: z.ZodObject<{
149
+ reservationId: z.ZodString;
150
+ now: z.ZodOptional<z.ZodString>;
151
+ }, z.core.$strip>;
152
+ readonly output: z.ZodObject<{
153
+ id: z.ZodString;
154
+ resourceId: z.ZodString;
155
+ startsAt: z.ZodString;
156
+ endsAt: z.ZodString;
157
+ state: z.ZodEnum<{
158
+ cancelled: "cancelled";
159
+ completed: "completed";
160
+ confirmed: "confirmed";
161
+ expired: "expired";
162
+ held: "held";
163
+ in_service: "in_service";
164
+ no_show: "no_show";
165
+ }>;
166
+ effectiveState: z.ZodEnum<{
167
+ cancelled: "cancelled";
168
+ completed: "completed";
169
+ confirmed: "confirmed";
170
+ expired: "expired";
171
+ held: "held";
172
+ in_service: "in_service";
173
+ no_show: "no_show";
174
+ }>;
175
+ quantity: z.ZodNumber;
176
+ expiresAt: z.ZodNullable<z.ZodString>;
177
+ fillTarget: z.ZodNullable<z.ZodNumber>;
178
+ note: z.ZodNullable<z.ZodString>;
179
+ createdBy: z.ZodString;
180
+ createdAt: z.ZodString;
181
+ }, z.core.$strip>;
182
+ };
183
+ readonly 'booking/expire': {
184
+ readonly summary: "Sweep a hold whose deadline has passed";
185
+ readonly permission: "booking:confirm";
186
+ readonly input: z.ZodObject<{
187
+ reservationId: z.ZodString;
188
+ now: z.ZodOptional<z.ZodString>;
189
+ }, z.core.$strip>;
190
+ readonly output: z.ZodObject<{
191
+ id: z.ZodString;
192
+ resourceId: z.ZodString;
193
+ startsAt: z.ZodString;
194
+ endsAt: z.ZodString;
195
+ state: z.ZodEnum<{
196
+ cancelled: "cancelled";
197
+ completed: "completed";
198
+ confirmed: "confirmed";
199
+ expired: "expired";
200
+ held: "held";
201
+ in_service: "in_service";
202
+ no_show: "no_show";
203
+ }>;
204
+ effectiveState: z.ZodEnum<{
205
+ cancelled: "cancelled";
206
+ completed: "completed";
207
+ confirmed: "confirmed";
208
+ expired: "expired";
209
+ held: "held";
210
+ in_service: "in_service";
211
+ no_show: "no_show";
212
+ }>;
213
+ quantity: z.ZodNumber;
214
+ expiresAt: z.ZodNullable<z.ZodString>;
215
+ fillTarget: z.ZodNullable<z.ZodNumber>;
216
+ note: z.ZodNullable<z.ZodString>;
217
+ createdBy: z.ZodString;
218
+ createdAt: z.ZodString;
219
+ }, z.core.$strip>;
220
+ };
221
+ readonly 'booking/join': {
222
+ readonly summary: "Join a reservation that is on offer";
223
+ readonly permission: {
224
+ readonly key: "booking:cancel" | "booking:complete" | "booking:confirm" | "booking:create" | "booking:hold" | "booking:manage-resources" | "booking:move" | "booking:read";
225
+ readonly entity: 'reservation';
226
+ readonly idFrom: 'reservationId';
227
+ };
228
+ readonly input: z.ZodObject<{
229
+ reservationId: z.ZodString;
230
+ partyRef: z.core.$ZodBranded<z.ZodString, "DataSubjectId", "out">;
231
+ share: z.ZodOptional<z.ZodObject<{
232
+ amount: z.core.$ZodBranded<z.ZodString, "MoneyAmount", "out">;
233
+ currency: z.core.$ZodBranded<z.ZodString, "CurrencyCode", "out">;
234
+ }, z.core.$strip>>;
235
+ now: z.ZodOptional<z.ZodString>;
236
+ }, z.core.$strip>;
237
+ readonly output: z.ZodObject<{
238
+ participant: z.ZodObject<{
239
+ id: z.ZodString;
240
+ partyRef: z.ZodString;
241
+ share: z.ZodNullable<z.ZodObject<{
242
+ amount: z.core.$ZodBranded<z.ZodString, "MoneyAmount", "out">;
243
+ currency: z.core.$ZodBranded<z.ZodString, "CurrencyCode", "out">;
244
+ }, z.core.$strip>>;
245
+ joinedAt: z.ZodString;
246
+ leftAt: z.ZodNullable<z.ZodString>;
247
+ }, z.core.$strip>;
248
+ reservation: z.ZodObject<{
249
+ id: z.ZodString;
250
+ resourceId: z.ZodString;
251
+ startsAt: z.ZodString;
252
+ endsAt: z.ZodString;
253
+ state: z.ZodEnum<{
254
+ cancelled: "cancelled";
255
+ completed: "completed";
256
+ confirmed: "confirmed";
257
+ expired: "expired";
258
+ held: "held";
259
+ in_service: "in_service";
260
+ no_show: "no_show";
261
+ }>;
262
+ effectiveState: z.ZodEnum<{
263
+ cancelled: "cancelled";
264
+ completed: "completed";
265
+ confirmed: "confirmed";
266
+ expired: "expired";
267
+ held: "held";
268
+ in_service: "in_service";
269
+ no_show: "no_show";
270
+ }>;
271
+ quantity: z.ZodNumber;
272
+ expiresAt: z.ZodNullable<z.ZodString>;
273
+ fillTarget: z.ZodNullable<z.ZodNumber>;
274
+ note: z.ZodNullable<z.ZodString>;
275
+ createdBy: z.ZodString;
276
+ createdAt: z.ZodString;
277
+ }, z.core.$strip>;
278
+ }, z.core.$strip>;
279
+ };
280
+ readonly 'booking/leave': {
281
+ readonly summary: "Leave a reservation previously joined";
282
+ readonly permission: {
283
+ readonly key: "booking:cancel" | "booking:complete" | "booking:confirm" | "booking:create" | "booking:hold" | "booking:manage-resources" | "booking:move" | "booking:read";
284
+ readonly entity: 'reservation';
285
+ readonly idFrom: 'reservationId';
286
+ };
287
+ readonly input: z.ZodObject<{
288
+ reservationId: z.ZodString;
289
+ participantId: z.ZodString;
290
+ now: z.ZodOptional<z.ZodString>;
291
+ }, z.core.$strip>;
292
+ readonly output: z.ZodObject<{
293
+ id: z.ZodString;
294
+ resourceId: z.ZodString;
295
+ startsAt: z.ZodString;
296
+ endsAt: z.ZodString;
297
+ state: z.ZodEnum<{
298
+ cancelled: "cancelled";
299
+ completed: "completed";
300
+ confirmed: "confirmed";
301
+ expired: "expired";
302
+ held: "held";
303
+ in_service: "in_service";
304
+ no_show: "no_show";
305
+ }>;
306
+ effectiveState: z.ZodEnum<{
307
+ cancelled: "cancelled";
308
+ completed: "completed";
309
+ confirmed: "confirmed";
310
+ expired: "expired";
311
+ held: "held";
312
+ in_service: "in_service";
313
+ no_show: "no_show";
314
+ }>;
315
+ quantity: z.ZodNumber;
316
+ expiresAt: z.ZodNullable<z.ZodString>;
317
+ fillTarget: z.ZodNullable<z.ZodNumber>;
318
+ note: z.ZodNullable<z.ZodString>;
319
+ createdBy: z.ZodString;
320
+ createdAt: z.ZodString;
321
+ }, z.core.$strip>;
322
+ };
323
+ readonly 'booking/cancel': {
324
+ readonly summary: "Cancel a reservation";
325
+ readonly permission: {
326
+ readonly key: "booking:cancel" | "booking:complete" | "booking:confirm" | "booking:create" | "booking:hold" | "booking:manage-resources" | "booking:move" | "booking:read";
327
+ readonly entity: 'reservation';
328
+ readonly idFrom: 'reservationId';
329
+ };
330
+ readonly input: z.ZodObject<{
331
+ reservationId: z.ZodString;
332
+ reason: z.ZodOptional<z.ZodString>;
333
+ }, z.core.$strip>;
334
+ readonly output: z.ZodObject<{
335
+ id: z.ZodString;
336
+ resourceId: z.ZodString;
337
+ startsAt: z.ZodString;
338
+ endsAt: z.ZodString;
339
+ state: z.ZodEnum<{
340
+ cancelled: "cancelled";
341
+ completed: "completed";
342
+ confirmed: "confirmed";
343
+ expired: "expired";
344
+ held: "held";
345
+ in_service: "in_service";
346
+ no_show: "no_show";
347
+ }>;
348
+ effectiveState: z.ZodEnum<{
349
+ cancelled: "cancelled";
350
+ completed: "completed";
351
+ confirmed: "confirmed";
352
+ expired: "expired";
353
+ held: "held";
354
+ in_service: "in_service";
355
+ no_show: "no_show";
356
+ }>;
357
+ quantity: z.ZodNumber;
358
+ expiresAt: z.ZodNullable<z.ZodString>;
359
+ fillTarget: z.ZodNullable<z.ZodNumber>;
360
+ note: z.ZodNullable<z.ZodString>;
361
+ createdBy: z.ZodString;
362
+ createdAt: z.ZodString;
363
+ }, z.core.$strip>;
364
+ };
365
+ readonly 'booking/move': {
366
+ readonly summary: "Reschedule a reservation to another slot or resource";
367
+ readonly permission: {
368
+ readonly key: "booking:cancel" | "booking:complete" | "booking:confirm" | "booking:create" | "booking:hold" | "booking:manage-resources" | "booking:move" | "booking:read";
369
+ readonly entity: 'reservation';
370
+ readonly idFrom: 'reservationId';
371
+ };
372
+ readonly input: z.ZodObject<{
373
+ reservationId: z.ZodString;
374
+ resourceId: z.ZodOptional<z.ZodString>;
375
+ startsAt: z.ZodOptional<z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>>;
376
+ endsAt: z.ZodOptional<z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>>;
377
+ now: z.ZodOptional<z.ZodString>;
378
+ }, z.core.$strip>;
379
+ readonly output: z.ZodObject<{
380
+ id: z.ZodString;
381
+ resourceId: z.ZodString;
382
+ startsAt: z.ZodString;
383
+ endsAt: z.ZodString;
384
+ state: z.ZodEnum<{
385
+ cancelled: "cancelled";
386
+ completed: "completed";
387
+ confirmed: "confirmed";
388
+ expired: "expired";
389
+ held: "held";
390
+ in_service: "in_service";
391
+ no_show: "no_show";
392
+ }>;
393
+ effectiveState: z.ZodEnum<{
394
+ cancelled: "cancelled";
395
+ completed: "completed";
396
+ confirmed: "confirmed";
397
+ expired: "expired";
398
+ held: "held";
399
+ in_service: "in_service";
400
+ no_show: "no_show";
401
+ }>;
402
+ quantity: z.ZodNumber;
403
+ expiresAt: z.ZodNullable<z.ZodString>;
404
+ fillTarget: z.ZodNullable<z.ZodNumber>;
405
+ note: z.ZodNullable<z.ZodString>;
406
+ createdBy: z.ZodString;
407
+ createdAt: z.ZodString;
408
+ }, z.core.$strip>;
409
+ };
410
+ readonly 'booking/open': {
411
+ readonly summary: "Put a reservation on offer, or take it off";
412
+ readonly permission: {
413
+ readonly key: "booking:cancel" | "booking:complete" | "booking:confirm" | "booking:create" | "booking:hold" | "booking:manage-resources" | "booking:move" | "booking:read";
414
+ readonly entity: 'reservation';
415
+ readonly idFrom: 'reservationId';
416
+ };
417
+ readonly input: z.ZodObject<{
418
+ reservationId: z.ZodString;
419
+ fillTarget: z.ZodNullable<z.ZodNumber>;
420
+ now: z.ZodOptional<z.ZodString>;
421
+ }, z.core.$strip>;
422
+ readonly output: z.ZodObject<{
423
+ id: z.ZodString;
424
+ resourceId: z.ZodString;
425
+ startsAt: z.ZodString;
426
+ endsAt: z.ZodString;
427
+ state: z.ZodEnum<{
428
+ cancelled: "cancelled";
429
+ completed: "completed";
430
+ confirmed: "confirmed";
431
+ expired: "expired";
432
+ held: "held";
433
+ in_service: "in_service";
434
+ no_show: "no_show";
435
+ }>;
436
+ effectiveState: z.ZodEnum<{
437
+ cancelled: "cancelled";
438
+ completed: "completed";
439
+ confirmed: "confirmed";
440
+ expired: "expired";
441
+ held: "held";
442
+ in_service: "in_service";
443
+ no_show: "no_show";
444
+ }>;
445
+ quantity: z.ZodNumber;
446
+ expiresAt: z.ZodNullable<z.ZodString>;
447
+ fillTarget: z.ZodNullable<z.ZodNumber>;
448
+ note: z.ZodNullable<z.ZodString>;
449
+ createdBy: z.ZodString;
450
+ createdAt: z.ZodString;
451
+ }, z.core.$strip>;
452
+ };
453
+ readonly 'booking/start': {
454
+ readonly summary: "Start service on a reservation";
455
+ readonly permission: "booking:complete";
456
+ readonly input: z.ZodObject<{
457
+ reservationId: z.ZodString;
458
+ }, z.core.$strip>;
459
+ readonly output: z.ZodObject<{
460
+ id: z.ZodString;
461
+ resourceId: z.ZodString;
462
+ startsAt: z.ZodString;
463
+ endsAt: z.ZodString;
464
+ state: z.ZodEnum<{
465
+ cancelled: "cancelled";
466
+ completed: "completed";
467
+ confirmed: "confirmed";
468
+ expired: "expired";
469
+ held: "held";
470
+ in_service: "in_service";
471
+ no_show: "no_show";
472
+ }>;
473
+ effectiveState: z.ZodEnum<{
474
+ cancelled: "cancelled";
475
+ completed: "completed";
476
+ confirmed: "confirmed";
477
+ expired: "expired";
478
+ held: "held";
479
+ in_service: "in_service";
480
+ no_show: "no_show";
481
+ }>;
482
+ quantity: z.ZodNumber;
483
+ expiresAt: z.ZodNullable<z.ZodString>;
484
+ fillTarget: z.ZodNullable<z.ZodNumber>;
485
+ note: z.ZodNullable<z.ZodString>;
486
+ createdBy: z.ZodString;
487
+ createdAt: z.ZodString;
488
+ }, z.core.$strip>;
489
+ };
490
+ readonly 'booking/complete': {
491
+ readonly summary: "Complete a reservation";
492
+ readonly permission: "booking:complete";
493
+ readonly input: z.ZodObject<{
494
+ reservationId: z.ZodString;
495
+ }, z.core.$strip>;
496
+ readonly output: z.ZodObject<{
497
+ id: z.ZodString;
498
+ resourceId: z.ZodString;
499
+ startsAt: z.ZodString;
500
+ endsAt: z.ZodString;
501
+ state: z.ZodEnum<{
502
+ cancelled: "cancelled";
503
+ completed: "completed";
504
+ confirmed: "confirmed";
505
+ expired: "expired";
506
+ held: "held";
507
+ in_service: "in_service";
508
+ no_show: "no_show";
509
+ }>;
510
+ effectiveState: z.ZodEnum<{
511
+ cancelled: "cancelled";
512
+ completed: "completed";
513
+ confirmed: "confirmed";
514
+ expired: "expired";
515
+ held: "held";
516
+ in_service: "in_service";
517
+ no_show: "no_show";
518
+ }>;
519
+ quantity: z.ZodNumber;
520
+ expiresAt: z.ZodNullable<z.ZodString>;
521
+ fillTarget: z.ZodNullable<z.ZodNumber>;
522
+ note: z.ZodNullable<z.ZodString>;
523
+ createdBy: z.ZodString;
524
+ createdAt: z.ZodString;
525
+ }, z.core.$strip>;
526
+ };
527
+ readonly 'booking/no-show': {
528
+ readonly summary: "Mark a reservation as a no-show";
529
+ readonly permission: "booking:complete";
530
+ readonly input: z.ZodObject<{
531
+ reservationId: z.ZodString;
532
+ }, z.core.$strip>;
533
+ readonly output: z.ZodObject<{
534
+ id: z.ZodString;
535
+ resourceId: z.ZodString;
536
+ startsAt: z.ZodString;
537
+ endsAt: z.ZodString;
538
+ state: z.ZodEnum<{
539
+ cancelled: "cancelled";
540
+ completed: "completed";
541
+ confirmed: "confirmed";
542
+ expired: "expired";
543
+ held: "held";
544
+ in_service: "in_service";
545
+ no_show: "no_show";
546
+ }>;
547
+ effectiveState: z.ZodEnum<{
548
+ cancelled: "cancelled";
549
+ completed: "completed";
550
+ confirmed: "confirmed";
551
+ expired: "expired";
552
+ held: "held";
553
+ in_service: "in_service";
554
+ no_show: "no_show";
555
+ }>;
556
+ quantity: z.ZodNumber;
557
+ expiresAt: z.ZodNullable<z.ZodString>;
558
+ fillTarget: z.ZodNullable<z.ZodNumber>;
559
+ note: z.ZodNullable<z.ZodString>;
560
+ createdBy: z.ZodString;
561
+ createdAt: z.ZodString;
562
+ }, z.core.$strip>;
563
+ };
564
+ readonly 'booking/get': {
565
+ readonly summary: "One reservation with its participants";
566
+ readonly permission: {
567
+ readonly key: "booking:cancel" | "booking:complete" | "booking:confirm" | "booking:create" | "booking:hold" | "booking:manage-resources" | "booking:move" | "booking:read";
568
+ readonly entity: 'reservation';
569
+ readonly idFrom: 'reservationId';
570
+ };
571
+ readonly input: z.ZodObject<{
572
+ reservationId: z.ZodString;
573
+ now: z.ZodOptional<z.ZodString>;
574
+ }, z.core.$strip>;
575
+ readonly output: z.ZodObject<{
576
+ reservation: z.ZodObject<{
577
+ id: z.ZodString;
578
+ resourceId: z.ZodString;
579
+ startsAt: z.ZodString;
580
+ endsAt: z.ZodString;
581
+ state: z.ZodEnum<{
582
+ cancelled: "cancelled";
583
+ completed: "completed";
584
+ confirmed: "confirmed";
585
+ expired: "expired";
586
+ held: "held";
587
+ in_service: "in_service";
588
+ no_show: "no_show";
589
+ }>;
590
+ effectiveState: z.ZodEnum<{
591
+ cancelled: "cancelled";
592
+ completed: "completed";
593
+ confirmed: "confirmed";
594
+ expired: "expired";
595
+ held: "held";
596
+ in_service: "in_service";
597
+ no_show: "no_show";
598
+ }>;
599
+ quantity: z.ZodNumber;
600
+ expiresAt: z.ZodNullable<z.ZodString>;
601
+ fillTarget: z.ZodNullable<z.ZodNumber>;
602
+ note: z.ZodNullable<z.ZodString>;
603
+ createdBy: z.ZodString;
604
+ createdAt: z.ZodString;
605
+ }, z.core.$strip>;
606
+ participants: z.ZodArray<z.ZodObject<{
607
+ id: z.ZodString;
608
+ partyRef: z.ZodString;
609
+ share: z.ZodNullable<z.ZodObject<{
610
+ amount: z.core.$ZodBranded<z.ZodString, "MoneyAmount", "out">;
611
+ currency: z.core.$ZodBranded<z.ZodString, "CurrencyCode", "out">;
612
+ }, z.core.$strip>>;
613
+ joinedAt: z.ZodString;
614
+ leftAt: z.ZodNullable<z.ZodString>;
615
+ }, z.core.$strip>>;
616
+ }, z.core.$strip>;
617
+ };
618
+ readonly 'booking/list': {
619
+ readonly summary: "Reservations overlapping a window";
620
+ readonly permission: "booking:read";
621
+ readonly input: z.ZodObject<{
622
+ resourceId: z.ZodOptional<z.ZodString>;
623
+ from: z.ZodOptional<z.ZodString>;
624
+ to: z.ZodOptional<z.ZodString>;
625
+ now: z.ZodOptional<z.ZodString>;
626
+ }, z.core.$strip>;
627
+ readonly inputOptional: true;
628
+ readonly output: z.ZodObject<{
629
+ id: z.ZodString;
630
+ resourceId: z.ZodString;
631
+ startsAt: z.ZodString;
632
+ endsAt: z.ZodString;
633
+ state: z.ZodEnum<{
634
+ cancelled: "cancelled";
635
+ completed: "completed";
636
+ confirmed: "confirmed";
637
+ expired: "expired";
638
+ held: "held";
639
+ in_service: "in_service";
640
+ no_show: "no_show";
641
+ }>;
642
+ effectiveState: z.ZodEnum<{
643
+ cancelled: "cancelled";
644
+ completed: "completed";
645
+ confirmed: "confirmed";
646
+ expired: "expired";
647
+ held: "held";
648
+ in_service: "in_service";
649
+ no_show: "no_show";
650
+ }>;
651
+ quantity: z.ZodNumber;
652
+ expiresAt: z.ZodNullable<z.ZodString>;
653
+ fillTarget: z.ZodNullable<z.ZodNumber>;
654
+ note: z.ZodNullable<z.ZodString>;
655
+ createdBy: z.ZodString;
656
+ createdAt: z.ZodString;
657
+ }, z.core.$strip>;
658
+ /**
659
+ * Handler-composed, and the cursor is `id` rather than `startsAt`.
660
+ *
661
+ * The window is an OVERLAP test — `starts_at < to AND ends_at > from` — and
662
+ * the kernel's filter vocabulary is equality only, deliberately (a range
663
+ * vocabulary is where a filter becomes a query language). So this read owns
664
+ * its own `WHERE`, and `paged.sortKey` names the field the cursor walks.
665
+ *
666
+ * It has to be a UNIQUE field. This list shipped `ORDER BY starts_at, id`,
667
+ * and a keyset cursor on `starts_at` skips and repeats rows wherever two
668
+ * reservations share a start — which on a court schedule is every hour. Ids
669
+ * are ULIDs, so `id` is unique and still roughly chronological by creation.
670
+ * A caller rendering a calendar sorts the page by `startsAt` itself.
671
+ */
672
+ readonly paged: {
673
+ readonly sortKey: "id";
674
+ };
675
+ };
676
+ readonly 'booking/availability': {
677
+ readonly summary: "Free intervals on a resource within a window";
678
+ readonly permission: "booking:read";
679
+ readonly input: z.ZodObject<{
680
+ resourceId: z.ZodString;
681
+ from: z.ZodString;
682
+ to: z.ZodString;
683
+ now: z.ZodOptional<z.ZodString>;
684
+ }, z.core.$strip>;
685
+ readonly output: z.ZodObject<{
686
+ startsAt: z.ZodString;
687
+ endsAt: z.ZodString;
688
+ available: z.ZodNumber;
689
+ }, z.core.$strip>;
690
+ /**
691
+ * A computed fold, not a table walk — so handler-composed, like the list
692
+ * above. The segments this returns are DISJOINT and returned in order, so
693
+ * `startsAt` is unique among them and is a sound cursor where it would not
694
+ * be over reservation rows.
695
+ */
696
+ readonly paged: {
697
+ readonly sortKey: "startsAt";
698
+ };
699
+ };
700
+ };
701
+ //# sourceMappingURL=operations.d.ts.map