@voyantjs/bookings 0.4.5 → 0.5.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 +4 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -2
- package/dist/routes-groups.d.ts +354 -0
- package/dist/routes-groups.d.ts.map +1 -0
- package/dist/routes-groups.js +61 -0
- package/dist/routes.d.ts +380 -3
- package/dist/routes.d.ts.map +1 -1
- package/dist/routes.js +12 -1
- package/dist/schema-groups.d.ts +261 -0
- package/dist/schema-groups.d.ts.map +1 -0
- package/dist/schema-groups.js +34 -0
- package/dist/schema-relations.d.ts +8 -0
- package/dist/schema-relations.d.ts.map +1 -1
- package/dist/schema-relations.js +15 -0
- package/dist/schema.d.ts +1 -0
- package/dist/schema.d.ts.map +1 -1
- package/dist/schema.js +1 -0
- package/dist/service-groups.d.ts +69 -0
- package/dist/service-groups.d.ts.map +1 -0
- package/dist/service-groups.js +199 -0
- package/dist/service.d.ts +1 -1
- package/dist/service.d.ts.map +1 -1
- package/dist/service.js +3 -0
- package/dist/validation.d.ts +47 -0
- package/dist/validation.d.ts.map +1 -1
- package/dist/validation.js +24 -0
- package/package.json +6 -6
|
@@ -0,0 +1,261 @@
|
|
|
1
|
+
export declare const bookingGroupKindEnum: import("drizzle-orm/pg-core").PgEnum<["shared_room", "other"]>;
|
|
2
|
+
export declare const bookingGroupMemberRoleEnum: import("drizzle-orm/pg-core").PgEnum<["primary", "shared"]>;
|
|
3
|
+
export declare const bookingGroups: import("drizzle-orm/pg-core").PgTableWithColumns<{
|
|
4
|
+
name: "booking_groups";
|
|
5
|
+
schema: undefined;
|
|
6
|
+
columns: {
|
|
7
|
+
id: import("drizzle-orm/pg-core").PgColumn<{
|
|
8
|
+
name: string;
|
|
9
|
+
tableName: "booking_groups";
|
|
10
|
+
dataType: "string";
|
|
11
|
+
columnType: "PgText";
|
|
12
|
+
data: string;
|
|
13
|
+
driverParam: string;
|
|
14
|
+
notNull: true;
|
|
15
|
+
hasDefault: true;
|
|
16
|
+
isPrimaryKey: true;
|
|
17
|
+
isAutoincrement: false;
|
|
18
|
+
hasRuntimeDefault: true;
|
|
19
|
+
enumValues: [string, ...string[]];
|
|
20
|
+
baseColumn: never;
|
|
21
|
+
identity: undefined;
|
|
22
|
+
generated: undefined;
|
|
23
|
+
}, {}, {}>;
|
|
24
|
+
kind: import("drizzle-orm/pg-core").PgColumn<{
|
|
25
|
+
name: "kind";
|
|
26
|
+
tableName: "booking_groups";
|
|
27
|
+
dataType: "string";
|
|
28
|
+
columnType: "PgEnumColumn";
|
|
29
|
+
data: "other" | "shared_room";
|
|
30
|
+
driverParam: string;
|
|
31
|
+
notNull: true;
|
|
32
|
+
hasDefault: true;
|
|
33
|
+
isPrimaryKey: false;
|
|
34
|
+
isAutoincrement: false;
|
|
35
|
+
hasRuntimeDefault: false;
|
|
36
|
+
enumValues: ["shared_room", "other"];
|
|
37
|
+
baseColumn: never;
|
|
38
|
+
identity: undefined;
|
|
39
|
+
generated: undefined;
|
|
40
|
+
}, {}, {}>;
|
|
41
|
+
label: import("drizzle-orm/pg-core").PgColumn<{
|
|
42
|
+
name: "label";
|
|
43
|
+
tableName: "booking_groups";
|
|
44
|
+
dataType: "string";
|
|
45
|
+
columnType: "PgText";
|
|
46
|
+
data: string;
|
|
47
|
+
driverParam: string;
|
|
48
|
+
notNull: true;
|
|
49
|
+
hasDefault: false;
|
|
50
|
+
isPrimaryKey: false;
|
|
51
|
+
isAutoincrement: false;
|
|
52
|
+
hasRuntimeDefault: false;
|
|
53
|
+
enumValues: [string, ...string[]];
|
|
54
|
+
baseColumn: never;
|
|
55
|
+
identity: undefined;
|
|
56
|
+
generated: undefined;
|
|
57
|
+
}, {}, {}>;
|
|
58
|
+
primaryBookingId: import("drizzle-orm/pg-core").PgColumn<{
|
|
59
|
+
name: string;
|
|
60
|
+
tableName: "booking_groups";
|
|
61
|
+
dataType: "string";
|
|
62
|
+
columnType: "PgText";
|
|
63
|
+
data: string;
|
|
64
|
+
driverParam: string;
|
|
65
|
+
notNull: false;
|
|
66
|
+
hasDefault: false;
|
|
67
|
+
isPrimaryKey: false;
|
|
68
|
+
isAutoincrement: false;
|
|
69
|
+
hasRuntimeDefault: false;
|
|
70
|
+
enumValues: [string, ...string[]];
|
|
71
|
+
baseColumn: never;
|
|
72
|
+
identity: undefined;
|
|
73
|
+
generated: undefined;
|
|
74
|
+
}, {}, {}>;
|
|
75
|
+
productId: import("drizzle-orm/pg-core").PgColumn<{
|
|
76
|
+
name: "product_id";
|
|
77
|
+
tableName: "booking_groups";
|
|
78
|
+
dataType: "string";
|
|
79
|
+
columnType: "PgText";
|
|
80
|
+
data: string;
|
|
81
|
+
driverParam: string;
|
|
82
|
+
notNull: false;
|
|
83
|
+
hasDefault: false;
|
|
84
|
+
isPrimaryKey: false;
|
|
85
|
+
isAutoincrement: false;
|
|
86
|
+
hasRuntimeDefault: false;
|
|
87
|
+
enumValues: [string, ...string[]];
|
|
88
|
+
baseColumn: never;
|
|
89
|
+
identity: undefined;
|
|
90
|
+
generated: undefined;
|
|
91
|
+
}, {}, {}>;
|
|
92
|
+
optionUnitId: import("drizzle-orm/pg-core").PgColumn<{
|
|
93
|
+
name: "option_unit_id";
|
|
94
|
+
tableName: "booking_groups";
|
|
95
|
+
dataType: "string";
|
|
96
|
+
columnType: "PgText";
|
|
97
|
+
data: string;
|
|
98
|
+
driverParam: string;
|
|
99
|
+
notNull: false;
|
|
100
|
+
hasDefault: false;
|
|
101
|
+
isPrimaryKey: false;
|
|
102
|
+
isAutoincrement: false;
|
|
103
|
+
hasRuntimeDefault: false;
|
|
104
|
+
enumValues: [string, ...string[]];
|
|
105
|
+
baseColumn: never;
|
|
106
|
+
identity: undefined;
|
|
107
|
+
generated: undefined;
|
|
108
|
+
}, {}, {}>;
|
|
109
|
+
metadata: import("drizzle-orm/pg-core").PgColumn<{
|
|
110
|
+
name: "metadata";
|
|
111
|
+
tableName: "booking_groups";
|
|
112
|
+
dataType: "json";
|
|
113
|
+
columnType: "PgJsonb";
|
|
114
|
+
data: Record<string, unknown>;
|
|
115
|
+
driverParam: unknown;
|
|
116
|
+
notNull: false;
|
|
117
|
+
hasDefault: false;
|
|
118
|
+
isPrimaryKey: false;
|
|
119
|
+
isAutoincrement: false;
|
|
120
|
+
hasRuntimeDefault: false;
|
|
121
|
+
enumValues: undefined;
|
|
122
|
+
baseColumn: never;
|
|
123
|
+
identity: undefined;
|
|
124
|
+
generated: undefined;
|
|
125
|
+
}, {}, {
|
|
126
|
+
$type: Record<string, unknown>;
|
|
127
|
+
}>;
|
|
128
|
+
createdAt: import("drizzle-orm/pg-core").PgColumn<{
|
|
129
|
+
name: "created_at";
|
|
130
|
+
tableName: "booking_groups";
|
|
131
|
+
dataType: "date";
|
|
132
|
+
columnType: "PgTimestamp";
|
|
133
|
+
data: Date;
|
|
134
|
+
driverParam: string;
|
|
135
|
+
notNull: true;
|
|
136
|
+
hasDefault: true;
|
|
137
|
+
isPrimaryKey: false;
|
|
138
|
+
isAutoincrement: false;
|
|
139
|
+
hasRuntimeDefault: false;
|
|
140
|
+
enumValues: undefined;
|
|
141
|
+
baseColumn: never;
|
|
142
|
+
identity: undefined;
|
|
143
|
+
generated: undefined;
|
|
144
|
+
}, {}, {}>;
|
|
145
|
+
updatedAt: import("drizzle-orm/pg-core").PgColumn<{
|
|
146
|
+
name: "updated_at";
|
|
147
|
+
tableName: "booking_groups";
|
|
148
|
+
dataType: "date";
|
|
149
|
+
columnType: "PgTimestamp";
|
|
150
|
+
data: Date;
|
|
151
|
+
driverParam: string;
|
|
152
|
+
notNull: true;
|
|
153
|
+
hasDefault: true;
|
|
154
|
+
isPrimaryKey: false;
|
|
155
|
+
isAutoincrement: false;
|
|
156
|
+
hasRuntimeDefault: false;
|
|
157
|
+
enumValues: undefined;
|
|
158
|
+
baseColumn: never;
|
|
159
|
+
identity: undefined;
|
|
160
|
+
generated: undefined;
|
|
161
|
+
}, {}, {}>;
|
|
162
|
+
};
|
|
163
|
+
dialect: "pg";
|
|
164
|
+
}>;
|
|
165
|
+
export declare const bookingGroupMembers: import("drizzle-orm/pg-core").PgTableWithColumns<{
|
|
166
|
+
name: "booking_group_members";
|
|
167
|
+
schema: undefined;
|
|
168
|
+
columns: {
|
|
169
|
+
id: import("drizzle-orm/pg-core").PgColumn<{
|
|
170
|
+
name: string;
|
|
171
|
+
tableName: "booking_group_members";
|
|
172
|
+
dataType: "string";
|
|
173
|
+
columnType: "PgText";
|
|
174
|
+
data: string;
|
|
175
|
+
driverParam: string;
|
|
176
|
+
notNull: true;
|
|
177
|
+
hasDefault: true;
|
|
178
|
+
isPrimaryKey: true;
|
|
179
|
+
isAutoincrement: false;
|
|
180
|
+
hasRuntimeDefault: true;
|
|
181
|
+
enumValues: [string, ...string[]];
|
|
182
|
+
baseColumn: never;
|
|
183
|
+
identity: undefined;
|
|
184
|
+
generated: undefined;
|
|
185
|
+
}, {}, {}>;
|
|
186
|
+
groupId: import("drizzle-orm/pg-core").PgColumn<{
|
|
187
|
+
name: string;
|
|
188
|
+
tableName: "booking_group_members";
|
|
189
|
+
dataType: "string";
|
|
190
|
+
columnType: "PgText";
|
|
191
|
+
data: string;
|
|
192
|
+
driverParam: string;
|
|
193
|
+
notNull: true;
|
|
194
|
+
hasDefault: false;
|
|
195
|
+
isPrimaryKey: false;
|
|
196
|
+
isAutoincrement: false;
|
|
197
|
+
hasRuntimeDefault: false;
|
|
198
|
+
enumValues: [string, ...string[]];
|
|
199
|
+
baseColumn: never;
|
|
200
|
+
identity: undefined;
|
|
201
|
+
generated: undefined;
|
|
202
|
+
}, {}, {}>;
|
|
203
|
+
bookingId: import("drizzle-orm/pg-core").PgColumn<{
|
|
204
|
+
name: string;
|
|
205
|
+
tableName: "booking_group_members";
|
|
206
|
+
dataType: "string";
|
|
207
|
+
columnType: "PgText";
|
|
208
|
+
data: string;
|
|
209
|
+
driverParam: string;
|
|
210
|
+
notNull: true;
|
|
211
|
+
hasDefault: false;
|
|
212
|
+
isPrimaryKey: false;
|
|
213
|
+
isAutoincrement: false;
|
|
214
|
+
hasRuntimeDefault: false;
|
|
215
|
+
enumValues: [string, ...string[]];
|
|
216
|
+
baseColumn: never;
|
|
217
|
+
identity: undefined;
|
|
218
|
+
generated: undefined;
|
|
219
|
+
}, {}, {}>;
|
|
220
|
+
role: import("drizzle-orm/pg-core").PgColumn<{
|
|
221
|
+
name: "role";
|
|
222
|
+
tableName: "booking_group_members";
|
|
223
|
+
dataType: "string";
|
|
224
|
+
columnType: "PgEnumColumn";
|
|
225
|
+
data: "primary" | "shared";
|
|
226
|
+
driverParam: string;
|
|
227
|
+
notNull: true;
|
|
228
|
+
hasDefault: true;
|
|
229
|
+
isPrimaryKey: false;
|
|
230
|
+
isAutoincrement: false;
|
|
231
|
+
hasRuntimeDefault: false;
|
|
232
|
+
enumValues: ["primary", "shared"];
|
|
233
|
+
baseColumn: never;
|
|
234
|
+
identity: undefined;
|
|
235
|
+
generated: undefined;
|
|
236
|
+
}, {}, {}>;
|
|
237
|
+
createdAt: import("drizzle-orm/pg-core").PgColumn<{
|
|
238
|
+
name: "created_at";
|
|
239
|
+
tableName: "booking_group_members";
|
|
240
|
+
dataType: "date";
|
|
241
|
+
columnType: "PgTimestamp";
|
|
242
|
+
data: Date;
|
|
243
|
+
driverParam: string;
|
|
244
|
+
notNull: true;
|
|
245
|
+
hasDefault: true;
|
|
246
|
+
isPrimaryKey: false;
|
|
247
|
+
isAutoincrement: false;
|
|
248
|
+
hasRuntimeDefault: false;
|
|
249
|
+
enumValues: undefined;
|
|
250
|
+
baseColumn: never;
|
|
251
|
+
identity: undefined;
|
|
252
|
+
generated: undefined;
|
|
253
|
+
}, {}, {}>;
|
|
254
|
+
};
|
|
255
|
+
dialect: "pg";
|
|
256
|
+
}>;
|
|
257
|
+
export type BookingGroup = typeof bookingGroups.$inferSelect;
|
|
258
|
+
export type NewBookingGroup = typeof bookingGroups.$inferInsert;
|
|
259
|
+
export type BookingGroupMember = typeof bookingGroupMembers.$inferSelect;
|
|
260
|
+
export type NewBookingGroupMember = typeof bookingGroupMembers.$inferInsert;
|
|
261
|
+
//# sourceMappingURL=schema-groups.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema-groups.d.ts","sourceRoot":"","sources":["../src/schema-groups.ts"],"names":[],"mappings":"AAKA,eAAO,MAAM,oBAAoB,gEAAyD,CAAA;AAE1F,eAAO,MAAM,0BAA0B,6DAA6D,CAAA;AAEpG,eAAO,MAAM,aAAa;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAkBzB,CAAA;AAED,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAiB/B,CAAA;AAED,MAAM,MAAM,YAAY,GAAG,OAAO,aAAa,CAAC,YAAY,CAAA;AAC5D,MAAM,MAAM,eAAe,GAAG,OAAO,aAAa,CAAC,YAAY,CAAA;AAC/D,MAAM,MAAM,kBAAkB,GAAG,OAAO,mBAAmB,CAAC,YAAY,CAAA;AACxE,MAAM,MAAM,qBAAqB,GAAG,OAAO,mBAAmB,CAAC,YAAY,CAAA"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { typeId, typeIdRef } from "@voyantjs/db/lib/typeid-column";
|
|
2
|
+
import { index, jsonb, pgEnum, pgTable, text, timestamp, uniqueIndex } from "drizzle-orm/pg-core";
|
|
3
|
+
import { bookings } from "./schema-core";
|
|
4
|
+
export const bookingGroupKindEnum = pgEnum("booking_group_kind", ["shared_room", "other"]);
|
|
5
|
+
export const bookingGroupMemberRoleEnum = pgEnum("booking_group_member_role", ["primary", "shared"]);
|
|
6
|
+
export const bookingGroups = pgTable("booking_groups", {
|
|
7
|
+
id: typeId("booking_groups"),
|
|
8
|
+
kind: bookingGroupKindEnum("kind").notNull().default("shared_room"),
|
|
9
|
+
label: text("label").notNull(),
|
|
10
|
+
primaryBookingId: typeIdRef("primary_booking_id"),
|
|
11
|
+
productId: text("product_id"),
|
|
12
|
+
optionUnitId: text("option_unit_id"),
|
|
13
|
+
metadata: jsonb("metadata").$type(),
|
|
14
|
+
createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
|
|
15
|
+
updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow(),
|
|
16
|
+
}, (table) => [
|
|
17
|
+
index("idx_booking_groups_kind").on(table.kind),
|
|
18
|
+
index("idx_booking_groups_product").on(table.productId),
|
|
19
|
+
index("idx_booking_groups_option_unit").on(table.optionUnitId),
|
|
20
|
+
]);
|
|
21
|
+
export const bookingGroupMembers = pgTable("booking_group_members", {
|
|
22
|
+
id: typeId("booking_group_members"),
|
|
23
|
+
groupId: typeIdRef("group_id")
|
|
24
|
+
.notNull()
|
|
25
|
+
.references(() => bookingGroups.id, { onDelete: "cascade" }),
|
|
26
|
+
bookingId: typeIdRef("booking_id")
|
|
27
|
+
.notNull()
|
|
28
|
+
.references(() => bookings.id, { onDelete: "cascade" }),
|
|
29
|
+
role: bookingGroupMemberRoleEnum("role").notNull().default("shared"),
|
|
30
|
+
createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
|
|
31
|
+
}, (table) => [
|
|
32
|
+
uniqueIndex("booking_group_members_booking_unique").on(table.bookingId),
|
|
33
|
+
index("idx_booking_group_members_group").on(table.groupId),
|
|
34
|
+
]);
|
|
@@ -9,6 +9,14 @@ export declare const bookingsRelations: import("drizzle-orm").Relations<"booking
|
|
|
9
9
|
redemptionEvents: import("drizzle-orm").Many<"booking_redemption_events">;
|
|
10
10
|
items: import("drizzle-orm").Many<"booking_items">;
|
|
11
11
|
allocations: import("drizzle-orm").Many<"booking_allocations">;
|
|
12
|
+
groupMemberships: import("drizzle-orm").Many<"booking_group_members">;
|
|
13
|
+
}>;
|
|
14
|
+
export declare const bookingGroupsRelations: import("drizzle-orm").Relations<"booking_groups", {
|
|
15
|
+
members: import("drizzle-orm").Many<"booking_group_members">;
|
|
16
|
+
}>;
|
|
17
|
+
export declare const bookingGroupMembersRelations: import("drizzle-orm").Relations<"booking_group_members", {
|
|
18
|
+
group: import("drizzle-orm").One<"booking_groups", true>;
|
|
19
|
+
booking: import("drizzle-orm").One<"bookings", true>;
|
|
12
20
|
}>;
|
|
13
21
|
export declare const bookingParticipantsRelations: import("drizzle-orm").Relations<"booking_participants", {
|
|
14
22
|
booking: import("drizzle-orm").One<"bookings", true>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"schema-relations.d.ts","sourceRoot":"","sources":["../src/schema-relations.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"schema-relations.d.ts","sourceRoot":"","sources":["../src/schema-relations.ts"],"names":[],"mappings":"AAoBA,eAAO,MAAM,iBAAiB;;;;;;;;;;;;EAY3B,CAAA;AAEH,eAAO,MAAM,sBAAsB;;EAEhC,CAAA;AAEH,eAAO,MAAM,4BAA4B;;;EAStC,CAAA;AAEH,eAAO,MAAM,4BAA4B;;;;;;EAMtC,CAAA;AAEH,eAAO,MAAM,qBAAqB;;;;;;EAM/B,CAAA;AAEH,eAAO,MAAM,2BAA2B;;;;EAUrC,CAAA;AAEH,eAAO,MAAM,gCAAgC;;;EAS1C,CAAA;AAEH,eAAO,MAAM,gCAAgC;;EAK1C,CAAA;AAEH,eAAO,MAAM,4BAA4B;;;;EAUtC,CAAA;AAEH,eAAO,MAAM,gCAAgC;;;;EAa1C,CAAA;AAEH,eAAO,MAAM,2BAA2B;;EAErC,CAAA;AAEH,eAAO,MAAM,6BAA6B;;EAKvC,CAAA;AAEH,eAAO,MAAM,qBAAqB;;EAE/B,CAAA;AAEH,eAAO,MAAM,yBAAyB;;;EAMnC,CAAA"}
|
package/dist/schema-relations.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { relations } from "drizzle-orm";
|
|
2
2
|
import { availabilitySlotsRef } from "./availability-ref.js";
|
|
3
3
|
import { bookingParticipants, bookings } from "./schema-core";
|
|
4
|
+
import { bookingGroupMembers, bookingGroups } from "./schema-groups";
|
|
4
5
|
import { bookingAllocations, bookingFulfillments, bookingItemParticipants, bookingItems, bookingRedemptionEvents, } from "./schema-items";
|
|
5
6
|
import { bookingActivityLog, bookingDocuments, bookingNotes, bookingSessionStates, bookingSupplierStatuses, } from "./schema-operations";
|
|
6
7
|
export const bookingsRelations = relations(bookings, ({ many }) => ({
|
|
@@ -14,6 +15,20 @@ export const bookingsRelations = relations(bookings, ({ many }) => ({
|
|
|
14
15
|
redemptionEvents: many(bookingRedemptionEvents),
|
|
15
16
|
items: many(bookingItems),
|
|
16
17
|
allocations: many(bookingAllocations),
|
|
18
|
+
groupMemberships: many(bookingGroupMembers),
|
|
19
|
+
}));
|
|
20
|
+
export const bookingGroupsRelations = relations(bookingGroups, ({ many }) => ({
|
|
21
|
+
members: many(bookingGroupMembers),
|
|
22
|
+
}));
|
|
23
|
+
export const bookingGroupMembersRelations = relations(bookingGroupMembers, ({ one }) => ({
|
|
24
|
+
group: one(bookingGroups, {
|
|
25
|
+
fields: [bookingGroupMembers.groupId],
|
|
26
|
+
references: [bookingGroups.id],
|
|
27
|
+
}),
|
|
28
|
+
booking: one(bookings, {
|
|
29
|
+
fields: [bookingGroupMembers.bookingId],
|
|
30
|
+
references: [bookings.id],
|
|
31
|
+
}),
|
|
17
32
|
}));
|
|
18
33
|
export const bookingParticipantsRelations = relations(bookingParticipants, ({ one, many }) => ({
|
|
19
34
|
booking: one(bookings, { fields: [bookingParticipants.bookingId], references: [bookings.id] }),
|
package/dist/schema.d.ts
CHANGED
package/dist/schema.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../src/schema.ts"],"names":[],"mappings":"AAAA,cAAc,eAAe,CAAA;AAC7B,cAAc,gBAAgB,CAAA;AAC9B,cAAc,qBAAqB,CAAA;AACnC,cAAc,oBAAoB,CAAA;AAClC,cAAc,iBAAiB,CAAA"}
|
|
1
|
+
{"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../src/schema.ts"],"names":[],"mappings":"AAAA,cAAc,eAAe,CAAA;AAC7B,cAAc,iBAAiB,CAAA;AAC/B,cAAc,gBAAgB,CAAA;AAC9B,cAAc,qBAAqB,CAAA;AACnC,cAAc,oBAAoB,CAAA;AAClC,cAAc,iBAAiB,CAAA"}
|
package/dist/schema.js
CHANGED
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import type { PostgresJsDatabase } from "drizzle-orm/postgres-js";
|
|
2
|
+
import type { z } from "zod";
|
|
3
|
+
import { type Booking, type BookingPassenger } from "./schema-core.js";
|
|
4
|
+
import { type BookingGroup, type BookingGroupMember } from "./schema-groups.js";
|
|
5
|
+
import type { addBookingGroupMemberSchema, bookingGroupListQuerySchema, insertBookingGroupSchema, updateBookingGroupSchema } from "./validation.js";
|
|
6
|
+
export type BookingGroupListQuery = z.infer<typeof bookingGroupListQuerySchema>;
|
|
7
|
+
export type CreateBookingGroupInput = z.infer<typeof insertBookingGroupSchema>;
|
|
8
|
+
export type UpdateBookingGroupInput = z.infer<typeof updateBookingGroupSchema>;
|
|
9
|
+
export type AddBookingGroupMemberInput = z.infer<typeof addBookingGroupMemberSchema>;
|
|
10
|
+
export type BookingGroupMemberWithBooking = BookingGroupMember & {
|
|
11
|
+
booking: Booking | null;
|
|
12
|
+
};
|
|
13
|
+
export declare function listBookingGroups(db: PostgresJsDatabase, query: BookingGroupListQuery): Promise<{
|
|
14
|
+
data: BookingGroup[];
|
|
15
|
+
total: number;
|
|
16
|
+
limit: number;
|
|
17
|
+
offset: number;
|
|
18
|
+
}>;
|
|
19
|
+
export declare function getBookingGroupById(db: PostgresJsDatabase, id: string): Promise<BookingGroup | null>;
|
|
20
|
+
export declare function createBookingGroup(db: PostgresJsDatabase, data: CreateBookingGroupInput): Promise<BookingGroup>;
|
|
21
|
+
export declare function updateBookingGroup(db: PostgresJsDatabase, id: string, data: UpdateBookingGroupInput): Promise<BookingGroup | null>;
|
|
22
|
+
export declare function deleteBookingGroup(db: PostgresJsDatabase, id: string): Promise<{
|
|
23
|
+
id: string;
|
|
24
|
+
} | null>;
|
|
25
|
+
export declare function listGroupMembers(db: PostgresJsDatabase, groupId: string): Promise<BookingGroupMemberWithBooking[]>;
|
|
26
|
+
export declare function getBookingGroupForBooking(db: PostgresJsDatabase, bookingId: string): Promise<(BookingGroup & {
|
|
27
|
+
membership: BookingGroupMember;
|
|
28
|
+
}) | null>;
|
|
29
|
+
export declare function addGroupMember(db: PostgresJsDatabase, groupId: string, data: AddBookingGroupMemberInput): Promise<{
|
|
30
|
+
status: "ok";
|
|
31
|
+
member: BookingGroupMember;
|
|
32
|
+
} | {
|
|
33
|
+
status: "group_not_found";
|
|
34
|
+
} | {
|
|
35
|
+
status: "booking_not_found";
|
|
36
|
+
} | {
|
|
37
|
+
status: "already_in_group";
|
|
38
|
+
currentGroupId: string;
|
|
39
|
+
}>;
|
|
40
|
+
export declare function removeGroupMember(db: PostgresJsDatabase, groupId: string, bookingId: string): Promise<{
|
|
41
|
+
id: string;
|
|
42
|
+
} | null>;
|
|
43
|
+
/**
|
|
44
|
+
* Dissolve or slim down a booking group after a member is cancelled.
|
|
45
|
+
*
|
|
46
|
+
* - 3+ active members remain: no-op (group stays intact)
|
|
47
|
+
* - 1 active member remains: dissolve (delete last member + group)
|
|
48
|
+
* - 0 active members remain: delete the group
|
|
49
|
+
*/
|
|
50
|
+
export declare function cleanupGroupOnBookingCancelled(db: PostgresJsDatabase, bookingId: string): Promise<void>;
|
|
51
|
+
/**
|
|
52
|
+
* Returns all passengers across every member booking in a group.
|
|
53
|
+
* Used by rooming-list exports to show shared-room occupants as one unit.
|
|
54
|
+
*/
|
|
55
|
+
export declare function listGroupBookingPassengers(db: PostgresJsDatabase, groupId: string): Promise<BookingPassenger[]>;
|
|
56
|
+
export declare const bookingGroupsService: {
|
|
57
|
+
listBookingGroups: typeof listBookingGroups;
|
|
58
|
+
getBookingGroupById: typeof getBookingGroupById;
|
|
59
|
+
createBookingGroup: typeof createBookingGroup;
|
|
60
|
+
updateBookingGroup: typeof updateBookingGroup;
|
|
61
|
+
deleteBookingGroup: typeof deleteBookingGroup;
|
|
62
|
+
listGroupMembers: typeof listGroupMembers;
|
|
63
|
+
getBookingGroupForBooking: typeof getBookingGroupForBooking;
|
|
64
|
+
addGroupMember: typeof addGroupMember;
|
|
65
|
+
removeGroupMember: typeof removeGroupMember;
|
|
66
|
+
cleanupGroupOnBookingCancelled: typeof cleanupGroupOnBookingCancelled;
|
|
67
|
+
listGroupBookingPassengers: typeof listGroupBookingPassengers;
|
|
68
|
+
};
|
|
69
|
+
//# sourceMappingURL=service-groups.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"service-groups.d.ts","sourceRoot":"","sources":["../src/service-groups.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
import { and, asc, eq, inArray, sql } from "drizzle-orm";
|
|
2
|
+
import { bookingPassengers, bookings } from "./schema-core.js";
|
|
3
|
+
import { bookingGroupMembers, bookingGroups, } from "./schema-groups.js";
|
|
4
|
+
export async function listBookingGroups(db, query) {
|
|
5
|
+
const conditions = [];
|
|
6
|
+
if (query.kind)
|
|
7
|
+
conditions.push(eq(bookingGroups.kind, query.kind));
|
|
8
|
+
if (query.productId)
|
|
9
|
+
conditions.push(eq(bookingGroups.productId, query.productId));
|
|
10
|
+
if (query.optionUnitId)
|
|
11
|
+
conditions.push(eq(bookingGroups.optionUnitId, query.optionUnitId));
|
|
12
|
+
const where = conditions.length ? and(...conditions) : undefined;
|
|
13
|
+
const [rows, countResult] = await Promise.all([
|
|
14
|
+
db
|
|
15
|
+
.select()
|
|
16
|
+
.from(bookingGroups)
|
|
17
|
+
.where(where)
|
|
18
|
+
.limit(query.limit)
|
|
19
|
+
.offset(query.offset)
|
|
20
|
+
.orderBy(asc(bookingGroups.createdAt)),
|
|
21
|
+
db.select({ count: sql `count(*)::int` }).from(bookingGroups).where(where),
|
|
22
|
+
]);
|
|
23
|
+
return {
|
|
24
|
+
data: rows,
|
|
25
|
+
total: countResult[0]?.count ?? 0,
|
|
26
|
+
limit: query.limit,
|
|
27
|
+
offset: query.offset,
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
export async function getBookingGroupById(db, id) {
|
|
31
|
+
const [row] = await db.select().from(bookingGroups).where(eq(bookingGroups.id, id)).limit(1);
|
|
32
|
+
return row ?? null;
|
|
33
|
+
}
|
|
34
|
+
export async function createBookingGroup(db, data) {
|
|
35
|
+
const [row] = await db.insert(bookingGroups).values(data).returning();
|
|
36
|
+
if (!row)
|
|
37
|
+
throw new Error("Failed to create booking group");
|
|
38
|
+
return row;
|
|
39
|
+
}
|
|
40
|
+
export async function updateBookingGroup(db, id, data) {
|
|
41
|
+
const [row] = await db
|
|
42
|
+
.update(bookingGroups)
|
|
43
|
+
.set({ ...data, updatedAt: new Date() })
|
|
44
|
+
.where(eq(bookingGroups.id, id))
|
|
45
|
+
.returning();
|
|
46
|
+
return row ?? null;
|
|
47
|
+
}
|
|
48
|
+
export async function deleteBookingGroup(db, id) {
|
|
49
|
+
const [row] = await db
|
|
50
|
+
.delete(bookingGroups)
|
|
51
|
+
.where(eq(bookingGroups.id, id))
|
|
52
|
+
.returning({ id: bookingGroups.id });
|
|
53
|
+
return row ?? null;
|
|
54
|
+
}
|
|
55
|
+
export async function listGroupMembers(db, groupId) {
|
|
56
|
+
const rows = await db
|
|
57
|
+
.select()
|
|
58
|
+
.from(bookingGroupMembers)
|
|
59
|
+
.where(eq(bookingGroupMembers.groupId, groupId))
|
|
60
|
+
.orderBy(asc(bookingGroupMembers.createdAt));
|
|
61
|
+
if (rows.length === 0)
|
|
62
|
+
return [];
|
|
63
|
+
const bookingIds = rows.map((r) => r.bookingId);
|
|
64
|
+
const bookingRows = await db.select().from(bookings).where(inArray(bookings.id, bookingIds));
|
|
65
|
+
const bookingMap = new Map(bookingRows.map((b) => [b.id, b]));
|
|
66
|
+
return rows.map((member) => ({
|
|
67
|
+
...member,
|
|
68
|
+
booking: bookingMap.get(member.bookingId) ?? null,
|
|
69
|
+
}));
|
|
70
|
+
}
|
|
71
|
+
export async function getBookingGroupForBooking(db, bookingId) {
|
|
72
|
+
const [membership] = await db
|
|
73
|
+
.select()
|
|
74
|
+
.from(bookingGroupMembers)
|
|
75
|
+
.where(eq(bookingGroupMembers.bookingId, bookingId))
|
|
76
|
+
.limit(1);
|
|
77
|
+
if (!membership)
|
|
78
|
+
return null;
|
|
79
|
+
const [group] = await db
|
|
80
|
+
.select()
|
|
81
|
+
.from(bookingGroups)
|
|
82
|
+
.where(eq(bookingGroups.id, membership.groupId))
|
|
83
|
+
.limit(1);
|
|
84
|
+
if (!group)
|
|
85
|
+
return null;
|
|
86
|
+
return { ...group, membership };
|
|
87
|
+
}
|
|
88
|
+
export async function addGroupMember(db, groupId, data) {
|
|
89
|
+
const [group] = await db
|
|
90
|
+
.select({ id: bookingGroups.id })
|
|
91
|
+
.from(bookingGroups)
|
|
92
|
+
.where(eq(bookingGroups.id, groupId))
|
|
93
|
+
.limit(1);
|
|
94
|
+
if (!group)
|
|
95
|
+
return { status: "group_not_found" };
|
|
96
|
+
const [booking] = await db
|
|
97
|
+
.select({ id: bookings.id })
|
|
98
|
+
.from(bookings)
|
|
99
|
+
.where(eq(bookings.id, data.bookingId))
|
|
100
|
+
.limit(1);
|
|
101
|
+
if (!booking)
|
|
102
|
+
return { status: "booking_not_found" };
|
|
103
|
+
const [existing] = await db
|
|
104
|
+
.select({ groupId: bookingGroupMembers.groupId })
|
|
105
|
+
.from(bookingGroupMembers)
|
|
106
|
+
.where(eq(bookingGroupMembers.bookingId, data.bookingId))
|
|
107
|
+
.limit(1);
|
|
108
|
+
if (existing) {
|
|
109
|
+
return { status: "already_in_group", currentGroupId: existing.groupId };
|
|
110
|
+
}
|
|
111
|
+
const [member] = await db
|
|
112
|
+
.insert(bookingGroupMembers)
|
|
113
|
+
.values({
|
|
114
|
+
groupId,
|
|
115
|
+
bookingId: data.bookingId,
|
|
116
|
+
role: data.role,
|
|
117
|
+
})
|
|
118
|
+
.returning();
|
|
119
|
+
if (!member)
|
|
120
|
+
throw new Error("Failed to add group member");
|
|
121
|
+
return { status: "ok", member };
|
|
122
|
+
}
|
|
123
|
+
export async function removeGroupMember(db, groupId, bookingId) {
|
|
124
|
+
const [row] = await db
|
|
125
|
+
.delete(bookingGroupMembers)
|
|
126
|
+
.where(and(eq(bookingGroupMembers.groupId, groupId), eq(bookingGroupMembers.bookingId, bookingId)))
|
|
127
|
+
.returning({ id: bookingGroupMembers.id });
|
|
128
|
+
return row ?? null;
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Dissolve or slim down a booking group after a member is cancelled.
|
|
132
|
+
*
|
|
133
|
+
* - 3+ active members remain: no-op (group stays intact)
|
|
134
|
+
* - 1 active member remains: dissolve (delete last member + group)
|
|
135
|
+
* - 0 active members remain: delete the group
|
|
136
|
+
*/
|
|
137
|
+
export async function cleanupGroupOnBookingCancelled(db, bookingId) {
|
|
138
|
+
const [membership] = await db
|
|
139
|
+
.select()
|
|
140
|
+
.from(bookingGroupMembers)
|
|
141
|
+
.where(eq(bookingGroupMembers.bookingId, bookingId))
|
|
142
|
+
.limit(1);
|
|
143
|
+
if (!membership)
|
|
144
|
+
return;
|
|
145
|
+
// Remove the cancelled booking's membership
|
|
146
|
+
await db.delete(bookingGroupMembers).where(eq(bookingGroupMembers.id, membership.id));
|
|
147
|
+
// Count remaining members with an active (not-cancelled) booking
|
|
148
|
+
const remaining = await db
|
|
149
|
+
.select({
|
|
150
|
+
memberId: bookingGroupMembers.id,
|
|
151
|
+
bookingId: bookingGroupMembers.bookingId,
|
|
152
|
+
status: bookings.status,
|
|
153
|
+
})
|
|
154
|
+
.from(bookingGroupMembers)
|
|
155
|
+
.innerJoin(bookings, eq(bookings.id, bookingGroupMembers.bookingId))
|
|
156
|
+
.where(eq(bookingGroupMembers.groupId, membership.groupId));
|
|
157
|
+
const active = remaining.filter((r) => r.status !== "cancelled");
|
|
158
|
+
if (active.length === 0) {
|
|
159
|
+
// No active members — delete the group (cascades any non-active members)
|
|
160
|
+
await db.delete(bookingGroups).where(eq(bookingGroups.id, membership.groupId));
|
|
161
|
+
return;
|
|
162
|
+
}
|
|
163
|
+
if (active.length === 1) {
|
|
164
|
+
// Only one active member left — dissolve the group
|
|
165
|
+
await db.delete(bookingGroupMembers).where(eq(bookingGroupMembers.groupId, membership.groupId));
|
|
166
|
+
await db.delete(bookingGroups).where(eq(bookingGroups.id, membership.groupId));
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* Returns all passengers across every member booking in a group.
|
|
171
|
+
* Used by rooming-list exports to show shared-room occupants as one unit.
|
|
172
|
+
*/
|
|
173
|
+
export async function listGroupBookingPassengers(db, groupId) {
|
|
174
|
+
const members = await db
|
|
175
|
+
.select({ bookingId: bookingGroupMembers.bookingId })
|
|
176
|
+
.from(bookingGroupMembers)
|
|
177
|
+
.where(eq(bookingGroupMembers.groupId, groupId));
|
|
178
|
+
if (members.length === 0)
|
|
179
|
+
return [];
|
|
180
|
+
const bookingIds = members.map((m) => m.bookingId);
|
|
181
|
+
return db
|
|
182
|
+
.select()
|
|
183
|
+
.from(bookingPassengers)
|
|
184
|
+
.where(inArray(bookingPassengers.bookingId, bookingIds))
|
|
185
|
+
.orderBy(asc(bookingPassengers.createdAt));
|
|
186
|
+
}
|
|
187
|
+
export const bookingGroupsService = {
|
|
188
|
+
listBookingGroups,
|
|
189
|
+
getBookingGroupById,
|
|
190
|
+
createBookingGroup,
|
|
191
|
+
updateBookingGroup,
|
|
192
|
+
deleteBookingGroup,
|
|
193
|
+
listGroupMembers,
|
|
194
|
+
getBookingGroupForBooking,
|
|
195
|
+
addGroupMember,
|
|
196
|
+
removeGroupMember,
|
|
197
|
+
cleanupGroupOnBookingCancelled,
|
|
198
|
+
listGroupBookingPassengers,
|
|
199
|
+
};
|
package/dist/service.d.ts
CHANGED
|
@@ -2620,6 +2620,7 @@ export declare const bookingsService: {
|
|
|
2620
2620
|
metadata: Record<string, unknown> | null;
|
|
2621
2621
|
sellCurrency: string;
|
|
2622
2622
|
bookingId: string;
|
|
2623
|
+
optionUnitId: string | null;
|
|
2623
2624
|
title: string;
|
|
2624
2625
|
description: string | null;
|
|
2625
2626
|
itemType: "other" | "unit" | "extra" | "service" | "fee" | "tax" | "discount" | "adjustment" | "accommodation" | "transport";
|
|
@@ -2630,7 +2631,6 @@ export declare const bookingsService: {
|
|
|
2630
2631
|
costCurrency: string | null;
|
|
2631
2632
|
unitCostAmountCents: number | null;
|
|
2632
2633
|
totalCostAmountCents: number | null;
|
|
2633
|
-
optionUnitId: string | null;
|
|
2634
2634
|
pricingCategoryId: string | null;
|
|
2635
2635
|
sourceSnapshotId: string | null;
|
|
2636
2636
|
sourceOfferId: string | null;
|