Merged in feat/booking-flow-submit (pull request #580)
This implements the actual call to the API to create a booking. That’s the only thing it does, it doesn’t handle the response in any way. This PR is just to get it there and the new booking sub team will handle it further, with payment etc. Approved-by: Michael Zetterberg Approved-by: Fredrik Thorsson Approved-by: Simon.Emanuelsson
This commit is contained in:
129
server/routers/booking/mutation.ts
Normal file
129
server/routers/booking/mutation.ts
Normal file
@@ -0,0 +1,129 @@
|
||||
import { metrics } from "@opentelemetry/api"
|
||||
|
||||
import * as api from "@/lib/api"
|
||||
import { getVerifiedUser } from "@/server/routers/user/query"
|
||||
import { router, safeProtectedProcedure } 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<string | undefined> {
|
||||
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({
|
||||
booking: router({
|
||||
create: safeProtectedProcedure
|
||||
.input(createBookingInput)
|
||||
.mutation(async function ({ ctx, input }) {
|
||||
const { checkInDate, checkOutDate, hotelId } = input
|
||||
|
||||
const loggingAttributes = {
|
||||
membershipNumber: await getMembershipNumber(ctx.session),
|
||||
checkInDate,
|
||||
checkOutDate,
|
||||
hotelId,
|
||||
}
|
||||
|
||||
createBookingCounter.add(1, { hotelId, checkInDate, checkOutDate })
|
||||
|
||||
console.info(
|
||||
"api.booking.booking.create start",
|
||||
JSON.stringify({
|
||||
query: loggingAttributes,
|
||||
})
|
||||
)
|
||||
const headers = ctx.session
|
||||
? {
|
||||
Authorization: `Bearer ${ctx.session?.token.access_token}`,
|
||||
}
|
||||
: undefined
|
||||
const apiResponse = await api.post(api.endpoints.v1.booking, {
|
||||
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.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.booking.create validation error",
|
||||
JSON.stringify({
|
||||
query: loggingAttributes,
|
||||
error: verifiedData.error,
|
||||
})
|
||||
)
|
||||
return null
|
||||
}
|
||||
|
||||
createBookingSuccessCounter.add(1, {
|
||||
hotelId,
|
||||
checkInDate,
|
||||
checkOutDate,
|
||||
})
|
||||
|
||||
console.info(
|
||||
"api.booking.booking.create success",
|
||||
JSON.stringify({
|
||||
query: loggingAttributes,
|
||||
})
|
||||
)
|
||||
return verifiedData.data
|
||||
}),
|
||||
}),
|
||||
})
|
||||
Reference in New Issue
Block a user