@substrat-run/engine-booking 0.5.2 → 0.6.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/dist/index.d.ts +59 -182
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +107 -154
- package/dist/index.js.map +1 -1
- package/dist/lifecycle.d.ts +89 -0
- package/dist/lifecycle.d.ts.map +1 -0
- package/dist/lifecycle.js +84 -0
- package/dist/lifecycle.js.map +1 -0
- package/dist/model.d.ts +4 -3
- package/dist/model.d.ts.map +1 -1
- package/dist/model.js +5 -4
- package/dist/model.js.map +1 -1
- package/dist/operations.d.ts +701 -0
- package/dist/operations.d.ts.map +1 -0
- package/dist/operations.js +193 -0
- package/dist/operations.js.map +1 -0
- package/dist/schemas.d.ts +178 -0
- package/dist/schemas.d.ts.map +1 -0
- package/dist/schemas.js +163 -0
- package/dist/schemas.js.map +1 -0
- package/package.json +9 -5
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"operations.d.ts","sourceRoot":"","sources":["../src/operations.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AACH,OAAO,EAAoB,CAAC,EAAE,MAAM,yBAAyB,CAAC;AAsB9D,mEAAmE;AACnE,eAAO,MAAM,mBAAmB,YAC9B,gBAAgB,EAChB,cAAc,EACd,cAAc,EACd,iBAAiB,EACjB,gBAAgB,EAChB,cAAc,EACd,kBAAkB,EAClB,0BAA0B,CAClB,CAAC;AAMX,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;6BAFZ,aAAa;6BAAU,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;QA+HpD;;;;;;;;;;;;;WAaG;;;;;;;;;;;;;;;;;;;QASH;;;;;WAKG;;;;;CAGL,CAAC"}
|
|
@@ -0,0 +1,193 @@
|
|
|
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 { defineOperations, z } from '@substrat-run/contracts';
|
|
38
|
+
import { bookingEntities } from './entities.js';
|
|
39
|
+
import { availabilityInput, cancelReservationInput, createResourceInput, freeInterval, holdReservationInput, joinReservationInput, leaveReservationInput, listReservationsInput, listResourcesInput, moveReservationInput, openReservationInput, participant, reservation, reservationAtInput, reservationIdIn, resource, setResourceActiveInput, } from './schemas.js';
|
|
40
|
+
/** The keys these operations check. Mirrors `PERM` in index.ts. */
|
|
41
|
+
export const BOOKING_PERMISSIONS = [
|
|
42
|
+
'booking:create',
|
|
43
|
+
'booking:read',
|
|
44
|
+
'booking:hold',
|
|
45
|
+
'booking:confirm',
|
|
46
|
+
'booking:cancel',
|
|
47
|
+
'booking:move',
|
|
48
|
+
'booking:complete',
|
|
49
|
+
'booking:manage-resources',
|
|
50
|
+
];
|
|
51
|
+
/** The narrowed check five mutations and one read share. */
|
|
52
|
+
const onReservation = (key) => ({ key, entity: 'reservation', idFrom: 'reservationId' });
|
|
53
|
+
export const bookingOperations = defineOperations(bookingEntities, BOOKING_PERMISSIONS)({
|
|
54
|
+
'booking/create-resource': {
|
|
55
|
+
summary: 'Register a bookable resource',
|
|
56
|
+
permission: 'booking:manage-resources',
|
|
57
|
+
input: createResourceInput,
|
|
58
|
+
output: resource,
|
|
59
|
+
},
|
|
60
|
+
'booking/set-resource-active': {
|
|
61
|
+
summary: 'Take a resource in or out of service',
|
|
62
|
+
permission: 'booking:manage-resources',
|
|
63
|
+
input: setResourceActiveInput,
|
|
64
|
+
output: resource,
|
|
65
|
+
},
|
|
66
|
+
'booking/list-resources': {
|
|
67
|
+
summary: 'Bookable resources, by name',
|
|
68
|
+
permission: 'booking:read',
|
|
69
|
+
input: listResourcesInput,
|
|
70
|
+
inputOptional: true,
|
|
71
|
+
output: resource,
|
|
72
|
+
// Kernel-composed: a resource list is a plain table walk, so the `WHERE`,
|
|
73
|
+
// the `ORDER BY`, the keyset tie-break and the indexes are all the kernel's.
|
|
74
|
+
// `name` first because that is the order this list shipped with.
|
|
75
|
+
paged: {
|
|
76
|
+
over: {
|
|
77
|
+
entity: 'resource',
|
|
78
|
+
sortable: ['name', 'kind', 'created_at'],
|
|
79
|
+
filterable: ['kind', 'active'],
|
|
80
|
+
},
|
|
81
|
+
},
|
|
82
|
+
},
|
|
83
|
+
'booking/hold': {
|
|
84
|
+
summary: 'Place a tentative hold on a slot',
|
|
85
|
+
permission: 'booking:hold',
|
|
86
|
+
input: holdReservationInput,
|
|
87
|
+
output: reservation,
|
|
88
|
+
},
|
|
89
|
+
'booking/confirm': {
|
|
90
|
+
summary: 'Confirm a held reservation',
|
|
91
|
+
permission: onReservation('booking:confirm'),
|
|
92
|
+
input: reservationAtInput,
|
|
93
|
+
output: reservation,
|
|
94
|
+
},
|
|
95
|
+
'booking/expire': {
|
|
96
|
+
summary: 'Sweep a hold whose deadline has passed',
|
|
97
|
+
// Node, deliberately — see the header. A sweep acts on whatever has lapsed.
|
|
98
|
+
permission: 'booking:confirm',
|
|
99
|
+
input: reservationAtInput,
|
|
100
|
+
output: reservation,
|
|
101
|
+
},
|
|
102
|
+
'booking/join': {
|
|
103
|
+
summary: 'Join a reservation that is on offer',
|
|
104
|
+
permission: onReservation('booking:create'),
|
|
105
|
+
input: joinReservationInput,
|
|
106
|
+
output: z.object({ participant, reservation }),
|
|
107
|
+
},
|
|
108
|
+
'booking/leave': {
|
|
109
|
+
summary: 'Leave a reservation previously joined',
|
|
110
|
+
permission: onReservation('booking:cancel'),
|
|
111
|
+
input: leaveReservationInput,
|
|
112
|
+
output: reservation,
|
|
113
|
+
},
|
|
114
|
+
'booking/cancel': {
|
|
115
|
+
summary: 'Cancel a reservation',
|
|
116
|
+
permission: onReservation('booking:cancel'),
|
|
117
|
+
input: cancelReservationInput,
|
|
118
|
+
output: reservation,
|
|
119
|
+
},
|
|
120
|
+
'booking/move': {
|
|
121
|
+
summary: 'Reschedule a reservation to another slot or resource',
|
|
122
|
+
permission: onReservation('booking:move'),
|
|
123
|
+
input: moveReservationInput,
|
|
124
|
+
output: reservation,
|
|
125
|
+
},
|
|
126
|
+
'booking/open': {
|
|
127
|
+
summary: 'Put a reservation on offer, or take it off',
|
|
128
|
+
// Whoever may confirm a reservation may decide whether it is on offer.
|
|
129
|
+
permission: onReservation('booking:confirm'),
|
|
130
|
+
input: openReservationInput,
|
|
131
|
+
output: reservation,
|
|
132
|
+
},
|
|
133
|
+
'booking/start': {
|
|
134
|
+
summary: 'Start service on a reservation',
|
|
135
|
+
permission: 'booking:complete',
|
|
136
|
+
input: reservationIdIn,
|
|
137
|
+
output: reservation,
|
|
138
|
+
},
|
|
139
|
+
'booking/complete': {
|
|
140
|
+
summary: 'Complete a reservation',
|
|
141
|
+
permission: 'booking:complete',
|
|
142
|
+
input: reservationIdIn,
|
|
143
|
+
output: reservation,
|
|
144
|
+
},
|
|
145
|
+
'booking/no-show': {
|
|
146
|
+
summary: 'Mark a reservation as a no-show',
|
|
147
|
+
permission: 'booking:complete',
|
|
148
|
+
input: reservationIdIn,
|
|
149
|
+
output: reservation,
|
|
150
|
+
},
|
|
151
|
+
'booking/get': {
|
|
152
|
+
summary: 'One reservation with its participants',
|
|
153
|
+
permission: onReservation('booking:read'),
|
|
154
|
+
input: reservationAtInput,
|
|
155
|
+
output: z.object({ reservation, participants: z.array(participant) }),
|
|
156
|
+
},
|
|
157
|
+
'booking/list': {
|
|
158
|
+
summary: 'Reservations overlapping a window',
|
|
159
|
+
permission: 'booking:read',
|
|
160
|
+
input: listReservationsInput,
|
|
161
|
+
inputOptional: true,
|
|
162
|
+
output: reservation,
|
|
163
|
+
/**
|
|
164
|
+
* Handler-composed, and the cursor is `id` rather than `startsAt`.
|
|
165
|
+
*
|
|
166
|
+
* The window is an OVERLAP test — `starts_at < to AND ends_at > from` — and
|
|
167
|
+
* the kernel's filter vocabulary is equality only, deliberately (a range
|
|
168
|
+
* vocabulary is where a filter becomes a query language). So this read owns
|
|
169
|
+
* its own `WHERE`, and `paged.sortKey` names the field the cursor walks.
|
|
170
|
+
*
|
|
171
|
+
* It has to be a UNIQUE field. This list shipped `ORDER BY starts_at, id`,
|
|
172
|
+
* and a keyset cursor on `starts_at` skips and repeats rows wherever two
|
|
173
|
+
* reservations share a start — which on a court schedule is every hour. Ids
|
|
174
|
+
* are ULIDs, so `id` is unique and still roughly chronological by creation.
|
|
175
|
+
* A caller rendering a calendar sorts the page by `startsAt` itself.
|
|
176
|
+
*/
|
|
177
|
+
paged: { sortKey: 'id' },
|
|
178
|
+
},
|
|
179
|
+
'booking/availability': {
|
|
180
|
+
summary: 'Free intervals on a resource within a window',
|
|
181
|
+
permission: 'booking:read',
|
|
182
|
+
input: availabilityInput,
|
|
183
|
+
output: freeInterval,
|
|
184
|
+
/**
|
|
185
|
+
* A computed fold, not a table walk — so handler-composed, like the list
|
|
186
|
+
* above. The segments this returns are DISJOINT and returned in order, so
|
|
187
|
+
* `startsAt` is unique among them and is a sound cursor where it would not
|
|
188
|
+
* be over reservation rows.
|
|
189
|
+
*/
|
|
190
|
+
paged: { sortKey: 'startsAt' },
|
|
191
|
+
},
|
|
192
|
+
});
|
|
193
|
+
//# sourceMappingURL=operations.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"operations.js","sourceRoot":"","sources":["../src/operations.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
import { z } from '@substrat-run/contracts';
|
|
2
|
+
/**
|
|
3
|
+
* engine-booking's schemas — what it ACCEPTS and what it ANSWERS (#707/#865).
|
|
4
|
+
*
|
|
5
|
+
* The published projections were seven hand-written `export interface`s in
|
|
6
|
+
* `index.ts`, and the operation inputs were a mix of exported schemas and inline
|
|
7
|
+
* TypeScript types on each handler. Both moved here because `defineOperations`
|
|
8
|
+
* declares an operation's `input` and `output` as schemas, and a TypeScript
|
|
9
|
+
* interface cannot be one — the alternative was a zod schema beside each
|
|
10
|
+
* interface saying the same thing twice, which is the two-descriptions defect
|
|
11
|
+
* this engine already deleted once (see `reservationState` below).
|
|
12
|
+
*
|
|
13
|
+
* They live in their own file rather than in `operations.ts` for the reason
|
|
14
|
+
* `entities.ts` does: `index.ts` needs them too, and a declaration file that
|
|
15
|
+
* imports the implementation is the cycle the old `OPERATIONS` note described.
|
|
16
|
+
* Nothing here imports `index.ts`, so the direction stays acyclic.
|
|
17
|
+
*
|
|
18
|
+
* Row versus published, the distinction `entities.ts` draws: a `ResourceRow` has
|
|
19
|
+
* `active` as 0/1 and `created_at` in snake_case because SQLite has no boolean
|
|
20
|
+
* and the column is what it is. `Resource` publishes `active: boolean` and
|
|
21
|
+
* `createdAt`. The registry describes what is STORED; this describes what is
|
|
22
|
+
* ANSWERED, and `toResource`/`toReservation` in `index.ts` are the one crossing.
|
|
23
|
+
*/
|
|
24
|
+
/** Parse to a canonical ISO instant, or refuse. */
|
|
25
|
+
export declare function toInstant(value: string): string;
|
|
26
|
+
export declare const instantIn: z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>;
|
|
27
|
+
/**
|
|
28
|
+
* The reservation's states — **taken from the entity registry, not restated**.
|
|
29
|
+
*
|
|
30
|
+
* Moved here from `index.ts` unchanged. Reading the column's own schema keeps
|
|
31
|
+
* storage and domain unable to disagree (#844).
|
|
32
|
+
*/
|
|
33
|
+
export declare const reservationState: z.ZodEnum<{
|
|
34
|
+
cancelled: "cancelled";
|
|
35
|
+
completed: "completed";
|
|
36
|
+
confirmed: "confirmed";
|
|
37
|
+
expired: "expired";
|
|
38
|
+
held: "held";
|
|
39
|
+
in_service: "in_service";
|
|
40
|
+
no_show: "no_show";
|
|
41
|
+
}>;
|
|
42
|
+
export type ReservationState = z.infer<typeof reservationState>;
|
|
43
|
+
export declare const resource: z.ZodObject<{
|
|
44
|
+
id: z.ZodString;
|
|
45
|
+
kind: z.ZodString;
|
|
46
|
+
name: z.ZodString;
|
|
47
|
+
capacity: z.ZodNumber;
|
|
48
|
+
active: z.ZodBoolean;
|
|
49
|
+
createdAt: z.ZodString;
|
|
50
|
+
}, z.core.$strip>;
|
|
51
|
+
export type Resource = z.infer<typeof resource>;
|
|
52
|
+
export declare const participant: z.ZodObject<{
|
|
53
|
+
id: z.ZodString;
|
|
54
|
+
partyRef: z.ZodString;
|
|
55
|
+
share: z.ZodNullable<z.ZodObject<{
|
|
56
|
+
amount: z.core.$ZodBranded<z.ZodString, "MoneyAmount", "out">;
|
|
57
|
+
currency: z.core.$ZodBranded<z.ZodString, "CurrencyCode", "out">;
|
|
58
|
+
}, z.core.$strip>>;
|
|
59
|
+
joinedAt: z.ZodString;
|
|
60
|
+
leftAt: z.ZodNullable<z.ZodString>;
|
|
61
|
+
}, z.core.$strip>;
|
|
62
|
+
export type Participant = z.infer<typeof participant>;
|
|
63
|
+
export declare const reservation: z.ZodObject<{
|
|
64
|
+
id: z.ZodString;
|
|
65
|
+
resourceId: z.ZodString;
|
|
66
|
+
startsAt: z.ZodString;
|
|
67
|
+
endsAt: z.ZodString;
|
|
68
|
+
state: z.ZodEnum<{
|
|
69
|
+
cancelled: "cancelled";
|
|
70
|
+
completed: "completed";
|
|
71
|
+
confirmed: "confirmed";
|
|
72
|
+
expired: "expired";
|
|
73
|
+
held: "held";
|
|
74
|
+
in_service: "in_service";
|
|
75
|
+
no_show: "no_show";
|
|
76
|
+
}>;
|
|
77
|
+
effectiveState: z.ZodEnum<{
|
|
78
|
+
cancelled: "cancelled";
|
|
79
|
+
completed: "completed";
|
|
80
|
+
confirmed: "confirmed";
|
|
81
|
+
expired: "expired";
|
|
82
|
+
held: "held";
|
|
83
|
+
in_service: "in_service";
|
|
84
|
+
no_show: "no_show";
|
|
85
|
+
}>;
|
|
86
|
+
quantity: z.ZodNumber;
|
|
87
|
+
expiresAt: z.ZodNullable<z.ZodString>;
|
|
88
|
+
fillTarget: z.ZodNullable<z.ZodNumber>;
|
|
89
|
+
note: z.ZodNullable<z.ZodString>;
|
|
90
|
+
createdBy: z.ZodString;
|
|
91
|
+
createdAt: z.ZodString;
|
|
92
|
+
}, z.core.$strip>;
|
|
93
|
+
export type Reservation = z.infer<typeof reservation>;
|
|
94
|
+
export declare const freeInterval: z.ZodObject<{
|
|
95
|
+
startsAt: z.ZodString;
|
|
96
|
+
endsAt: z.ZodString;
|
|
97
|
+
available: z.ZodNumber;
|
|
98
|
+
}, z.core.$strip>;
|
|
99
|
+
export type FreeInterval = z.infer<typeof freeInterval>;
|
|
100
|
+
/** Every reservation-scoped operation opens with this, and most add nothing. */
|
|
101
|
+
export declare const reservationIdIn: z.ZodObject<{
|
|
102
|
+
reservationId: z.ZodString;
|
|
103
|
+
}, z.core.$strip>;
|
|
104
|
+
export declare const createResourceInput: z.ZodObject<{
|
|
105
|
+
kind: z.ZodString;
|
|
106
|
+
name: z.ZodString;
|
|
107
|
+
capacity: z.ZodOptional<z.ZodNumber>;
|
|
108
|
+
}, z.core.$strip>;
|
|
109
|
+
export type CreateResourceInput = z.infer<typeof createResourceInput>;
|
|
110
|
+
export declare const setResourceActiveInput: z.ZodObject<{
|
|
111
|
+
resourceId: z.ZodString;
|
|
112
|
+
active: z.ZodBoolean;
|
|
113
|
+
}, z.core.$strip>;
|
|
114
|
+
export type SetResourceActiveInput = z.infer<typeof setResourceActiveInput>;
|
|
115
|
+
export declare const listResourcesInput: z.ZodObject<{
|
|
116
|
+
kind: z.ZodOptional<z.ZodString>;
|
|
117
|
+
}, z.core.$strip>;
|
|
118
|
+
export declare const holdReservationInput: z.ZodObject<{
|
|
119
|
+
resourceId: z.ZodString;
|
|
120
|
+
startsAt: z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>;
|
|
121
|
+
endsAt: z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>;
|
|
122
|
+
expiresAt: z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>;
|
|
123
|
+
quantity: z.ZodOptional<z.ZodNumber>;
|
|
124
|
+
fillTarget: z.ZodOptional<z.ZodNumber>;
|
|
125
|
+
note: z.ZodOptional<z.ZodString>;
|
|
126
|
+
now: z.ZodOptional<z.ZodString>;
|
|
127
|
+
}, z.core.$strip>;
|
|
128
|
+
export type HoldReservationInput = z.infer<typeof holdReservationInput>;
|
|
129
|
+
export declare const joinReservationInput: z.ZodObject<{
|
|
130
|
+
reservationId: z.ZodString;
|
|
131
|
+
partyRef: z.core.$ZodBranded<z.ZodString, "DataSubjectId", "out">;
|
|
132
|
+
share: z.ZodOptional<z.ZodObject<{
|
|
133
|
+
amount: z.core.$ZodBranded<z.ZodString, "MoneyAmount", "out">;
|
|
134
|
+
currency: z.core.$ZodBranded<z.ZodString, "CurrencyCode", "out">;
|
|
135
|
+
}, z.core.$strip>>;
|
|
136
|
+
now: z.ZodOptional<z.ZodString>;
|
|
137
|
+
}, z.core.$strip>;
|
|
138
|
+
export type JoinReservationInput = z.infer<typeof joinReservationInput>;
|
|
139
|
+
export declare const leaveReservationInput: z.ZodObject<{
|
|
140
|
+
reservationId: z.ZodString;
|
|
141
|
+
participantId: z.ZodString;
|
|
142
|
+
now: z.ZodOptional<z.ZodString>;
|
|
143
|
+
}, z.core.$strip>;
|
|
144
|
+
export declare const cancelReservationInput: z.ZodObject<{
|
|
145
|
+
reservationId: z.ZodString;
|
|
146
|
+
reason: z.ZodOptional<z.ZodString>;
|
|
147
|
+
}, z.core.$strip>;
|
|
148
|
+
export declare const moveReservationInput: z.ZodObject<{
|
|
149
|
+
reservationId: z.ZodString;
|
|
150
|
+
resourceId: z.ZodOptional<z.ZodString>;
|
|
151
|
+
startsAt: z.ZodOptional<z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>>;
|
|
152
|
+
endsAt: z.ZodOptional<z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>>;
|
|
153
|
+
now: z.ZodOptional<z.ZodString>;
|
|
154
|
+
}, z.core.$strip>;
|
|
155
|
+
export type MoveReservationInput = z.infer<typeof moveReservationInput>;
|
|
156
|
+
export declare const openReservationInput: z.ZodObject<{
|
|
157
|
+
reservationId: z.ZodString;
|
|
158
|
+
fillTarget: z.ZodNullable<z.ZodNumber>;
|
|
159
|
+
now: z.ZodOptional<z.ZodString>;
|
|
160
|
+
}, z.core.$strip>;
|
|
161
|
+
/** `now` is injectable so lazy expiry renders identically in a test and a replay. */
|
|
162
|
+
export declare const reservationAtInput: z.ZodObject<{
|
|
163
|
+
reservationId: z.ZodString;
|
|
164
|
+
now: z.ZodOptional<z.ZodString>;
|
|
165
|
+
}, z.core.$strip>;
|
|
166
|
+
export declare const listReservationsInput: z.ZodObject<{
|
|
167
|
+
resourceId: z.ZodOptional<z.ZodString>;
|
|
168
|
+
from: z.ZodOptional<z.ZodString>;
|
|
169
|
+
to: z.ZodOptional<z.ZodString>;
|
|
170
|
+
now: z.ZodOptional<z.ZodString>;
|
|
171
|
+
}, z.core.$strip>;
|
|
172
|
+
export declare const availabilityInput: z.ZodObject<{
|
|
173
|
+
resourceId: z.ZodString;
|
|
174
|
+
from: z.ZodString;
|
|
175
|
+
to: z.ZodString;
|
|
176
|
+
now: z.ZodOptional<z.ZodString>;
|
|
177
|
+
}, z.core.$strip>;
|
|
178
|
+
//# sourceMappingURL=schemas.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schemas.d.ts","sourceRoot":"","sources":["../src/schemas.ts"],"names":[],"mappings":"AAAA,OAAO,EAAuC,CAAC,EAAE,MAAM,yBAAyB,CAAC;AAGjF;;;;;;;;;;;;;;;;;;;;;GAqBG;AAMH,mDAAmD;AACnD,wBAAgB,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAI/C;AAED,eAAO,MAAM,SAAS,wDAGC,CAAC;AAMxB;;;;;GAKG;AACH,eAAO,MAAM,gBAAgB;;;;;;;;EAAiD,CAAC;AAC/E,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAEhE,eAAO,MAAM,QAAQ;;;;;;;iBAOnB,CAAC;AACH,MAAM,MAAM,QAAQ,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,QAAQ,CAAC,CAAC;AAEhD,eAAO,MAAM,WAAW;;;;;;;;;iBAMtB,CAAC;AACH,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,WAAW,CAAC,CAAC;AAEtD,eAAO,MAAM,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAsBtB,CAAC;AACH,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,WAAW,CAAC,CAAC;AAEtD,eAAO,MAAM,YAAY;;;;iBAIvB,CAAC;AACH,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,YAAY,CAAC,CAAC;AAMxD,gFAAgF;AAChF,eAAO,MAAM,eAAe;;iBAAiD,CAAC;AAE9E,eAAO,MAAM,mBAAmB;;;;iBAI9B,CAAC;AACH,MAAM,MAAM,mBAAmB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mBAAmB,CAAC,CAAC;AAEtE,eAAO,MAAM,sBAAsB;;;iBAGjC,CAAC;AACH,MAAM,MAAM,sBAAsB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,sBAAsB,CAAC,CAAC;AAE5E,eAAO,MAAM,kBAAkB;;iBAAmD,CAAC;AAEnF,eAAO,MAAM,oBAAoB;;;;;;;;;iBAS/B,CAAC;AACH,MAAM,MAAM,oBAAoB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oBAAoB,CAAC,CAAC;AAExE,eAAO,MAAM,oBAAoB;;;;;;;;iBAU/B,CAAC;AACH,MAAM,MAAM,oBAAoB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oBAAoB,CAAC,CAAC;AAExE,eAAO,MAAM,qBAAqB;;;;iBAGhC,CAAC;AAEH,eAAO,MAAM,sBAAsB;;;iBAEjC,CAAC;AAEH,eAAO,MAAM,oBAAoB;;;;;;iBAS/B,CAAC;AACH,MAAM,MAAM,oBAAoB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oBAAoB,CAAC,CAAC;AAExE,eAAO,MAAM,oBAAoB;;;;iBAG/B,CAAC;AAEH,qFAAqF;AACrF,eAAO,MAAM,kBAAkB;;;iBAAyD,CAAC;AAEzF,eAAO,MAAM,qBAAqB;;;;;iBAKhC,CAAC;AAEH,eAAO,MAAM,iBAAiB;;;;;iBAK5B,CAAC"}
|
package/dist/schemas.js
ADDED
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
import { dataSubjectId, money, substratError, z } from '@substrat-run/contracts';
|
|
2
|
+
import { bookingEntities } from './entities.js';
|
|
3
|
+
/**
|
|
4
|
+
* engine-booking's schemas — what it ACCEPTS and what it ANSWERS (#707/#865).
|
|
5
|
+
*
|
|
6
|
+
* The published projections were seven hand-written `export interface`s in
|
|
7
|
+
* `index.ts`, and the operation inputs were a mix of exported schemas and inline
|
|
8
|
+
* TypeScript types on each handler. Both moved here because `defineOperations`
|
|
9
|
+
* declares an operation's `input` and `output` as schemas, and a TypeScript
|
|
10
|
+
* interface cannot be one — the alternative was a zod schema beside each
|
|
11
|
+
* interface saying the same thing twice, which is the two-descriptions defect
|
|
12
|
+
* this engine already deleted once (see `reservationState` below).
|
|
13
|
+
*
|
|
14
|
+
* They live in their own file rather than in `operations.ts` for the reason
|
|
15
|
+
* `entities.ts` does: `index.ts` needs them too, and a declaration file that
|
|
16
|
+
* imports the implementation is the cycle the old `OPERATIONS` note described.
|
|
17
|
+
* Nothing here imports `index.ts`, so the direction stays acyclic.
|
|
18
|
+
*
|
|
19
|
+
* Row versus published, the distinction `entities.ts` draws: a `ResourceRow` has
|
|
20
|
+
* `active` as 0/1 and `created_at` in snake_case because SQLite has no boolean
|
|
21
|
+
* and the column is what it is. `Resource` publishes `active: boolean` and
|
|
22
|
+
* `createdAt`. The registry describes what is STORED; this describes what is
|
|
23
|
+
* ANSWERED, and `toResource`/`toReservation` in `index.ts` are the one crossing.
|
|
24
|
+
*/
|
|
25
|
+
// ---------------------------------------------------------------------------
|
|
26
|
+
// Instants
|
|
27
|
+
// ---------------------------------------------------------------------------
|
|
28
|
+
/** Parse to a canonical ISO instant, or refuse. */
|
|
29
|
+
export function toInstant(value) {
|
|
30
|
+
const ms = Date.parse(value);
|
|
31
|
+
if (Number.isNaN(ms))
|
|
32
|
+
throw substratError('validation_failed', `invalid instant: ${value}`);
|
|
33
|
+
return new Date(ms).toISOString();
|
|
34
|
+
}
|
|
35
|
+
export const instantIn = z
|
|
36
|
+
.string()
|
|
37
|
+
.refine((s) => !Number.isNaN(Date.parse(s)), { message: 'invalid instant' })
|
|
38
|
+
.transform(toInstant);
|
|
39
|
+
// ---------------------------------------------------------------------------
|
|
40
|
+
// Published projections
|
|
41
|
+
// ---------------------------------------------------------------------------
|
|
42
|
+
/**
|
|
43
|
+
* The reservation's states — **taken from the entity registry, not restated**.
|
|
44
|
+
*
|
|
45
|
+
* Moved here from `index.ts` unchanged. Reading the column's own schema keeps
|
|
46
|
+
* storage and domain unable to disagree (#844).
|
|
47
|
+
*/
|
|
48
|
+
export const reservationState = bookingEntities.reservation.fields.shape.state;
|
|
49
|
+
export const resource = z.object({
|
|
50
|
+
id: z.string(),
|
|
51
|
+
kind: z.string(),
|
|
52
|
+
name: z.string(),
|
|
53
|
+
capacity: z.number(),
|
|
54
|
+
active: z.boolean(),
|
|
55
|
+
createdAt: z.string(),
|
|
56
|
+
});
|
|
57
|
+
export const participant = z.object({
|
|
58
|
+
id: z.string(),
|
|
59
|
+
partyRef: z.string(),
|
|
60
|
+
share: money.nullable(),
|
|
61
|
+
joinedAt: z.string(),
|
|
62
|
+
leftAt: z.string().nullable(),
|
|
63
|
+
});
|
|
64
|
+
export const reservation = z.object({
|
|
65
|
+
id: z.string(),
|
|
66
|
+
resourceId: z.string(),
|
|
67
|
+
startsAt: z.string(),
|
|
68
|
+
endsAt: z.string(),
|
|
69
|
+
/** The state as stored. A `held` row keeps saying `held` until someone sweeps it. */
|
|
70
|
+
state: reservationState,
|
|
71
|
+
/**
|
|
72
|
+
* What the row actually means *now* — `expired` once a hold's deadline has passed,
|
|
73
|
+
* whether or not anyone has swept it.
|
|
74
|
+
*
|
|
75
|
+
* Expiry is lazy, so `state` alone would render a dead hold as a live one: the
|
|
76
|
+
* console calendar would show a HELD cell counting down past 0:00 forever. Read
|
|
77
|
+
* paths render this; the transition guards use the stored `state`.
|
|
78
|
+
*/
|
|
79
|
+
effectiveState: reservationState,
|
|
80
|
+
quantity: z.number(),
|
|
81
|
+
expiresAt: z.string().nullable(),
|
|
82
|
+
fillTarget: z.number().nullable(),
|
|
83
|
+
note: z.string().nullable(),
|
|
84
|
+
createdBy: z.string(),
|
|
85
|
+
createdAt: z.string(),
|
|
86
|
+
});
|
|
87
|
+
export const freeInterval = z.object({
|
|
88
|
+
startsAt: z.string(),
|
|
89
|
+
endsAt: z.string(),
|
|
90
|
+
available: z.number(),
|
|
91
|
+
});
|
|
92
|
+
// ---------------------------------------------------------------------------
|
|
93
|
+
// Operation inputs
|
|
94
|
+
// ---------------------------------------------------------------------------
|
|
95
|
+
/** Every reservation-scoped operation opens with this, and most add nothing. */
|
|
96
|
+
export const reservationIdIn = z.object({ reservationId: z.string().min(1) });
|
|
97
|
+
export const createResourceInput = z.object({
|
|
98
|
+
kind: z.string().min(1),
|
|
99
|
+
name: z.string().min(1),
|
|
100
|
+
capacity: z.number().int().min(1).optional(),
|
|
101
|
+
});
|
|
102
|
+
export const setResourceActiveInput = z.object({
|
|
103
|
+
resourceId: z.string().min(1),
|
|
104
|
+
active: z.boolean(),
|
|
105
|
+
});
|
|
106
|
+
export const listResourcesInput = z.object({ kind: z.string().min(1).optional() });
|
|
107
|
+
export const holdReservationInput = z.object({
|
|
108
|
+
resourceId: z.string().min(1),
|
|
109
|
+
startsAt: instantIn,
|
|
110
|
+
endsAt: instantIn,
|
|
111
|
+
expiresAt: instantIn,
|
|
112
|
+
quantity: z.number().int().min(1).optional(),
|
|
113
|
+
fillTarget: z.number().int().min(1).optional(),
|
|
114
|
+
note: z.string().optional(),
|
|
115
|
+
now: z.string().optional(),
|
|
116
|
+
});
|
|
117
|
+
export const joinReservationInput = z.object({
|
|
118
|
+
reservationId: z.string().min(1),
|
|
119
|
+
/**
|
|
120
|
+
* The participant, as an opaque **data-subject** id — never a `PrincipalId`.
|
|
121
|
+
* A participant is a person, so this must be shreddable: it keys the erasure
|
|
122
|
+
* of the `participant-joined` / `participant-left` events below.
|
|
123
|
+
*/
|
|
124
|
+
partyRef: dataSubjectId,
|
|
125
|
+
share: money.optional(),
|
|
126
|
+
now: z.string().optional(),
|
|
127
|
+
});
|
|
128
|
+
export const leaveReservationInput = reservationIdIn.extend({
|
|
129
|
+
participantId: z.string().min(1),
|
|
130
|
+
now: z.string().optional(),
|
|
131
|
+
});
|
|
132
|
+
export const cancelReservationInput = reservationIdIn.extend({
|
|
133
|
+
reason: z.string().optional(),
|
|
134
|
+
});
|
|
135
|
+
export const moveReservationInput = z.object({
|
|
136
|
+
reservationId: z.string().min(1),
|
|
137
|
+
/** Target resource. Omitted = stay on the current one. */
|
|
138
|
+
resourceId: z.string().min(1).optional(),
|
|
139
|
+
/** New start. Given alone, the booking is *shifted* — its duration is preserved. */
|
|
140
|
+
startsAt: instantIn.optional(),
|
|
141
|
+
/** New end. Given alone, the booking is re-sized from its existing start. */
|
|
142
|
+
endsAt: instantIn.optional(),
|
|
143
|
+
now: z.string().optional(),
|
|
144
|
+
});
|
|
145
|
+
export const openReservationInput = reservationIdIn.extend({
|
|
146
|
+
fillTarget: z.number().int().min(1).nullable(),
|
|
147
|
+
now: z.string().optional(),
|
|
148
|
+
});
|
|
149
|
+
/** `now` is injectable so lazy expiry renders identically in a test and a replay. */
|
|
150
|
+
export const reservationAtInput = reservationIdIn.extend({ now: z.string().optional() });
|
|
151
|
+
export const listReservationsInput = z.object({
|
|
152
|
+
resourceId: z.string().min(1).optional(),
|
|
153
|
+
from: z.string().optional(),
|
|
154
|
+
to: z.string().optional(),
|
|
155
|
+
now: z.string().optional(),
|
|
156
|
+
});
|
|
157
|
+
export const availabilityInput = z.object({
|
|
158
|
+
resourceId: z.string().min(1),
|
|
159
|
+
from: z.string(),
|
|
160
|
+
to: z.string(),
|
|
161
|
+
now: z.string().optional(),
|
|
162
|
+
});
|
|
163
|
+
//# sourceMappingURL=schemas.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schemas.js","sourceRoot":"","sources":["../src/schemas.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@substrat-run/engine-booking",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.0",
|
|
4
4
|
"description": "Substrat engine: reservations — resource + interval + capacity, one allocation invariant, no locks",
|
|
5
5
|
"license": "AGPL-3.0-only",
|
|
6
6
|
"repository": {
|
|
@@ -25,19 +25,23 @@
|
|
|
25
25
|
"access": "public"
|
|
26
26
|
},
|
|
27
27
|
"dependencies": {
|
|
28
|
-
"@substrat-run/contracts": "^0.
|
|
29
|
-
"@substrat-run/kernel": "^0.
|
|
28
|
+
"@substrat-run/contracts": "^0.88.0",
|
|
29
|
+
"@substrat-run/kernel": "^0.88.0"
|
|
30
30
|
},
|
|
31
31
|
"devDependencies": {
|
|
32
32
|
"typescript": "^7.0.0",
|
|
33
33
|
"vitest": "^3.2.7",
|
|
34
34
|
"zod": "^4.4.3",
|
|
35
|
-
"@substrat-run/engine-test-kit": "^0.3.
|
|
36
|
-
"@substrat-run/
|
|
35
|
+
"@substrat-run/engine-test-kit": "^0.3.15",
|
|
36
|
+
"@substrat-run/contract-tests": "^0.88.0",
|
|
37
|
+
"@substrat-run/model-emit": "0.8.0"
|
|
37
38
|
},
|
|
38
39
|
"peerDependencies": {
|
|
39
40
|
"zod": "^4.4.0"
|
|
40
41
|
},
|
|
42
|
+
"substrat": {
|
|
43
|
+
"conformance": "test/conformance.ts"
|
|
44
|
+
},
|
|
41
45
|
"scripts": {
|
|
42
46
|
"build": "tsc -p tsconfig.json",
|
|
43
47
|
"typecheck": "tsc -p tsconfig.json --noEmit && tsc -p tsconfig.test.json --noEmit",
|