import { metrics } from "@opentelemetry/api" import * as api from "@/lib/api" import { getVerifiedUser } from "@/server/routers/user/query" import { router, serviceProcedure } from "@/server/trpc" import { getMembership } from "@/utils/user" import { createBookingInput } from "./input" import { createBookingSchema } from "./output" import type { Session } from "next-auth" const meter = metrics.getMeter("trpc.bookings") const createBookingCounter = meter.createCounter("trpc.bookings.create") const createBookingSuccessCounter = meter.createCounter( "trpc.bookings.create-success" ) const createBookingFailCounter = meter.createCounter( "trpc.bookings.create-fail" ) async function getMembershipNumber( session: Session | null ): Promise { if (!session) return undefined const verifiedUser = await getVerifiedUser({ session }) if (!verifiedUser || "error" in verifiedUser) { return undefined } const membership = getMembership(verifiedUser.data.memberships) return membership?.membershipNumber } export const bookingMutationRouter = router({ create: serviceProcedure.input(createBookingInput).mutation(async function ({ ctx, input, }) { const { checkInDate, checkOutDate, hotelId } = input // TODO: add support for user token OR service token in procedure // then we can fetch membership number if user token exists const loggingAttributes = { // membershipNumber: await getMembershipNumber(ctx.session), checkInDate, checkOutDate, hotelId, } createBookingCounter.add(1, { hotelId, checkInDate, checkOutDate }) console.info( "api.booking.create start", JSON.stringify({ query: loggingAttributes, }) ) const headers = { Authorization: `Bearer ${ctx.serviceToken}`, } const apiResponse = await api.post(api.endpoints.v1.Booking.bookings, { headers, body: input, }) if (!apiResponse.ok) { const text = await apiResponse.text() createBookingFailCounter.add(1, { hotelId, checkInDate, checkOutDate, error_type: "http_error", error: JSON.stringify({ status: apiResponse.status, }), }) console.error( "api.booking.create error", JSON.stringify({ query: loggingAttributes, error: { status: apiResponse.status, statusText: apiResponse.statusText, error: text, }, }) ) return null } const apiJson = await apiResponse.json() const verifiedData = createBookingSchema.safeParse(apiJson) if (!verifiedData.success) { createBookingFailCounter.add(1, { hotelId, checkInDate, checkOutDate, error_type: "validation_error", }) console.error( "api.booking.create validation error", JSON.stringify({ query: loggingAttributes, error: verifiedData.error, }) ) return null } createBookingSuccessCounter.add(1, { hotelId, checkInDate, checkOutDate, }) console.info( "api.booking.create success", JSON.stringify({ query: loggingAttributes, }) ) return verifiedData.data }), })