@voyantjs/bookings 0.9.0 → 0.10.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 +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/markets-ref.d.ts +151 -0
- package/dist/markets-ref.d.ts.map +1 -0
- package/dist/markets-ref.js +19 -0
- package/dist/pii-redaction.d.ts +89 -0
- package/dist/pii-redaction.d.ts.map +1 -0
- package/dist/pii-redaction.js +120 -0
- package/dist/pii.d.ts +1 -0
- package/dist/pii.d.ts.map +1 -1
- package/dist/pii.js +20 -1
- package/dist/routes-groups.d.ts +3 -2
- package/dist/routes-groups.d.ts.map +1 -1
- package/dist/routes-public.d.ts +11 -13
- package/dist/routes-public.d.ts.map +1 -1
- package/dist/routes-public.js +3 -3
- package/dist/routes.d.ts +16 -8
- package/dist/routes.d.ts.map +1 -1
- package/dist/routes.js +57 -9
- package/dist/schema/travel-details.d.ts +37 -0
- package/dist/schema/travel-details.d.ts.map +1 -1
- package/dist/schema/travel-details.js +6 -0
- package/dist/schema-core.d.ts +17 -17
- package/dist/schema-core.d.ts.map +1 -1
- package/dist/schema-core.js +8 -2
- package/dist/schema-items.d.ts.map +1 -1
- package/dist/schema-items.js +6 -1
- package/dist/service-public.d.ts +0 -6
- package/dist/service-public.d.ts.map +1 -1
- package/dist/service-public.js +0 -4
- package/dist/service.d.ts +55 -46
- package/dist/service.d.ts.map +1 -1
- package/dist/service.js +288 -89
- package/dist/state-machine.d.ts +29 -0
- package/dist/state-machine.d.ts.map +1 -0
- package/dist/state-machine.js +39 -0
- package/dist/validation-public.d.ts +0 -6
- package/dist/validation-public.d.ts.map +1 -1
- package/dist/validation-public.js +0 -2
- package/dist/validation.d.ts +0 -4
- package/dist/validation.d.ts.map +1 -1
- package/dist/validation.js +0 -2
- package/dist/workflows/refund-booking.d.ts +87 -0
- package/dist/workflows/refund-booking.d.ts.map +1 -0
- package/dist/workflows/refund-booking.js +210 -0
- package/package.json +7 -6
package/dist/routes.d.ts
CHANGED
|
@@ -26,6 +26,7 @@ export declare const bookingRoutes: import("hono/hono-base").HonoBase<Env, ({
|
|
|
26
26
|
contactPostalCode: string | null;
|
|
27
27
|
sellCurrency: string;
|
|
28
28
|
baseCurrency: string | null;
|
|
29
|
+
fxRateSetId: string | null;
|
|
29
30
|
sellAmountCents: number | null;
|
|
30
31
|
baseSellAmountCents: number | null;
|
|
31
32
|
costAmountCents: number | null;
|
|
@@ -115,7 +116,7 @@ export declare const bookingRoutes: import("hono/hono-base").HonoBase<Env, ({
|
|
|
115
116
|
data: {
|
|
116
117
|
total: number;
|
|
117
118
|
countsByStatus: {
|
|
118
|
-
status: "
|
|
119
|
+
status: import("./state-machine.js").BookingStatus;
|
|
119
120
|
count: number;
|
|
120
121
|
}[];
|
|
121
122
|
monthlyCounts: {
|
|
@@ -256,6 +257,7 @@ export declare const bookingRoutes: import("hono/hono-base").HonoBase<Env, ({
|
|
|
256
257
|
contactPostalCode: string | null;
|
|
257
258
|
sellCurrency: string;
|
|
258
259
|
baseCurrency: string | null;
|
|
260
|
+
fxRateSetId: string | null;
|
|
259
261
|
sellAmountCents: number | null;
|
|
260
262
|
baseSellAmountCents: number | null;
|
|
261
263
|
costAmountCents: number | null;
|
|
@@ -310,6 +312,7 @@ export declare const bookingRoutes: import("hono/hono-base").HonoBase<Env, ({
|
|
|
310
312
|
contactPostalCode: string | null;
|
|
311
313
|
sellCurrency: string;
|
|
312
314
|
baseCurrency: string | null;
|
|
315
|
+
fxRateSetId: string | null;
|
|
313
316
|
sellAmountCents: number | null;
|
|
314
317
|
baseSellAmountCents: number | null;
|
|
315
318
|
costAmountCents: number | null;
|
|
@@ -387,6 +390,7 @@ export declare const bookingRoutes: import("hono/hono-base").HonoBase<Env, ({
|
|
|
387
390
|
contactPostalCode: string | null;
|
|
388
391
|
sellCurrency: string;
|
|
389
392
|
baseCurrency: string | null;
|
|
393
|
+
fxRateSetId: string | null;
|
|
390
394
|
sellAmountCents: number | null;
|
|
391
395
|
baseSellAmountCents: number | null;
|
|
392
396
|
costAmountCents: number | null;
|
|
@@ -532,6 +536,7 @@ export declare const bookingRoutes: import("hono/hono-base").HonoBase<Env, ({
|
|
|
532
536
|
contactPostalCode: string | null;
|
|
533
537
|
sellCurrency: string;
|
|
534
538
|
baseCurrency: string | null;
|
|
539
|
+
fxRateSetId: string | null;
|
|
535
540
|
sellAmountCents: number | null;
|
|
536
541
|
baseSellAmountCents: number | null;
|
|
537
542
|
costAmountCents: number | null;
|
|
@@ -599,6 +604,7 @@ export declare const bookingRoutes: import("hono/hono-base").HonoBase<Env, ({
|
|
|
599
604
|
contactPostalCode: string | null;
|
|
600
605
|
sellCurrency: string;
|
|
601
606
|
baseCurrency: string | null;
|
|
607
|
+
fxRateSetId: string | null;
|
|
602
608
|
sellAmountCents: number | null;
|
|
603
609
|
baseSellAmountCents: number | null;
|
|
604
610
|
costAmountCents: number | null;
|
|
@@ -748,6 +754,7 @@ export declare const bookingRoutes: import("hono/hono-base").HonoBase<Env, ({
|
|
|
748
754
|
contactPostalCode: string | null;
|
|
749
755
|
sellCurrency: string;
|
|
750
756
|
baseCurrency: string | null;
|
|
757
|
+
fxRateSetId: string | null;
|
|
751
758
|
sellAmountCents: number | null;
|
|
752
759
|
baseSellAmountCents: number | null;
|
|
753
760
|
costAmountCents: number | null;
|
|
@@ -834,6 +841,7 @@ export declare const bookingRoutes: import("hono/hono-base").HonoBase<Env, ({
|
|
|
834
841
|
contactPostalCode: string | null;
|
|
835
842
|
sellCurrency: string;
|
|
836
843
|
baseCurrency: string | null;
|
|
844
|
+
fxRateSetId: string | null;
|
|
837
845
|
sellAmountCents: number | null;
|
|
838
846
|
baseSellAmountCents: number | null;
|
|
839
847
|
costAmountCents: number | null;
|
|
@@ -920,6 +928,7 @@ export declare const bookingRoutes: import("hono/hono-base").HonoBase<Env, ({
|
|
|
920
928
|
contactPostalCode: string | null;
|
|
921
929
|
sellCurrency: string;
|
|
922
930
|
baseCurrency: string | null;
|
|
931
|
+
fxRateSetId: string | null;
|
|
923
932
|
sellAmountCents: number | null;
|
|
924
933
|
baseSellAmountCents: number | null;
|
|
925
934
|
costAmountCents: number | null;
|
|
@@ -1019,6 +1028,7 @@ export declare const bookingRoutes: import("hono/hono-base").HonoBase<Env, ({
|
|
|
1019
1028
|
contactPostalCode: string | null;
|
|
1020
1029
|
sellCurrency: string;
|
|
1021
1030
|
baseCurrency: string | null;
|
|
1031
|
+
fxRateSetId: string | null;
|
|
1022
1032
|
sellAmountCents: number | null;
|
|
1023
1033
|
baseSellAmountCents: number | null;
|
|
1024
1034
|
costAmountCents: number | null;
|
|
@@ -1107,7 +1117,6 @@ export declare const bookingRoutes: import("hono/hono-base").HonoBase<Env, ({
|
|
|
1107
1117
|
email: string | null;
|
|
1108
1118
|
phone: string | null;
|
|
1109
1119
|
preferredLanguage: string | null;
|
|
1110
|
-
accessibilityNeeds: string | null;
|
|
1111
1120
|
specialRequests: string | null;
|
|
1112
1121
|
isPrimary: boolean;
|
|
1113
1122
|
notes: string | null;
|
|
@@ -1164,7 +1173,6 @@ export declare const bookingRoutes: import("hono/hono-base").HonoBase<Env, ({
|
|
|
1164
1173
|
email: string | null;
|
|
1165
1174
|
phone: string | null;
|
|
1166
1175
|
preferredLanguage: string | null;
|
|
1167
|
-
accessibilityNeeds: string | null;
|
|
1168
1176
|
specialRequests: string | null;
|
|
1169
1177
|
isPrimary: boolean;
|
|
1170
1178
|
notes: string | null;
|
|
@@ -1225,7 +1233,6 @@ export declare const bookingRoutes: import("hono/hono-base").HonoBase<Env, ({
|
|
|
1225
1233
|
email: string | null;
|
|
1226
1234
|
phone: string | null;
|
|
1227
1235
|
preferredLanguage: string | null;
|
|
1228
|
-
accessibilityNeeds: string | null;
|
|
1229
1236
|
specialRequests: string | null;
|
|
1230
1237
|
isPrimary: boolean;
|
|
1231
1238
|
notes: string | null;
|
|
@@ -1360,8 +1367,8 @@ export declare const bookingRoutes: import("hono/hono-base").HonoBase<Env, ({
|
|
|
1360
1367
|
[x: string]: import("hono/utils/types").JSONValue;
|
|
1361
1368
|
} | null;
|
|
1362
1369
|
description: string | null;
|
|
1363
|
-
sellCurrency: string;
|
|
1364
1370
|
bookingId: string;
|
|
1371
|
+
sellCurrency: string;
|
|
1365
1372
|
optionUnitId: string | null;
|
|
1366
1373
|
title: string;
|
|
1367
1374
|
itemType: "service" | "unit" | "other" | "extra" | "fee" | "tax" | "discount" | "adjustment" | "accommodation" | "transport";
|
|
@@ -1619,9 +1626,9 @@ export declare const bookingRoutes: import("hono/hono-base").HonoBase<Env, ({
|
|
|
1619
1626
|
notes: string | null;
|
|
1620
1627
|
createdAt: string;
|
|
1621
1628
|
updatedAt: string;
|
|
1629
|
+
bookingId: string;
|
|
1622
1630
|
costAmountCents: number;
|
|
1623
1631
|
confirmedAt: string | null;
|
|
1624
|
-
bookingId: string;
|
|
1625
1632
|
costCurrency: string;
|
|
1626
1633
|
supplierServiceId: string | null;
|
|
1627
1634
|
serviceName: string;
|
|
@@ -2196,6 +2203,7 @@ export declare const bookingRoutes: import("hono/hono-base").HonoBase<Env, ({
|
|
|
2196
2203
|
contactPostalCode: string | null;
|
|
2197
2204
|
sellCurrency: string;
|
|
2198
2205
|
baseCurrency: string | null;
|
|
2206
|
+
fxRateSetId: string | null;
|
|
2199
2207
|
sellAmountCents: number | null;
|
|
2200
2208
|
baseSellAmountCents: number | null;
|
|
2201
2209
|
costAmountCents: number | null;
|
|
@@ -2332,6 +2340,7 @@ export declare const bookingRoutes: import("hono/hono-base").HonoBase<Env, ({
|
|
|
2332
2340
|
contactPostalCode: string | null;
|
|
2333
2341
|
sellCurrency: string;
|
|
2334
2342
|
baseCurrency: string | null;
|
|
2343
|
+
fxRateSetId: string | null;
|
|
2335
2344
|
sellAmountCents: number | null;
|
|
2336
2345
|
baseSellAmountCents: number | null;
|
|
2337
2346
|
costAmountCents: number | null;
|
|
@@ -2442,13 +2451,12 @@ export declare const bookingRoutes: import("hono/hono-base").HonoBase<Env, ({
|
|
|
2442
2451
|
email: string | null;
|
|
2443
2452
|
firstName: string;
|
|
2444
2453
|
lastName: string;
|
|
2445
|
-
personId: string | null;
|
|
2446
2454
|
bookingId: string;
|
|
2455
|
+
personId: string | null;
|
|
2447
2456
|
participantType: "other" | "traveler" | "occupant";
|
|
2448
2457
|
travelerCategory: "other" | "adult" | "child" | "infant" | "senior" | null;
|
|
2449
2458
|
phone: string | null;
|
|
2450
2459
|
preferredLanguage: string | null;
|
|
2451
|
-
accessibilityNeeds: string | null;
|
|
2452
2460
|
specialRequests: string | null;
|
|
2453
2461
|
isPrimary: boolean;
|
|
2454
2462
|
}[];
|
package/dist/routes.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"routes.d.ts","sourceRoot":"","sources":["../src/routes.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"routes.d.ts","sourceRoot":"","sources":["../src/routes.ts"],"names":[],"mappings":"AAwBA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAA;AAC7D,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,oBAAoB,CAAA;AAqM7C,eAAO,MAAM,aAAa;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iDA04Ba,CAAA;AAEvC,MAAM,MAAM,aAAa,GAAG,OAAO,aAAa,CAAA;AAChD,MAAM,MAAM,mBAAmB,GAAG,OAAO,mBAAmB,CAAA"}
|
package/dist/routes.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import { ForbiddenApiError, handleApiError, normalizeValidationError, parseJsonBody, parseQuery, requireUserId, UnauthorizedApiError, } from "@voyantjs/hono";
|
|
1
|
+
import { ForbiddenApiError, handleApiError, idempotencyKey, normalizeValidationError, parseJsonBody, parseQuery, requireUserId, UnauthorizedApiError, } from "@voyantjs/hono";
|
|
2
2
|
import { Hono } from "hono";
|
|
3
3
|
import { createBookingPiiService } from "./pii.js";
|
|
4
|
+
import { redactBookingContact, redactTravelerIdentity, shouldRevealBookingPii, } from "./pii-redaction.js";
|
|
4
5
|
import { BOOKING_ROUTE_RUNTIME_CONTAINER_KEY, buildBookingRouteRuntime, } from "./route-runtime.js";
|
|
5
6
|
import { bookingGroupRoutes } from "./routes-groups.js";
|
|
6
7
|
import { bookingPiiAccessLog } from "./schema.js";
|
|
@@ -135,7 +136,25 @@ export const bookingRoutes = new Hono()
|
|
|
135
136
|
// 1. GET / — List bookings
|
|
136
137
|
.get("/", async (c) => {
|
|
137
138
|
const query = parseQuery(c, bookingListQuerySchema);
|
|
138
|
-
|
|
139
|
+
const result = await bookingsService.listBookings(c.get("db"), query);
|
|
140
|
+
const reveal = shouldRevealBookingPii({
|
|
141
|
+
actor: c.get("actor"),
|
|
142
|
+
scopes: c.get("scopes"),
|
|
143
|
+
callerType: c.get("callerType"),
|
|
144
|
+
isInternalRequest: c.get("isInternalRequest"),
|
|
145
|
+
});
|
|
146
|
+
await logBookingPiiAccess(c, {
|
|
147
|
+
action: "read",
|
|
148
|
+
outcome: "allowed",
|
|
149
|
+
reason: reveal ? "list_reveal" : "list_redacted",
|
|
150
|
+
metadata: { rowCount: result.data.length, reveal },
|
|
151
|
+
});
|
|
152
|
+
if (reveal)
|
|
153
|
+
return c.json(result);
|
|
154
|
+
return c.json({
|
|
155
|
+
...result,
|
|
156
|
+
data: result.data.map((row) => redactBookingContact(row)),
|
|
157
|
+
});
|
|
139
158
|
})
|
|
140
159
|
// 1a. POST /pricing-preview — Resolve a pricing snapshot without creating a session.
|
|
141
160
|
.post("/pricing-preview", async (c) => {
|
|
@@ -168,10 +187,23 @@ export const bookingRoutes = new Hono()
|
|
|
168
187
|
if (!row) {
|
|
169
188
|
return c.json({ error: "Booking not found" }, 404);
|
|
170
189
|
}
|
|
171
|
-
|
|
190
|
+
const reveal = shouldRevealBookingPii({
|
|
191
|
+
actor: c.get("actor"),
|
|
192
|
+
scopes: c.get("scopes"),
|
|
193
|
+
callerType: c.get("callerType"),
|
|
194
|
+
isInternalRequest: c.get("isInternalRequest"),
|
|
195
|
+
});
|
|
196
|
+
await logBookingPiiAccess(c, {
|
|
197
|
+
bookingId: row.id,
|
|
198
|
+
action: "read",
|
|
199
|
+
outcome: "allowed",
|
|
200
|
+
reason: reveal ? "detail_reveal" : "detail_redacted",
|
|
201
|
+
metadata: { reveal },
|
|
202
|
+
});
|
|
203
|
+
return c.json({ data: reveal ? row : redactBookingContact(row) });
|
|
172
204
|
})
|
|
173
205
|
// 3. POST /reserve — Reserve inventory and create on-hold booking
|
|
174
|
-
.post("/reserve", async (c) => {
|
|
206
|
+
.post("/reserve", idempotencyKey({ scope: "POST /v1/admin/bookings/reserve" }), async (c) => {
|
|
175
207
|
const result = await bookingsService.reserveBooking(c.get("db"), await parseJsonBody(c, reserveBookingSchema), c.get("userId"));
|
|
176
208
|
if ("booking" in result) {
|
|
177
209
|
return c.json({ data: result.booking }, 201);
|
|
@@ -191,7 +223,7 @@ export const bookingRoutes = new Hono()
|
|
|
191
223
|
return c.json({ error: "Unable to reserve booking" }, 400);
|
|
192
224
|
})
|
|
193
225
|
// 3a. POST /from-product — Create booking draft from product definition
|
|
194
|
-
.post("/from-product", async (c) => {
|
|
226
|
+
.post("/from-product", idempotencyKey({ scope: "POST /v1/admin/bookings/from-product" }), async (c) => {
|
|
195
227
|
const row = await bookingsService.createBookingFromProduct(c.get("db"), await parseJsonBody(c, convertProductSchema), c.get("userId"));
|
|
196
228
|
if (!row) {
|
|
197
229
|
return c.json({ error: "Product or option not found" }, 404);
|
|
@@ -199,7 +231,7 @@ export const bookingRoutes = new Hono()
|
|
|
199
231
|
return c.json({ data: row }, 201);
|
|
200
232
|
})
|
|
201
233
|
// 3b. POST /from-offer/:offerId/reserve — Reserve booking from transaction offer
|
|
202
|
-
.post("/from-offer/:offerId/reserve", async (c) => {
|
|
234
|
+
.post("/from-offer/:offerId/reserve", idempotencyKey({ scope: "POST /v1/admin/bookings/from-offer" }), async (c) => {
|
|
203
235
|
const result = await bookingsService.reserveBookingFromOffer(c.get("db"), c.req.param("offerId"), await parseJsonBody(c, reserveBookingFromTransactionSchema), c.get("userId"));
|
|
204
236
|
if (result.status === "not_found") {
|
|
205
237
|
return c.json({ error: "Offer not found" }, 404);
|
|
@@ -222,7 +254,7 @@ export const bookingRoutes = new Hono()
|
|
|
222
254
|
return c.json({ error: "Unable to reserve booking from offer" }, 400);
|
|
223
255
|
})
|
|
224
256
|
// 3c. POST /from-order/:orderId/reserve — Reserve booking from transaction order
|
|
225
|
-
.post("/from-order/:orderId/reserve", async (c) => {
|
|
257
|
+
.post("/from-order/:orderId/reserve", idempotencyKey({ scope: "POST /v1/admin/bookings/from-order" }), async (c) => {
|
|
226
258
|
const result = await bookingsService.reserveBookingFromOrder(c.get("db"), c.req.param("orderId"), await parseJsonBody(c, reserveBookingFromTransactionSchema), c.get("userId"));
|
|
227
259
|
if (result.status === "not_found") {
|
|
228
260
|
return c.json({ error: "Order not found" }, 404);
|
|
@@ -245,7 +277,7 @@ export const bookingRoutes = new Hono()
|
|
|
245
277
|
return c.json({ error: "Unable to reserve booking from order" }, 400);
|
|
246
278
|
})
|
|
247
279
|
// 4. POST / — Create booking (manual/backoffice only)
|
|
248
|
-
.post("/", async (c) => {
|
|
280
|
+
.post("/", idempotencyKey({ scope: "POST /v1/admin/bookings" }), async (c) => {
|
|
249
281
|
try {
|
|
250
282
|
return c.json({
|
|
251
283
|
data: await bookingsService.createBooking(c.get("db"), await parseJsonBody(c, createBookingSchema, {
|
|
@@ -371,7 +403,23 @@ export const bookingRoutes = new Hono()
|
|
|
371
403
|
// Travelers
|
|
372
404
|
// ==========================================================================
|
|
373
405
|
.get("/:id/travelers", async (c) => {
|
|
374
|
-
|
|
406
|
+
const travelers = await bookingsService.listTravelers(c.get("db"), c.req.param("id"));
|
|
407
|
+
const reveal = shouldRevealBookingPii({
|
|
408
|
+
actor: c.get("actor"),
|
|
409
|
+
scopes: c.get("scopes"),
|
|
410
|
+
callerType: c.get("callerType"),
|
|
411
|
+
isInternalRequest: c.get("isInternalRequest"),
|
|
412
|
+
});
|
|
413
|
+
await logBookingPiiAccess(c, {
|
|
414
|
+
bookingId: c.req.param("id"),
|
|
415
|
+
action: "read",
|
|
416
|
+
outcome: "allowed",
|
|
417
|
+
reason: reveal ? "travelers_reveal" : "travelers_redacted",
|
|
418
|
+
metadata: { rowCount: travelers.length, reveal },
|
|
419
|
+
});
|
|
420
|
+
if (reveal)
|
|
421
|
+
return c.json({ data: travelers });
|
|
422
|
+
return c.json({ data: travelers.map((row) => redactTravelerIdentity(row)) });
|
|
375
423
|
})
|
|
376
424
|
.get("/:id/travelers/:travelerId/travel-details", async (c) => {
|
|
377
425
|
const auth = await authorizeBookingPiiAccess(c, {
|
|
@@ -8,6 +8,9 @@ export declare const bookingTravelerIdentitySchema: z.ZodObject<{
|
|
|
8
8
|
export declare const bookingTravelerDietarySchema: z.ZodObject<{
|
|
9
9
|
dietaryRequirements: z.ZodNullable<z.ZodOptional<z.ZodString>>;
|
|
10
10
|
}, z.core.$strip>;
|
|
11
|
+
export declare const bookingTravelerAccessibilitySchema: z.ZodObject<{
|
|
12
|
+
accessibilityNeeds: z.ZodNullable<z.ZodOptional<z.ZodString>>;
|
|
13
|
+
}, z.core.$strip>;
|
|
11
14
|
export declare const decryptedBookingTravelerTravelDetailSchema: z.ZodObject<{
|
|
12
15
|
travelerId: z.ZodString;
|
|
13
16
|
nationality: z.ZodNullable<z.ZodString>;
|
|
@@ -15,6 +18,7 @@ export declare const decryptedBookingTravelerTravelDetailSchema: z.ZodObject<{
|
|
|
15
18
|
passportExpiry: z.ZodNullable<z.ZodString>;
|
|
16
19
|
dateOfBirth: z.ZodNullable<z.ZodString>;
|
|
17
20
|
dietaryRequirements: z.ZodNullable<z.ZodString>;
|
|
21
|
+
accessibilityNeeds: z.ZodNullable<z.ZodString>;
|
|
18
22
|
isLeadTraveler: z.ZodBoolean;
|
|
19
23
|
createdAt: z.ZodDate;
|
|
20
24
|
updatedAt: z.ZodDate;
|
|
@@ -86,6 +90,29 @@ export declare const bookingTravelerTravelDetails: import("drizzle-orm/pg-core")
|
|
|
86
90
|
enc: string;
|
|
87
91
|
} | null;
|
|
88
92
|
}>;
|
|
93
|
+
accessibilityEncrypted: import("drizzle-orm/pg-core").PgColumn<{
|
|
94
|
+
name: "accessibility_encrypted";
|
|
95
|
+
tableName: "booking_traveler_travel_details";
|
|
96
|
+
dataType: "json";
|
|
97
|
+
columnType: "PgJsonb";
|
|
98
|
+
data: {
|
|
99
|
+
enc: string;
|
|
100
|
+
} | null;
|
|
101
|
+
driverParam: unknown;
|
|
102
|
+
notNull: false;
|
|
103
|
+
hasDefault: false;
|
|
104
|
+
isPrimaryKey: false;
|
|
105
|
+
isAutoincrement: false;
|
|
106
|
+
hasRuntimeDefault: false;
|
|
107
|
+
enumValues: undefined;
|
|
108
|
+
baseColumn: never;
|
|
109
|
+
identity: undefined;
|
|
110
|
+
generated: undefined;
|
|
111
|
+
}, {}, {
|
|
112
|
+
$type: {
|
|
113
|
+
enc: string;
|
|
114
|
+
} | null;
|
|
115
|
+
}>;
|
|
89
116
|
isLeadTraveler: import("drizzle-orm/pg-core").PgColumn<{
|
|
90
117
|
name: "is_lead_traveler";
|
|
91
118
|
tableName: "booking_traveler_travel_details";
|
|
@@ -141,6 +168,9 @@ export declare const bookingTravelerTravelDetails: import("drizzle-orm/pg-core")
|
|
|
141
168
|
dialect: "pg";
|
|
142
169
|
}>;
|
|
143
170
|
export declare const bookingTravelerTravelDetailInsertSchema: z.ZodObject<{
|
|
171
|
+
accessibilityEncrypted: z.ZodNullable<z.ZodOptional<z.ZodNullable<z.ZodObject<{
|
|
172
|
+
enc: z.ZodString;
|
|
173
|
+
}, z.core.$strip>>>>;
|
|
144
174
|
dietaryEncrypted: z.ZodNullable<z.ZodOptional<z.ZodNullable<z.ZodObject<{
|
|
145
175
|
enc: z.ZodString;
|
|
146
176
|
}, z.core.$strip>>>>;
|
|
@@ -151,6 +181,9 @@ export declare const bookingTravelerTravelDetailInsertSchema: z.ZodObject<{
|
|
|
151
181
|
travelerId: z.ZodString;
|
|
152
182
|
}, z.core.$strip>;
|
|
153
183
|
export declare const bookingTravelerTravelDetailUpdateSchema: z.ZodObject<{
|
|
184
|
+
accessibilityEncrypted: z.ZodOptional<z.ZodNullable<z.ZodOptional<z.ZodNullable<z.ZodObject<{
|
|
185
|
+
enc: z.ZodString;
|
|
186
|
+
}, z.core.$strip>>>>>;
|
|
154
187
|
dietaryEncrypted: z.ZodOptional<z.ZodNullable<z.ZodOptional<z.ZodNullable<z.ZodObject<{
|
|
155
188
|
enc: z.ZodString;
|
|
156
189
|
}, z.core.$strip>>>>>;
|
|
@@ -167,12 +200,16 @@ export declare const bookingTravelerTravelDetailSelectSchema: z.ZodObject<{
|
|
|
167
200
|
dietaryEncrypted: z.ZodNullable<z.ZodOptional<z.ZodNullable<z.ZodObject<{
|
|
168
201
|
enc: z.ZodString;
|
|
169
202
|
}, z.core.$strip>>>>;
|
|
203
|
+
accessibilityEncrypted: z.ZodNullable<z.ZodOptional<z.ZodNullable<z.ZodObject<{
|
|
204
|
+
enc: z.ZodString;
|
|
205
|
+
}, z.core.$strip>>>>;
|
|
170
206
|
isLeadTraveler: z.ZodDefault<z.ZodBoolean>;
|
|
171
207
|
createdAt: z.ZodDate;
|
|
172
208
|
updatedAt: z.ZodDate;
|
|
173
209
|
}, z.core.$strip>;
|
|
174
210
|
export type BookingTravelerIdentity = z.infer<typeof bookingTravelerIdentitySchema>;
|
|
175
211
|
export type BookingTravelerDietary = z.infer<typeof bookingTravelerDietarySchema>;
|
|
212
|
+
export type BookingTravelerAccessibility = z.infer<typeof bookingTravelerAccessibilitySchema>;
|
|
176
213
|
export type BookingTravelerTravelDetail = z.infer<typeof bookingTravelerTravelDetailSelectSchema>;
|
|
177
214
|
export type NewBookingTravelerTravelDetail = z.infer<typeof bookingTravelerTravelDetailInsertSchema>;
|
|
178
215
|
export type DecryptedBookingTravelerTravelDetail = z.infer<typeof decryptedBookingTravelerTravelDetailSchema>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"travel-details.d.ts","sourceRoot":"","sources":["../../src/schema/travel-details.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAIvB,eAAO,MAAM,6BAA6B;;;;;iBAKxC,CAAA;AAEF,eAAO,MAAM,4BAA4B;;iBAEvC,CAAA;
|
|
1
|
+
{"version":3,"file":"travel-details.d.ts","sourceRoot":"","sources":["../../src/schema/travel-details.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAIvB,eAAO,MAAM,6BAA6B;;;;;iBAKxC,CAAA;AAEF,eAAO,MAAM,4BAA4B;;iBAEvC,CAAA;AAEF,eAAO,MAAM,kCAAkC;;iBAE7C,CAAA;AAeF,eAAO,MAAM,0CAA0C;;;;;;;;;;;iBACL,CAAA;AAElD,eAAO,MAAM,4BAA4B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAcxC,CAAA;AAUD,eAAO,MAAM,uCAAuC;;;;;;;;;;;;iBAIhD,CAAA;AAEJ,eAAO,MAAM,uCAAuC;;;;;;;;;;;iBAEvB,CAAA;AAE7B,eAAO,MAAM,uCAAuC;;;;;;;;;;;;;;iBAIhD,CAAA;AAEJ,MAAM,MAAM,uBAAuB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,6BAA6B,CAAC,CAAA;AACnF,MAAM,MAAM,sBAAsB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,4BAA4B,CAAC,CAAA;AACjF,MAAM,MAAM,4BAA4B,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kCAAkC,CAAC,CAAA;AAC7F,MAAM,MAAM,2BAA2B,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,uCAAuC,CAAC,CAAA;AACjG,MAAM,MAAM,8BAA8B,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,uCAAuC,CAAC,CAAA;AACpG,MAAM,MAAM,oCAAoC,GAAG,CAAC,CAAC,KAAK,CACxD,OAAO,0CAA0C,CAClD,CAAA"}
|
|
@@ -11,6 +11,9 @@ export const bookingTravelerIdentitySchema = z.object({
|
|
|
11
11
|
export const bookingTravelerDietarySchema = z.object({
|
|
12
12
|
dietaryRequirements: z.string().optional().nullable(),
|
|
13
13
|
});
|
|
14
|
+
export const bookingTravelerAccessibilitySchema = z.object({
|
|
15
|
+
accessibilityNeeds: z.string().optional().nullable(),
|
|
16
|
+
});
|
|
14
17
|
const decryptedBookingTravelerTravelDetailRecordSchema = z.object({
|
|
15
18
|
travelerId: z.string(),
|
|
16
19
|
nationality: z.string().nullable(),
|
|
@@ -18,6 +21,7 @@ const decryptedBookingTravelerTravelDetailRecordSchema = z.object({
|
|
|
18
21
|
passportExpiry: z.string().nullable(),
|
|
19
22
|
dateOfBirth: z.string().nullable(),
|
|
20
23
|
dietaryRequirements: z.string().nullable(),
|
|
24
|
+
accessibilityNeeds: z.string().nullable(),
|
|
21
25
|
isLeadTraveler: z.boolean(),
|
|
22
26
|
createdAt: z.date(),
|
|
23
27
|
updatedAt: z.date(),
|
|
@@ -29,6 +33,7 @@ export const bookingTravelerTravelDetails = pgTable("booking_traveler_travel_det
|
|
|
29
33
|
.references(() => bookingTravelers.id, { onDelete: "cascade" }),
|
|
30
34
|
identityEncrypted: jsonb("identity_encrypted").$type(),
|
|
31
35
|
dietaryEncrypted: jsonb("dietary_encrypted").$type(),
|
|
36
|
+
accessibilityEncrypted: jsonb("accessibility_encrypted").$type(),
|
|
32
37
|
isLeadTraveler: boolean("is_lead_traveler").notNull().default(false),
|
|
33
38
|
createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
|
|
34
39
|
updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow(),
|
|
@@ -37,6 +42,7 @@ const bookingTravelerTravelDetailRecordCoreSchema = z.object({
|
|
|
37
42
|
travelerId: z.string().min(1),
|
|
38
43
|
identityEncrypted: kmsEnvelopeSchema.optional().nullable(),
|
|
39
44
|
dietaryEncrypted: kmsEnvelopeSchema.optional().nullable(),
|
|
45
|
+
accessibilityEncrypted: kmsEnvelopeSchema.optional().nullable(),
|
|
40
46
|
isLeadTraveler: z.boolean().default(false),
|
|
41
47
|
});
|
|
42
48
|
export const bookingTravelerTravelDetailInsertSchema = bookingTravelerTravelDetailRecordCoreSchema
|
package/dist/schema-core.d.ts
CHANGED
|
@@ -342,6 +342,23 @@ export declare const bookings: import("drizzle-orm/pg-core").PgTableWithColumns<
|
|
|
342
342
|
identity: undefined;
|
|
343
343
|
generated: undefined;
|
|
344
344
|
}, {}, {}>;
|
|
345
|
+
fxRateSetId: import("drizzle-orm/pg-core").PgColumn<{
|
|
346
|
+
name: "fx_rate_set_id";
|
|
347
|
+
tableName: "bookings";
|
|
348
|
+
dataType: "string";
|
|
349
|
+
columnType: "PgText";
|
|
350
|
+
data: string;
|
|
351
|
+
driverParam: string;
|
|
352
|
+
notNull: false;
|
|
353
|
+
hasDefault: false;
|
|
354
|
+
isPrimaryKey: false;
|
|
355
|
+
isAutoincrement: false;
|
|
356
|
+
hasRuntimeDefault: false;
|
|
357
|
+
enumValues: [string, ...string[]];
|
|
358
|
+
baseColumn: never;
|
|
359
|
+
identity: undefined;
|
|
360
|
+
generated: undefined;
|
|
361
|
+
}, {}, {}>;
|
|
345
362
|
sellAmountCents: import("drizzle-orm/pg-core").PgColumn<{
|
|
346
363
|
name: "sell_amount_cents";
|
|
347
364
|
tableName: "bookings";
|
|
@@ -808,23 +825,6 @@ export declare const bookingTravelers: import("drizzle-orm/pg-core").PgTableWith
|
|
|
808
825
|
identity: undefined;
|
|
809
826
|
generated: undefined;
|
|
810
827
|
}, {}, {}>;
|
|
811
|
-
accessibilityNeeds: import("drizzle-orm/pg-core").PgColumn<{
|
|
812
|
-
name: "accessibility_needs";
|
|
813
|
-
tableName: "booking_travelers";
|
|
814
|
-
dataType: "string";
|
|
815
|
-
columnType: "PgText";
|
|
816
|
-
data: string;
|
|
817
|
-
driverParam: string;
|
|
818
|
-
notNull: false;
|
|
819
|
-
hasDefault: false;
|
|
820
|
-
isPrimaryKey: false;
|
|
821
|
-
isAutoincrement: false;
|
|
822
|
-
hasRuntimeDefault: false;
|
|
823
|
-
enumValues: [string, ...string[]];
|
|
824
|
-
baseColumn: never;
|
|
825
|
-
identity: undefined;
|
|
826
|
-
generated: undefined;
|
|
827
|
-
}, {}, {}>;
|
|
828
828
|
specialRequests: import("drizzle-orm/pg-core").PgColumn<{
|
|
829
829
|
name: "special_requests";
|
|
830
830
|
tableName: "booking_travelers";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"schema-core.d.ts","sourceRoot":"","sources":["../src/schema-core.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"schema-core.d.ts","sourceRoot":"","sources":["../src/schema-core.ts"],"names":[],"mappings":"AAuBA,eAAO,MAAM,QAAQ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA0DpB,CAAA;AAED,eAAO,MAAM,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAoC5B,CAAA;AAED,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAqB/B,CAAA;AAED,MAAM,MAAM,OAAO,GAAG,OAAO,QAAQ,CAAC,YAAY,CAAA;AAClD,MAAM,MAAM,UAAU,GAAG,OAAO,QAAQ,CAAC,YAAY,CAAA;AACrD,MAAM,MAAM,eAAe,GAAG,OAAO,gBAAgB,CAAC,YAAY,CAAA;AAClE,MAAM,MAAM,kBAAkB,GAAG,OAAO,gBAAgB,CAAC,YAAY,CAAA;AACrE,MAAM,MAAM,mBAAmB,GAAG,OAAO,mBAAmB,CAAC,YAAY,CAAA;AACzE,MAAM,MAAM,sBAAsB,GAAG,OAAO,mBAAmB,CAAC,YAAY,CAAA"}
|
package/dist/schema-core.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { typeId, typeIdRef } from "@voyantjs/db/lib/typeid-column";
|
|
2
|
-
import {
|
|
2
|
+
import { sql } from "drizzle-orm";
|
|
3
|
+
import { boolean, check, date, index, integer, jsonb, pgTable, text, timestamp, } from "drizzle-orm/pg-core";
|
|
3
4
|
import { bookingParticipantTypeEnum, bookingPiiAccessActionEnum, bookingPiiAccessOutcomeEnum, bookingSourceTypeEnum, bookingStatusEnum, bookingTravelerCategoryEnum, } from "./schema-shared";
|
|
4
5
|
export const bookings = pgTable("bookings", {
|
|
5
6
|
id: typeId("bookings"),
|
|
@@ -22,6 +23,7 @@ export const bookings = pgTable("bookings", {
|
|
|
22
23
|
contactPostalCode: text("contact_postal_code"),
|
|
23
24
|
sellCurrency: text("sell_currency").notNull(),
|
|
24
25
|
baseCurrency: text("base_currency"),
|
|
26
|
+
fxRateSetId: text("fx_rate_set_id"),
|
|
25
27
|
sellAmountCents: integer("sell_amount_cents"),
|
|
26
28
|
baseSellAmountCents: integer("base_sell_amount_cents"),
|
|
27
29
|
costAmountCents: integer("cost_amount_cents"),
|
|
@@ -46,6 +48,11 @@ export const bookings = pgTable("bookings", {
|
|
|
46
48
|
index("idx_bookings_organization").on(table.organizationId),
|
|
47
49
|
index("idx_bookings_source_type").on(table.sourceType),
|
|
48
50
|
index("idx_bookings_number").on(table.bookingNumber),
|
|
51
|
+
// base_currency covers the base_*_amount_cents columns. If any base
|
|
52
|
+
// amount is set, base_currency must be set so downstream FX/reporting
|
|
53
|
+
// code can interpret it. Both null is fine (FX deferred until quote
|
|
54
|
+
// becomes a confirmed booking).
|
|
55
|
+
check("ck_bookings_base_currency_amounts", sql `(${table.baseSellAmountCents} IS NULL AND ${table.baseCostAmountCents} IS NULL) OR ${table.baseCurrency} IS NOT NULL`),
|
|
49
56
|
]);
|
|
50
57
|
export const bookingTravelers = pgTable("booking_travelers", {
|
|
51
58
|
id: typeId("booking_travelers"),
|
|
@@ -60,7 +67,6 @@ export const bookingTravelers = pgTable("booking_travelers", {
|
|
|
60
67
|
email: text("email"),
|
|
61
68
|
phone: text("phone"),
|
|
62
69
|
preferredLanguage: text("preferred_language"),
|
|
63
|
-
accessibilityNeeds: text("accessibility_needs"),
|
|
64
70
|
specialRequests: text("special_requests"),
|
|
65
71
|
isPrimary: boolean("is_primary").notNull().default(false),
|
|
66
72
|
notes: text("notes"),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"schema-items.d.ts","sourceRoot":"","sources":["../src/schema-items.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"schema-items.d.ts","sourceRoot":"","sources":["../src/schema-items.ts"],"names":[],"mappings":"AA4BA,eAAO,MAAM,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA4CxB,CAAA;AAED,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAmC9B,CAAA;AAED,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA8B/B,CAAA;AAED,eAAO,MAAM,uBAAuB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA+BnC,CAAA;AAED,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAuBhC,CAAA;AAED,MAAM,MAAM,WAAW,GAAG,OAAO,YAAY,CAAC,YAAY,CAAA;AAC1D,MAAM,MAAM,cAAc,GAAG,OAAO,YAAY,CAAC,YAAY,CAAA;AAC7D,MAAM,MAAM,iBAAiB,GAAG,OAAO,kBAAkB,CAAC,YAAY,CAAA;AACtE,MAAM,MAAM,oBAAoB,GAAG,OAAO,kBAAkB,CAAC,YAAY,CAAA;AACzE,MAAM,MAAM,kBAAkB,GAAG,OAAO,mBAAmB,CAAC,YAAY,CAAA;AACxE,MAAM,MAAM,qBAAqB,GAAG,OAAO,mBAAmB,CAAC,YAAY,CAAA;AAC3E,MAAM,MAAM,sBAAsB,GAAG,OAAO,uBAAuB,CAAC,YAAY,CAAA;AAChF,MAAM,MAAM,yBAAyB,GAAG,OAAO,uBAAuB,CAAC,YAAY,CAAA;AACnF,MAAM,MAAM,mBAAmB,GAAG,OAAO,oBAAoB,CAAC,YAAY,CAAA;AAC1E,MAAM,MAAM,sBAAsB,GAAG,OAAO,oBAAoB,CAAC,YAAY,CAAA"}
|
package/dist/schema-items.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { typeId, typeIdRef } from "@voyantjs/db/lib/typeid-column";
|
|
2
|
-
import {
|
|
2
|
+
import { sql } from "drizzle-orm";
|
|
3
|
+
import { boolean, check, date, index, integer, jsonb, pgTable, text, timestamp, } from "drizzle-orm/pg-core";
|
|
3
4
|
import { availabilitySlotsRef } from "./availability-ref.js";
|
|
4
5
|
import { bookings, bookingTravelers } from "./schema-core";
|
|
5
6
|
import { bookingAllocationStatusEnum, bookingAllocationTypeEnum, bookingFulfillmentDeliveryChannelEnum, bookingFulfillmentStatusEnum, bookingFulfillmentTypeEnum, bookingItemParticipantRoleEnum, bookingItemStatusEnum, bookingItemTypeEnum, bookingRedemptionMethodEnum, } from "./schema-shared";
|
|
@@ -36,6 +37,10 @@ export const bookingItems = pgTable("booking_items", {
|
|
|
36
37
|
index("idx_booking_items_booking").on(table.bookingId),
|
|
37
38
|
index("idx_booking_items_booking_created").on(table.bookingId, table.createdAt),
|
|
38
39
|
index("idx_booking_items_status").on(table.status),
|
|
40
|
+
// cost_currency is optional on items (not every line has cost data) but
|
|
41
|
+
// if any cost amount is set, the currency MUST be set so reporting can
|
|
42
|
+
// interpret it.
|
|
43
|
+
check("ck_booking_items_cost_currency_amounts", sql `(${table.unitCostAmountCents} IS NULL AND ${table.totalCostAmountCents} IS NULL) OR ${table.costCurrency} IS NOT NULL`),
|
|
39
44
|
]);
|
|
40
45
|
export const bookingAllocations = pgTable("booking_allocations", {
|
|
41
46
|
id: typeId("booking_allocations"),
|
package/dist/service-public.d.ts
CHANGED
|
@@ -83,7 +83,6 @@ export declare const publicBookingsService: {
|
|
|
83
83
|
email: string | null;
|
|
84
84
|
phone: string | null;
|
|
85
85
|
preferredLanguage: string | null;
|
|
86
|
-
accessibilityNeeds: string | null;
|
|
87
86
|
specialRequests: string | null;
|
|
88
87
|
isPrimary: boolean;
|
|
89
88
|
notes: string | null;
|
|
@@ -175,7 +174,6 @@ export declare const publicBookingsService: {
|
|
|
175
174
|
email: string | null;
|
|
176
175
|
phone: string | null;
|
|
177
176
|
preferredLanguage: string | null;
|
|
178
|
-
accessibilityNeeds: string | null;
|
|
179
177
|
specialRequests: string | null;
|
|
180
178
|
isPrimary: boolean;
|
|
181
179
|
notes: string | null;
|
|
@@ -296,7 +294,6 @@ export declare const publicBookingsService: {
|
|
|
296
294
|
email: string | null;
|
|
297
295
|
phone: string | null;
|
|
298
296
|
preferredLanguage: string | null;
|
|
299
|
-
accessibilityNeeds: string | null;
|
|
300
297
|
specialRequests: string | null;
|
|
301
298
|
isPrimary: boolean;
|
|
302
299
|
notes: string | null;
|
|
@@ -429,7 +426,6 @@ export declare const publicBookingsService: {
|
|
|
429
426
|
email: string | null;
|
|
430
427
|
phone: string | null;
|
|
431
428
|
preferredLanguage: string | null;
|
|
432
|
-
accessibilityNeeds: string | null;
|
|
433
429
|
specialRequests: string | null;
|
|
434
430
|
isPrimary: boolean;
|
|
435
431
|
notes: string | null;
|
|
@@ -525,7 +521,6 @@ export declare const publicBookingsService: {
|
|
|
525
521
|
email: string | null;
|
|
526
522
|
phone: string | null;
|
|
527
523
|
preferredLanguage: string | null;
|
|
528
|
-
accessibilityNeeds: string | null;
|
|
529
524
|
specialRequests: string | null;
|
|
530
525
|
isPrimary: boolean;
|
|
531
526
|
notes: string | null;
|
|
@@ -621,7 +616,6 @@ export declare const publicBookingsService: {
|
|
|
621
616
|
email: string | null;
|
|
622
617
|
phone: string | null;
|
|
623
618
|
preferredLanguage: string | null;
|
|
624
|
-
accessibilityNeeds: string | null;
|
|
625
619
|
specialRequests: string | null;
|
|
626
620
|
isPrimary: boolean;
|
|
627
621
|
notes: string | null;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"service-public.d.ts","sourceRoot":"","sources":["../src/service-public.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAA;AAoBjE,OAAO,KAAK,EACV,kCAAkC,EAClC,gCAAgC,EAChC,iCAAiC,EACjC,gCAAgC,EAEhC,+BAA+B,EAC/B,+BAA+B,EAC/B,oCAAoC,EACrC,MAAM,wBAAwB,CAAA;AA4d/B;;;;;;;;;;;GAWG;AACH,wBAAsB,6BAA6B,CACjD,EAAE,EAAE,kBAAkB,EACtB,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE;IAAE,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;CAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;UAwKzE;
|
|
1
|
+
{"version":3,"file":"service-public.d.ts","sourceRoot":"","sources":["../src/service-public.ts"],"names":[],"mappings":"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"}
|
package/dist/service-public.js
CHANGED
|
@@ -515,7 +515,6 @@ async function buildSessionSnapshot(db, bookingId) {
|
|
|
515
515
|
email: participant.email ?? null,
|
|
516
516
|
phone: participant.phone ?? null,
|
|
517
517
|
preferredLanguage: participant.preferredLanguage ?? null,
|
|
518
|
-
accessibilityNeeds: participant.accessibilityNeeds ?? null,
|
|
519
518
|
specialRequests: participant.specialRequests ?? null,
|
|
520
519
|
isPrimary: participant.isPrimary,
|
|
521
520
|
notes: participant.notes ?? null,
|
|
@@ -623,7 +622,6 @@ export const publicBookingsService = {
|
|
|
623
622
|
email: participant.email ?? null,
|
|
624
623
|
phone: participant.phone ?? null,
|
|
625
624
|
preferredLanguage: participant.preferredLanguage ?? null,
|
|
626
|
-
accessibilityNeeds: participant.accessibilityNeeds ?? null,
|
|
627
625
|
specialRequests: participant.specialRequests ?? null,
|
|
628
626
|
isPrimary: participant.isPrimary,
|
|
629
627
|
notes: participant.notes ?? null,
|
|
@@ -695,7 +693,6 @@ export const publicBookingsService = {
|
|
|
695
693
|
email: participant.email ?? null,
|
|
696
694
|
phone: participant.phone ?? null,
|
|
697
695
|
preferredLanguage: participant.preferredLanguage ?? null,
|
|
698
|
-
accessibilityNeeds: participant.accessibilityNeeds ?? null,
|
|
699
696
|
specialRequests: participant.specialRequests ?? null,
|
|
700
697
|
isPrimary: participant.isPrimary,
|
|
701
698
|
notes: participant.notes ?? null,
|
|
@@ -710,7 +707,6 @@ export const publicBookingsService = {
|
|
|
710
707
|
email: participant.email ?? null,
|
|
711
708
|
phone: participant.phone ?? null,
|
|
712
709
|
preferredLanguage: participant.preferredLanguage ?? null,
|
|
713
|
-
accessibilityNeeds: participant.accessibilityNeeds ?? null,
|
|
714
710
|
specialRequests: participant.specialRequests ?? null,
|
|
715
711
|
isPrimary: participant.isPrimary,
|
|
716
712
|
notes: participant.notes ?? null,
|