Files
dticket.tootaio.com/server/api/public/bookings.post.ts
xiaomai 8541c4a2d1 feat(bookings): implement booking system and confirmation flow
Add database tables and repository for managing bookings
Create API endpoints for booking submission and capacity management
Update landing page to persist bookings before WhatsApp redirection
2026-04-12 21:43:30 +08:00

57 lines
2.0 KiB
TypeScript

import type { BookingMode, CreateBookingResponse, TicketType } from '~~/shared/booking'
import { getTicketCatalogItem, getSeatCount } from '~~/shared/booking'
import { buildAppUrl } from '../../utils/app-url'
import { createBooking } from '../../utils/booking-repository'
import { buildBookingMessage, parseCreateBookingInput } from '../../utils/bookings'
import { assertBadRequest } from '../../utils/http'
import { getPublicContactById } from '../../utils/user-repository'
export default defineEventHandler(async (event): Promise<CreateBookingResponse> => {
const body = await readBody<{
customerName?: string
customerPhone?: string
bookingMode?: BookingMode
quantity?: number
ticketType?: TicketType
personInChargeId?: string
}>(event)
const input = parseCreateBookingInput(body)
const personInCharge = await getPublicContactById(input.personInChargeId)
assertBadRequest(personInCharge, 'Selected person in charge is not available')
const ticket = getTicketCatalogItem(input.ticketType)
assertBadRequest(ticket, 'Ticket category is invalid')
const seatCount = getSeatCount(input.bookingMode, input.quantity)
const totalPrice = seatCount * ticket.price
const { booking, confirmationToken } = await createBooking({
customerName: input.customerName,
customerPhone: input.customerPhone,
bookingMode: input.bookingMode,
quantity: input.quantity,
seatCount,
ticketType: input.ticketType,
unitPrice: ticket.price,
totalPrice,
personInChargeId: personInCharge.id,
personInChargeName: personInCharge.fullName,
personInChargePhoneNumber: personInCharge.phoneNumber
})
const confirmationUrl = buildAppUrl(event, `/confirmation/${confirmationToken}`)
const whatsappMessage = buildBookingMessage(booking, confirmationUrl)
const whatsappUrl = `https://wa.me/${booking.personInChargePhoneNumber}?text=${encodeURIComponent(whatsappMessage)}`
return {
booking,
confirmationUrl,
whatsappUrl
}
})