@voyant-travel/mice 0.1.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,24 @@
1
+ import type { LinkableDefinition, Module } from "@voyant-travel/core";
2
+ import type { HonoModule } from "@voyant-travel/hono/module";
3
+ /**
4
+ * The MICE spine is operator-local (niche) — registered in the deployment, NOT
5
+ * the framework standard set. The allotment primitives it links to (room
6
+ * blocks, function spaces) are standard and package-owned. See RFC voyant#1489.
7
+ */
8
+ export declare const programLinkable: LinkableDefinition;
9
+ export declare const sessionLinkable: LinkableDefinition;
10
+ export declare const miceLinkable: {
11
+ program: LinkableDefinition;
12
+ session: LinkableDefinition;
13
+ };
14
+ export declare const miceModule: Module;
15
+ export declare const miceHonoModule: HonoModule;
16
+ export declare const miceHonoModules: readonly [HonoModule];
17
+ export type { MiceAdminRoutes } from "./routes.js";
18
+ export { miceAdminRoutes } from "./routes.js";
19
+ export * from "./schema.js";
20
+ export * from "./service.js";
21
+ export * from "./service-sessions.js";
22
+ export * from "./validation.js";
23
+ export * from "./validation-sessions.js";
24
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAA;AACrE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,4BAA4B,CAAA;AAI5D;;;;GAIG;AACH,eAAO,MAAM,eAAe,EAAE,kBAK7B,CAAA;AAED,eAAO,MAAM,eAAe,EAAE,kBAK7B,CAAA;AAED,eAAO,MAAM,YAAY;;;CAGxB,CAAA;AAED,eAAO,MAAM,UAAU,EAAE,MAGxB,CAAA;AAED,eAAO,MAAM,cAAc,EAAE,UAG5B,CAAA;AAED,eAAO,MAAM,eAAe,uBAA4B,CAAA;AAExD,YAAY,EAAE,eAAe,EAAE,MAAM,aAAa,CAAA;AAClD,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAA;AAC7C,cAAc,aAAa,CAAA;AAC3B,cAAc,cAAc,CAAA;AAC5B,cAAc,uBAAuB,CAAA;AACrC,cAAc,iBAAiB,CAAA;AAC/B,cAAc,0BAA0B,CAAA"}
package/dist/index.js ADDED
@@ -0,0 +1,37 @@
1
+ import { miceAdminRoutes } from "./routes.js";
2
+ /**
3
+ * The MICE spine is operator-local (niche) — registered in the deployment, NOT
4
+ * the framework standard set. The allotment primitives it links to (room
5
+ * blocks, function spaces) are standard and package-owned. See RFC voyant#1489.
6
+ */
7
+ export const programLinkable = {
8
+ module: "mice",
9
+ entity: "program",
10
+ table: "mice_programs",
11
+ idPrefix: "prog",
12
+ };
13
+ export const sessionLinkable = {
14
+ module: "mice",
15
+ entity: "session",
16
+ table: "mice_program_sessions",
17
+ idPrefix: "mpss",
18
+ };
19
+ export const miceLinkable = {
20
+ program: programLinkable,
21
+ session: sessionLinkable,
22
+ };
23
+ export const miceModule = {
24
+ name: "mice",
25
+ linkable: miceLinkable,
26
+ };
27
+ export const miceHonoModule = {
28
+ module: miceModule,
29
+ adminRoutes: miceAdminRoutes,
30
+ };
31
+ export const miceHonoModules = [miceHonoModule];
32
+ export { miceAdminRoutes } from "./routes.js";
33
+ export * from "./schema.js";
34
+ export * from "./service.js";
35
+ export * from "./service-sessions.js";
36
+ export * from "./validation.js";
37
+ export * from "./validation-sessions.js";
@@ -0,0 +1,396 @@
1
+ /**
2
+ * MICE program admin routes. Mounted by the deployment under `/v1/admin/mice`.
3
+ * Routes stay thin: validate, call `miceService`, serialize. See RFC voyant#1489.
4
+ */
5
+ import type { PostgresJsDatabase } from "drizzle-orm/postgres-js";
6
+ type Env = {
7
+ Variables: {
8
+ db: PostgresJsDatabase;
9
+ userId?: string;
10
+ };
11
+ };
12
+ export declare const miceAdminRoutes: import("hono/hono-base").HonoBase<Env, {
13
+ "/programs": {
14
+ $get: {
15
+ input: {};
16
+ output: {
17
+ data: {
18
+ status: "lead" | "planning" | "contracted" | "operating" | "completed" | "cancelled";
19
+ type: "meeting" | "incentive" | "conference" | "exhibition" | "other";
20
+ organizationId: string | null;
21
+ metadata: {
22
+ [x: string]: import("hono/utils/types").JSONValue;
23
+ } | null;
24
+ code: string | null;
25
+ id: string;
26
+ name: string;
27
+ primaryContactPersonId: string | null;
28
+ accountManagerId: string | null;
29
+ destination: string | null;
30
+ startDate: string | null;
31
+ endDate: string | null;
32
+ estimatedPax: number | null;
33
+ confirmedPax: number | null;
34
+ currency: string | null;
35
+ budgetAmountCents: number | null;
36
+ createdAt: string;
37
+ updatedAt: string;
38
+ }[];
39
+ limit: number;
40
+ offset: number;
41
+ };
42
+ outputFormat: "json";
43
+ status: import("hono/utils/http-status").ContentfulStatusCode;
44
+ };
45
+ };
46
+ } & {
47
+ "/programs": {
48
+ $post: {
49
+ input: {};
50
+ output: {
51
+ data: {
52
+ status: "lead" | "planning" | "contracted" | "operating" | "completed" | "cancelled";
53
+ type: "meeting" | "incentive" | "conference" | "exhibition" | "other";
54
+ organizationId: string | null;
55
+ metadata: {
56
+ [x: string]: import("hono/utils/types").JSONValue;
57
+ } | null;
58
+ code: string | null;
59
+ id: string;
60
+ name: string;
61
+ primaryContactPersonId: string | null;
62
+ accountManagerId: string | null;
63
+ destination: string | null;
64
+ startDate: string | null;
65
+ endDate: string | null;
66
+ estimatedPax: number | null;
67
+ confirmedPax: number | null;
68
+ currency: string | null;
69
+ budgetAmountCents: number | null;
70
+ createdAt: string;
71
+ updatedAt: string;
72
+ };
73
+ };
74
+ outputFormat: "json";
75
+ status: 201;
76
+ };
77
+ };
78
+ } & {
79
+ "/programs/:id": {
80
+ $get: {
81
+ input: {
82
+ param: {
83
+ id: string;
84
+ };
85
+ };
86
+ output: {
87
+ error: string;
88
+ };
89
+ outputFormat: "json";
90
+ status: 404;
91
+ } | {
92
+ input: {
93
+ param: {
94
+ id: string;
95
+ };
96
+ };
97
+ output: {
98
+ data: {
99
+ status: "lead" | "planning" | "contracted" | "operating" | "completed" | "cancelled";
100
+ type: "meeting" | "incentive" | "conference" | "exhibition" | "other";
101
+ organizationId: string | null;
102
+ metadata: {
103
+ [x: string]: import("hono/utils/types").JSONValue;
104
+ } | null;
105
+ code: string | null;
106
+ id: string;
107
+ name: string;
108
+ primaryContactPersonId: string | null;
109
+ accountManagerId: string | null;
110
+ destination: string | null;
111
+ startDate: string | null;
112
+ endDate: string | null;
113
+ estimatedPax: number | null;
114
+ confirmedPax: number | null;
115
+ currency: string | null;
116
+ budgetAmountCents: number | null;
117
+ createdAt: string;
118
+ updatedAt: string;
119
+ };
120
+ };
121
+ outputFormat: "json";
122
+ status: import("hono/utils/http-status").ContentfulStatusCode;
123
+ };
124
+ };
125
+ } & {
126
+ "/programs/:id": {
127
+ $patch: {
128
+ input: {
129
+ param: {
130
+ id: string;
131
+ };
132
+ };
133
+ output: {
134
+ error: string;
135
+ };
136
+ outputFormat: "json";
137
+ status: 404;
138
+ } | {
139
+ input: {
140
+ param: {
141
+ id: string;
142
+ };
143
+ };
144
+ output: {
145
+ data: {
146
+ status: "lead" | "planning" | "contracted" | "operating" | "completed" | "cancelled";
147
+ type: "meeting" | "incentive" | "conference" | "exhibition" | "other";
148
+ organizationId: string | null;
149
+ metadata: {
150
+ [x: string]: import("hono/utils/types").JSONValue;
151
+ } | null;
152
+ code: string | null;
153
+ id: string;
154
+ name: string;
155
+ primaryContactPersonId: string | null;
156
+ accountManagerId: string | null;
157
+ destination: string | null;
158
+ startDate: string | null;
159
+ endDate: string | null;
160
+ estimatedPax: number | null;
161
+ confirmedPax: number | null;
162
+ currency: string | null;
163
+ budgetAmountCents: number | null;
164
+ createdAt: string;
165
+ updatedAt: string;
166
+ };
167
+ };
168
+ outputFormat: "json";
169
+ status: import("hono/utils/http-status").ContentfulStatusCode;
170
+ };
171
+ };
172
+ } & {
173
+ "/sessions": {
174
+ $get: {
175
+ input: {};
176
+ output: {
177
+ data: {
178
+ metadata: {
179
+ [x: string]: import("hono/utils/types").JSONValue;
180
+ } | null;
181
+ id: string;
182
+ title: string;
183
+ createdAt: string;
184
+ updatedAt: string;
185
+ programId: string;
186
+ sessionType: "keynote" | "breakout" | "meal" | "networking" | "gala" | "excursion" | "free";
187
+ functionSpaceId: string | null;
188
+ dayDate: string | null;
189
+ startsAt: string | null;
190
+ endsAt: string | null;
191
+ track: string | null;
192
+ capacity: number | null;
193
+ requiresRegistration: boolean;
194
+ notes: string | null;
195
+ }[];
196
+ limit: number;
197
+ offset: number;
198
+ };
199
+ outputFormat: "json";
200
+ status: import("hono/utils/http-status").ContentfulStatusCode;
201
+ };
202
+ };
203
+ } & {
204
+ "/sessions": {
205
+ $post: {
206
+ input: {};
207
+ output: {
208
+ data: {
209
+ metadata: {
210
+ [x: string]: import("hono/utils/types").JSONValue;
211
+ } | null;
212
+ id: string;
213
+ title: string;
214
+ createdAt: string;
215
+ updatedAt: string;
216
+ programId: string;
217
+ sessionType: "keynote" | "breakout" | "meal" | "networking" | "gala" | "excursion" | "free";
218
+ functionSpaceId: string | null;
219
+ dayDate: string | null;
220
+ startsAt: string | null;
221
+ endsAt: string | null;
222
+ track: string | null;
223
+ capacity: number | null;
224
+ requiresRegistration: boolean;
225
+ notes: string | null;
226
+ };
227
+ };
228
+ outputFormat: "json";
229
+ status: 201;
230
+ };
231
+ };
232
+ } & {
233
+ "/sessions/:id": {
234
+ $get: {
235
+ input: {
236
+ param: {
237
+ id: string;
238
+ };
239
+ };
240
+ output: {
241
+ error: string;
242
+ };
243
+ outputFormat: "json";
244
+ status: 404;
245
+ } | {
246
+ input: {
247
+ param: {
248
+ id: string;
249
+ };
250
+ };
251
+ output: {
252
+ data: {
253
+ metadata: {
254
+ [x: string]: import("hono/utils/types").JSONValue;
255
+ } | null;
256
+ id: string;
257
+ title: string;
258
+ createdAt: string;
259
+ updatedAt: string;
260
+ programId: string;
261
+ sessionType: "keynote" | "breakout" | "meal" | "networking" | "gala" | "excursion" | "free";
262
+ functionSpaceId: string | null;
263
+ dayDate: string | null;
264
+ startsAt: string | null;
265
+ endsAt: string | null;
266
+ track: string | null;
267
+ capacity: number | null;
268
+ requiresRegistration: boolean;
269
+ notes: string | null;
270
+ inclusions: {
271
+ id: string;
272
+ description: string | null;
273
+ currency: string | null;
274
+ createdAt: string;
275
+ updatedAt: string;
276
+ kind: "other" | "fnb" | "av" | "materials" | "signage";
277
+ quantity: number;
278
+ costAmountCents: number | null;
279
+ sessionId: string;
280
+ }[];
281
+ };
282
+ };
283
+ outputFormat: "json";
284
+ status: import("hono/utils/http-status").ContentfulStatusCode;
285
+ };
286
+ };
287
+ } & {
288
+ "/sessions/:id": {
289
+ $patch: {
290
+ input: {
291
+ param: {
292
+ id: string;
293
+ };
294
+ };
295
+ output: {
296
+ error: string;
297
+ };
298
+ outputFormat: "json";
299
+ status: 404;
300
+ } | {
301
+ input: {
302
+ param: {
303
+ id: string;
304
+ };
305
+ };
306
+ output: {
307
+ data: {
308
+ metadata: {
309
+ [x: string]: import("hono/utils/types").JSONValue;
310
+ } | null;
311
+ id: string;
312
+ title: string;
313
+ createdAt: string;
314
+ updatedAt: string;
315
+ programId: string;
316
+ sessionType: "keynote" | "breakout" | "meal" | "networking" | "gala" | "excursion" | "free";
317
+ functionSpaceId: string | null;
318
+ dayDate: string | null;
319
+ startsAt: string | null;
320
+ endsAt: string | null;
321
+ track: string | null;
322
+ capacity: number | null;
323
+ requiresRegistration: boolean;
324
+ notes: string | null;
325
+ };
326
+ };
327
+ outputFormat: "json";
328
+ status: import("hono/utils/http-status").ContentfulStatusCode;
329
+ };
330
+ };
331
+ } & {
332
+ "/sessions/:id": {
333
+ $delete: {
334
+ input: {
335
+ param: {
336
+ id: string;
337
+ };
338
+ };
339
+ output: {
340
+ error: string;
341
+ };
342
+ outputFormat: "json";
343
+ status: 404;
344
+ } | {
345
+ input: {
346
+ param: {
347
+ id: string;
348
+ };
349
+ };
350
+ output: {
351
+ success: true;
352
+ };
353
+ outputFormat: "json";
354
+ status: import("hono/utils/http-status").ContentfulStatusCode;
355
+ };
356
+ };
357
+ } & {
358
+ "/sessions/:id/inclusions": {
359
+ $put: {
360
+ input: {
361
+ param: {
362
+ id: string;
363
+ };
364
+ };
365
+ output: {
366
+ error: string;
367
+ };
368
+ outputFormat: "json";
369
+ status: 404;
370
+ } | {
371
+ input: {
372
+ param: {
373
+ id: string;
374
+ };
375
+ };
376
+ output: {
377
+ data: {
378
+ id: string;
379
+ description: string | null;
380
+ currency: string | null;
381
+ createdAt: string;
382
+ updatedAt: string;
383
+ kind: "other" | "fnb" | "av" | "materials" | "signage";
384
+ quantity: number;
385
+ costAmountCents: number | null;
386
+ sessionId: string;
387
+ }[];
388
+ };
389
+ outputFormat: "json";
390
+ status: import("hono/utils/http-status").ContentfulStatusCode;
391
+ };
392
+ };
393
+ }, "/", "/sessions/:id/inclusions">;
394
+ export type MiceAdminRoutes = typeof miceAdminRoutes;
395
+ export {};
396
+ //# sourceMappingURL=routes.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"routes.d.ts","sourceRoot":"","sources":["../src/routes.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAA;AAoBjE,KAAK,GAAG,GAAG;IACT,SAAS,EAAE;QACT,EAAE,EAAE,kBAAkB,CAAA;QACtB,MAAM,CAAC,EAAE,MAAM,CAAA;KAChB,CAAA;CACF,CAAA;AAED,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;mCAmDxB,CAAA;AAEJ,MAAM,MAAM,eAAe,GAAG,OAAO,eAAe,CAAA"}
package/dist/routes.js ADDED
@@ -0,0 +1,68 @@
1
+ /**
2
+ * MICE program admin routes. Mounted by the deployment under `/v1/admin/mice`.
3
+ * Routes stay thin: validate, call `miceService`, serialize. See RFC voyant#1489.
4
+ */
5
+ import { parseJsonBody, parseQuery } from "@voyant-travel/hono";
6
+ import { Hono } from "hono";
7
+ import { createProgram, getProgram, listPrograms, updateProgram } from "./service.js";
8
+ import { createSession, deleteSession, getSession, listSessions, setSessionInclusions, updateSession, } from "./service-sessions.js";
9
+ import { createProgramSchema, programListQuerySchema, updateProgramSchema } from "./validation.js";
10
+ import { createSessionSchema, sessionListQuerySchema, setSessionInclusionsSchema, updateSessionSchema, } from "./validation-sessions.js";
11
+ export const miceAdminRoutes = new Hono()
12
+ .get("/programs", async (c) => {
13
+ const query = await parseQuery(c, programListQuerySchema);
14
+ return c.json(await listPrograms(c.get("db"), query));
15
+ })
16
+ .post("/programs", async (c) => {
17
+ const body = await parseJsonBody(c, createProgramSchema);
18
+ return c.json({ data: await createProgram(c.get("db"), body) }, 201);
19
+ })
20
+ .get("/programs/:id", async (c) => {
21
+ const program = await getProgram(c.get("db"), c.req.param("id"));
22
+ if (!program)
23
+ return c.json({ error: "Program not found" }, 404);
24
+ return c.json({ data: program });
25
+ })
26
+ .patch("/programs/:id", async (c) => {
27
+ const body = await parseJsonBody(c, updateProgramSchema);
28
+ const program = await updateProgram(c.get("db"), c.req.param("id"), body);
29
+ if (!program)
30
+ return c.json({ error: "Program not found" }, 404);
31
+ return c.json({ data: program });
32
+ })
33
+ // Agenda sessions (RFC voyant#1489 Phase 2).
34
+ .get("/sessions", async (c) => {
35
+ const query = await parseQuery(c, sessionListQuerySchema);
36
+ return c.json(await listSessions(c.get("db"), query));
37
+ })
38
+ .post("/sessions", async (c) => {
39
+ const body = await parseJsonBody(c, createSessionSchema);
40
+ return c.json({ data: await createSession(c.get("db"), body) }, 201);
41
+ })
42
+ .get("/sessions/:id", async (c) => {
43
+ const session = await getSession(c.get("db"), c.req.param("id"));
44
+ if (!session)
45
+ return c.json({ error: "Session not found" }, 404);
46
+ return c.json({ data: session });
47
+ })
48
+ .patch("/sessions/:id", async (c) => {
49
+ const body = await parseJsonBody(c, updateSessionSchema);
50
+ const session = await updateSession(c.get("db"), c.req.param("id"), body);
51
+ if (!session)
52
+ return c.json({ error: "Session not found" }, 404);
53
+ return c.json({ data: session });
54
+ })
55
+ .delete("/sessions/:id", async (c) => {
56
+ const ok = await deleteSession(c.get("db"), c.req.param("id"));
57
+ if (!ok)
58
+ return c.json({ error: "Session not found" }, 404);
59
+ return c.json({ success: true });
60
+ })
61
+ .put("/sessions/:id/inclusions", async (c) => {
62
+ const id = c.req.param("id");
63
+ const session = await getSession(c.get("db"), id);
64
+ if (!session)
65
+ return c.json({ error: "Session not found" }, 404);
66
+ const { inclusions } = await parseJsonBody(c, setSessionInclusionsSchema);
67
+ return c.json({ data: await setSessionInclusions(c.get("db"), id, inclusions) });
68
+ });