import { createCounter } from "@scandic-hotels/common/telemetry" import * as api from "../../api" import { badRequestError, serverErrorByStatus } from "../../errors" import { toApiLang } from "../../utils" import { createBookingSchema } from "./mutation/create/schema" import { bookingConfirmationSchema } from "./output" import type { Lang } from "@scandic-hotels/common/constants/language" export async function getBooking( confirmationNumber: string, lang: Lang, token: string ) { const getBookingCounter = createCounter("booking", "get") const metricsGetBooking = getBookingCounter.init({ confirmationNumber }) metricsGetBooking.start() const apiResponse = await api.get( api.endpoints.v1.Booking.booking(confirmationNumber), { headers: { Authorization: `Bearer ${token}`, }, }, { language: toApiLang(lang) } ) if (!apiResponse.ok) { await metricsGetBooking.httpError(apiResponse) // If the booking is not found, return null. // This scenario is expected to happen when a logged in user trying to access a booking that doesn't belong to them. if (apiResponse.status === 404) { return null } throw serverErrorByStatus(apiResponse.status, apiResponse) } const apiJson = await apiResponse.json() const booking = bookingConfirmationSchema.safeParse(apiJson) if (!booking.success) { metricsGetBooking.validationError(booking.error) throw badRequestError() } metricsGetBooking.success() return booking.data } export async function findBooking( confirmationNumber: string, lang: Lang, token: string, lastName?: string, firstName?: string, email?: string ) { const findBookingCounter = createCounter("booking", "find") const metricsGetBooking = findBookingCounter.init({ confirmationNumber, lastName, firstName, email, }) metricsGetBooking.start() const apiResponse = await api.post( api.endpoints.v1.Booking.find(confirmationNumber), { headers: { Authorization: `Bearer ${token}`, }, body: { lastName, firstName, email, }, }, { language: toApiLang(lang) } ) if (!apiResponse.ok) { await metricsGetBooking.httpError(apiResponse) // If the booking is not found, return null. // This scenario is expected to happen when a logged in user trying to access a booking that doesn't belong to them. if (apiResponse.status === 400) { return null } throw serverErrorByStatus(apiResponse.status, apiResponse) } const apiJson = await apiResponse.json() const booking = bookingConfirmationSchema.safeParse(apiJson) if (!booking.success) { metricsGetBooking.validationError(booking.error) throw badRequestError() } metricsGetBooking.success() return booking.data } export async function cancelBooking( confirmationNumber: string, language: Lang, token: string ) { const cancelBookingCounter = createCounter("booking", "cancel") const metricsCancelBooking = cancelBookingCounter.init({ confirmationNumber, language, }) metricsCancelBooking.start() const headers = { Authorization: `Bearer ${token}`, } const booking = await getBooking(confirmationNumber, language, token) if (!booking) { metricsCancelBooking.noDataError({ confirmationNumber }) return null } const { firstName, lastName, email } = booking.guest const apiResponse = await api.remove( api.endpoints.v1.Booking.cancel(confirmationNumber), { headers, body: { firstName, lastName, email }, }, { language: toApiLang(language) } ) if (!apiResponse.ok) { await metricsCancelBooking.httpError(apiResponse) return null } const apiJson = await apiResponse.json() const verifiedData = createBookingSchema.safeParse(apiJson) if (!verifiedData.success) { metricsCancelBooking.validationError(verifiedData.error) return null } metricsCancelBooking.success() return verifiedData.data }