@substrat-run/engine-booking 0.5.3 → 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.
@@ -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"}
@@ -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.5.3",
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/kernel": "^0.87.0",
29
- "@substrat-run/contracts": "^0.87.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.14",
36
- "@substrat-run/model-emit": "0.7.3"
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",