import { signupVerify } from "@scandic-hotels/common/constants/routes/signup" import { createCounter } from "@scandic-hotels/common/telemetry" import { env } from "../../../env/server" import { router } from "../.." import * as api from "../../api" import { serverErrorByStatus } from "../../errors" import { protectedProcedure, serviceProcedure } from "../../procedures" import { addCreditCardInput, deleteCreditCardInput, saveCreditCardInput, signupInput, } from "./input" import { initiateSaveCardSchema, subscriberIdSchema } from "./output" export const userMutationRouter = router({ creditCard: router({ add: protectedProcedure.input(addCreditCardInput).mutation(async function ({ ctx, input, }) { console.info( "api.user.creditCard.add start", JSON.stringify({ query: { language: input.language } }) ) const apiResponse = await api.post( api.endpoints.v1.Profile.CreditCards.initiateSaveCard, { headers: { Authorization: `Bearer ${ctx.session.token.access_token}`, }, body: { language: input.language, mobileToken: false, redirectUrl: `api/web/add-card-callback/${input.language}`, }, } ) if (!apiResponse.ok) { const text = await apiResponse.text() console.error( "api.user.creditCard.add error", JSON.stringify({ query: { language: input.language }, error: { status: apiResponse.status, statusText: apiResponse.statusText, error: text, }, }) ) return null } const apiJson = await apiResponse.json() const verifiedData = initiateSaveCardSchema.safeParse(apiJson) if (!verifiedData.success) { console.error( "api.user.creditCard.add validation error", JSON.stringify({ query: { language: input.language }, error: verifiedData.error, }) ) return null } console.info( "api.user.creditCard.add success", JSON.stringify({ query: { language: input.language } }) ) return verifiedData.data.data }), save: protectedProcedure .input(saveCreditCardInput) .mutation(async function ({ ctx, input }) { console.info("api.user.creditCard.save start", JSON.stringify({})) const apiResponse = await api.post( api.endpoints.v1.Profile.CreditCards.transaction(input.transactionId), { headers: { Authorization: `Bearer ${ctx.session.token.access_token}`, }, } ) if (!apiResponse.ok) { const text = await apiResponse.text() console.error( "api.user.creditCard.save error", JSON.stringify({ error: { status: apiResponse.status, statusText: apiResponse.statusText, text, }, }) ) return false } console.info("api.user.creditCard.save success", JSON.stringify({})) return true }), delete: protectedProcedure .input(deleteCreditCardInput) .mutation(async function ({ ctx, input }) { console.info( "api.user.creditCard.delete start", JSON.stringify({ query: {} }) ) const apiResponse = await api.remove( api.endpoints.v1.Profile.CreditCards.deleteCreditCard( input.creditCardId ), { headers: { Authorization: `Bearer ${ctx.session.token.access_token}`, }, } ) if (!apiResponse.ok) { const text = await apiResponse.text() console.error( "api.user.creditCard.delete error", JSON.stringify({ error: { status: apiResponse.status, statusText: apiResponse.statusText, text, }, query: {}, }) ) return false } console.info("api.user.creditCard.delete success", JSON.stringify({})) return true }), }), generatePreferencesLink: protectedProcedure.mutation(async function ({ ctx, }) { const generatePreferencesLinkCounter = createCounter( "trpc.user", "generatePreferencesLink" ) const metricsGeneratePreferencesLink = generatePreferencesLinkCounter.init() metricsGeneratePreferencesLink.start() const apiResponse = await api.get(api.endpoints.v1.Profile.subscriberId, { headers: { Authorization: `Bearer ${ctx.session.token.access_token}`, }, }) if (!apiResponse.ok) { await metricsGeneratePreferencesLink.httpError(apiResponse) return null } const data = await apiResponse.json() const validatedData = subscriberIdSchema.safeParse(data) if (!validatedData.success) { metricsGeneratePreferencesLink.validationError(validatedData.error) return null } const preferencesLink = new URL(env.SALESFORCE_PREFERENCE_BASE_URL) preferencesLink.searchParams.set("subKey", validatedData.data.subscriberId) metricsGeneratePreferencesLink.success() return preferencesLink.toString() }), signup: serviceProcedure.input(signupInput).mutation(async function ({ ctx, input, }) { const signupCounter = createCounter("trpc.user", "signup") const metricsSignup = signupCounter.init() const apiResponse = await api.post(api.endpoints.v1.Profile.profile, { body: input, headers: { Authorization: `Bearer ${ctx.serviceToken}`, }, }) if (!apiResponse.ok) { await metricsSignup.httpError(apiResponse) const text = await apiResponse.text() throw serverErrorByStatus(apiResponse.status, text) } metricsSignup.success() return { success: true, redirectUrl: signupVerify[input.language], } }), })