/** * Admin routes for booking groups — the shared-room / split-booking model. * Mounted under the booking admin surface at `/v1/admin/bookings/groups/*`. * * Migrated to `@hono/zod-openapi` for the OpenAPI admin backfill (voyant#2114). * Request schemas reuse the existing `@voyant-travel/bookings-contracts` * schemas the handlers already parse; the list uses the framework's canonical * `listResponseSchema(...)` envelope; response row schemas are authored from the * Drizzle `$inferSelect` shapes (§17: timestamp columns serialize to ISO strings * over the wire). The group-detail GET extends the base row with the joined * `members` array; the add-member POST carries a typed * `group_not_found`/`booking_not_found`/`already_in_group` union declared inline * per leg. The business logic + service wiring are unchanged. * * Split into per-resource child `OpenAPIHono` sub-chains (`.route("/", child)`) * rather than one long flat `.openapi()` chain to keep tsc inference linear. */ import { OpenAPIHono, z } from "@hono/zod-openapi"; import { bookingGroupsService } from "./service-groups.js"; type Env = { Variables: { db: Parameters[0]; userId?: string; }; }; export declare const bookingGroupRoutes: OpenAPIHono & import("hono/types").MergeSchemaPath<{ "/": { $get: { input: { query: { kind?: "other" | "shared_room" | "cruise_party" | undefined; productId?: string | undefined; optionUnitId?: string | undefined; limit?: unknown; offset?: unknown; }; }; output: { data: { id: string; kind: "other" | "shared_room" | "cruise_party"; label: string; primaryBookingId: string | null; productId: string | null; optionUnitId: string | null; metadata: { [x: string]: import("hono/utils/types").JSONValue; } | null; createdAt: string; updatedAt: string; }[]; total: number; limit: number; offset: number; }; outputFormat: "json"; status: 200; } | { input: { query: { kind?: "other" | "shared_room" | "cruise_party" | undefined; productId?: string | undefined; optionUnitId?: string | undefined; limit?: unknown; offset?: unknown; }; }; output: { error: string; }; outputFormat: "json"; status: 400; }; }; } & { "/": { $post: { input: { json: { label: string; kind?: "other" | "shared_room" | "cruise_party" | undefined; primaryBookingId?: string | null | undefined; productId?: string | null | undefined; optionUnitId?: string | null | undefined; metadata?: Record | null | undefined; }; }; output: { error: string; }; outputFormat: "json"; status: 400; } | { input: { json: { label: string; kind?: "other" | "shared_room" | "cruise_party" | undefined; primaryBookingId?: string | null | undefined; productId?: string | null | undefined; optionUnitId?: string | null | undefined; metadata?: Record | null | undefined; }; }; output: { data: { id: string; kind: "other" | "shared_room" | "cruise_party"; label: string; primaryBookingId: string | null; productId: string | null; optionUnitId: string | null; metadata: { [x: string]: import("hono/utils/types").JSONValue; } | null; createdAt: string; updatedAt: string; }; }; outputFormat: "json"; status: 201; }; }; } & { "/:id": { $get: { input: { param: { id: string; }; }; output: { data: { id: string; kind: "other" | "shared_room" | "cruise_party"; label: string; primaryBookingId: string | null; productId: string | null; optionUnitId: string | null; metadata: { [x: string]: import("hono/utils/types").JSONValue; } | null; createdAt: string; updatedAt: string; members: { id: string; groupId: string; bookingId: string; role: "primary" | "shared"; createdAt: string; }[]; }; }; outputFormat: "json"; status: 200; } | { input: { param: { id: string; }; }; output: { error: string; }; outputFormat: "json"; status: 404; }; }; } & { "/:id": { $patch: { input: { param: { id: string; }; } & { json: { kind?: "other" | "shared_room" | "cruise_party" | undefined; label?: string | undefined; primaryBookingId?: string | null | undefined; productId?: string | null | undefined; optionUnitId?: string | null | undefined; metadata?: Record | null | undefined; }; }; output: { error: string; }; outputFormat: "json"; status: 400; } | { input: { param: { id: string; }; } & { json: { kind?: "other" | "shared_room" | "cruise_party" | undefined; label?: string | undefined; primaryBookingId?: string | null | undefined; productId?: string | null | undefined; optionUnitId?: string | null | undefined; metadata?: Record | null | undefined; }; }; output: { error: string; }; outputFormat: "json"; status: 404; } | { input: { param: { id: string; }; } & { json: { kind?: "other" | "shared_room" | "cruise_party" | undefined; label?: string | undefined; primaryBookingId?: string | null | undefined; productId?: string | null | undefined; optionUnitId?: string | null | undefined; metadata?: Record | null | undefined; }; }; output: { data: { id: string; kind: "other" | "shared_room" | "cruise_party"; label: string; primaryBookingId: string | null; productId: string | null; optionUnitId: string | null; metadata: { [x: string]: import("hono/utils/types").JSONValue; } | null; createdAt: string; updatedAt: string; }; }; outputFormat: "json"; status: 200; }; }; } & { "/:id": { $delete: { input: { param: { id: string; }; }; output: { error: string; }; outputFormat: "json"; status: 404; } | { input: { param: { id: string; }; }; output: { success: boolean; }; outputFormat: "json"; status: 200; }; }; }, "/">, "/">; export type BookingGroupRoutes = typeof bookingGroupRoutes; export declare const __test__: { bookingGroupSchema: z.ZodObject<{ id: z.ZodString; kind: z.ZodEnum<{ other: "other"; shared_room: "shared_room"; cruise_party: "cruise_party"; }>; label: z.ZodString; primaryBookingId: z.ZodNullable; productId: z.ZodNullable; optionUnitId: z.ZodNullable; metadata: z.ZodNullable>; createdAt: z.ZodString; updatedAt: z.ZodString; }, z.core.$strip>; bookingGroupMemberSchema: z.ZodObject<{ id: z.ZodString; groupId: z.ZodString; bookingId: z.ZodString; role: z.ZodEnum<{ primary: "primary"; shared: "shared"; }>; createdAt: z.ZodString; }, z.core.$strip>; bookingGroupWithMembersSchema: z.ZodObject<{ id: z.ZodString; kind: z.ZodEnum<{ other: "other"; shared_room: "shared_room"; cruise_party: "cruise_party"; }>; label: z.ZodString; primaryBookingId: z.ZodNullable; productId: z.ZodNullable; optionUnitId: z.ZodNullable; metadata: z.ZodNullable>; createdAt: z.ZodString; updatedAt: z.ZodString; members: z.ZodArray; createdAt: z.ZodString; }, z.core.$strip>>; }, z.core.$strip>; }; export {};