import { metrics } from "@opentelemetry/api" import * as api from "@/lib/api" import { badRequestError, serverErrorByStatus } from "@/server/errors/trpc" import { router, serviceProcedure } from "@/server/trpc" import { bookingConfirmationInput, getBookingStatusInput } from "./input" import { bookingConfirmationSchema, createBookingSchema } from "./output" const meter = metrics.getMeter("trpc.booking") const getBookingConfirmationCounter = meter.createCounter( "trpc.booking.confirmation" ) const getBookingConfirmationSuccessCounter = meter.createCounter( "trpc.booking.confirmation-success" ) const getBookingConfirmationFailCounter = meter.createCounter( "trpc.booking.confirmation-fail" ) const getBookingStatusCounter = meter.createCounter("trpc.booking.status") const getBookingStatusSuccessCounter = meter.createCounter( "trpc.booking.status-success" ) const getBookingStatusFailCounter = meter.createCounter( "trpc.booking.status-fail" ) export const bookingQueryRouter = router({ confirmation: serviceProcedure .input(bookingConfirmationInput) .query(async function ({ ctx, input: { confirmationNumber } }) { getBookingConfirmationCounter.add(1, { confirmationNumber }) const apiResponse = await api.get( `${api.endpoints.v1.booking}/${confirmationNumber}`, { headers: { Authorization: `Bearer ${ctx.serviceToken}`, }, } ) if (!apiResponse.ok) { const responseMessage = await apiResponse.text() getBookingConfirmationFailCounter.add(1, { confirmationNumber, error_type: "http_error", error: responseMessage, }) console.error( "api.booking.confirmation error", JSON.stringify({ query: { confirmationNumber }, error: { status: apiResponse.status, statusText: apiResponse.statusText, text: responseMessage, }, }) ) throw serverErrorByStatus(apiResponse.status, apiResponse) } const apiJson = await apiResponse.json() const booking = bookingConfirmationSchema.safeParse(apiJson) if (!booking.success) { getBookingConfirmationFailCounter.add(1, { confirmationNumber, error_type: "validation_error", error: JSON.stringify(booking.error), }) console.error( "api.booking.confirmation validation error", JSON.stringify({ query: { confirmationNumber }, error: booking.error, }) ) throw badRequestError() } getBookingConfirmationSuccessCounter.add(1, { confirmationNumber }) console.info( "api.booking.confirmation success", JSON.stringify({ query: { confirmationNumber }, }) ) return { ...booking.data, temp: { breakfastFrom: "06:30", breakfastTo: "11:00", cancelPolicy: "Free rebooking", fromDate: "2024-10-21 14:00", packages: [ { name: "Breakfast buffet", price: "150 SEK", }, { name: "Member discount", price: "-297 SEK", }, { name: "Points used / remaining", price: "0 / 1044", }, ], payment: "2024-08-09 1:47", room: { price: "2 589 SEK", type: "Cozy Cabin", vat: "684,79 SEK", }, toDate: "2024-10-22 11:00", total: "2 739 SEK", totalInEuro: "265 EUR", }, guest: { email: "sarah.obrian@gmail.com", firstName: "Sarah", lastName: "O'Brian", memberbershipNumber: "19822", phoneNumber: "+46702446688", }, hotel: { email: "bookings@scandichotels.com", name: "Downtown Camper by Scandic", phoneNumber: "+4689001350", }, } }), status: serviceProcedure.input(getBookingStatusInput).query(async function ({ ctx, input, }) { const { confirmationNumber } = input getBookingStatusCounter.add(1, { confirmationNumber }) const apiResponse = await api.get( `${api.endpoints.v1.booking}/${confirmationNumber}/status`, { headers: { Authorization: `Bearer ${ctx.serviceToken}`, }, } ) if (!apiResponse.ok) { const responseMessage = await apiResponse.text() getBookingStatusFailCounter.add(1, { confirmationNumber, error_type: "http_error", error: responseMessage, }) console.error( "api.booking.status error", JSON.stringify({ query: { confirmationNumber }, error: { status: apiResponse.status, statusText: apiResponse.statusText, text: responseMessage, }, }) ) throw serverErrorByStatus(apiResponse.status, apiResponse) } const apiJson = await apiResponse.json() const verifiedData = createBookingSchema.safeParse(apiJson) if (!verifiedData.success) { getBookingStatusFailCounter.add(1, { confirmationNumber, error_type: "validation_error", error: JSON.stringify(verifiedData.error), }) console.error( "api.booking.status validation error", JSON.stringify({ query: { confirmationNumber }, error: verifiedData.error, }) ) throw badRequestError() } getBookingStatusSuccessCounter.add(1, { confirmationNumber }) console.info( "api.booking.status success", JSON.stringify({ query: { confirmationNumber }, }) ) return verifiedData.data }), })