feat(reservations): assign trip members and guests to bookings — backend (schema, migration, travelers endpoint)

This commit is contained in:
Maurice
2026-07-24 13:50:14 +02:00
committed by Maurice
parent 9344d4508c
commit 21456b983e
5 changed files with 132 additions and 0 deletions
@@ -34,6 +34,20 @@ export const reservationEndpointSchema = z.object({
});
export type ReservationEndpoint = z.infer<typeof reservationEndpointSchema>;
/**
* A traveler assigned to a reservation — a trip member or a named guest (both are
* `users` rows; a guest carries is_guest=1). Mirrors the budget member read shape
* without the cost-split fields; joined + avatar-resolved in reservationService.
*/
export const reservationTravelerSchema = z.object({
user_id: z.number(),
username: z.string(),
avatar_url: z.string().nullable().optional(),
avatar: z.string().nullable().optional(),
is_guest: z.number().nullable().optional(),
});
export type ReservationTraveler = z.infer<typeof reservationTravelerSchema>;
/**
* Endpoints as accepted on a WRITE (create/update body `endpoints` array). This
* pins the STRUCTURE (role must be a known value, name/code are strings) so a
@@ -102,6 +116,8 @@ export const reservationSchema = z.object({
accommodation_end_day_id: z.number().nullable().optional(),
day_positions: z.record(z.string(), z.number()).nullable().optional(),
endpoints: z.array(reservationEndpointSchema).optional(),
// Trip members / named guests this booking is for (#1517). Joined in listReservations.
travelers: z.array(reservationTravelerSchema).optional(),
});
export type Reservation = z.infer<typeof reservationSchema>;
@@ -139,6 +155,12 @@ export type ReservationCreateRequest = z.infer<typeof reservationCreateRequestSc
export const reservationUpdateRequestSchema = open;
export type ReservationUpdateRequest = z.infer<typeof reservationUpdateRequestSchema>;
/** Assign trip members/guests to a reservation (mirrors budget's PUT :id/members). */
export const reservationTravelersRequestSchema = z.object({
user_ids: z.array(z.number()),
});
export type ReservationTravelersRequest = z.infer<typeof reservationTravelersRequestSchema>;
export const reservationPositionsRequestSchema = z.object({
positions: z.array(z.object({ id: z.number(), day_plan_position: z.number() })),
day_id: z.union([z.number(), z.string()]).nullable().optional(),