import { metrics } from "@opentelemetry/api" import { env } from "@/env/server" import * as api from "@/lib/api" import { initiateSaveCardSchema, subscriberIdSchema, } from "@/server/routers/user/output" import { protectedProcedure, router } from "@/server/trpc" import { addCreditCardInput, deleteCreditCardInput, saveCreditCardInput, } from "./input" const meter = metrics.getMeter("trpc.user") const generatePreferencesLinkCounter = meter.createCounter( "trpc.user.generatePreferencesLink" ) const generatePreferencesLinkSuccessCounter = meter.createCounter( "trpc.user.generatePreferencesLink-success" ) const generatePreferencesLinkFailCounter = meter.createCounter( "trpc.user.generatePreferencesLink-fail" ) 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.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.creditCards}/${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.creditCards}/${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, }) { generatePreferencesLinkCounter.add(1) const apiResponse = await api.get(api.endpoints.v1.subscriberId, { headers: { Authorization: `Bearer ${ctx.session.token.access_token}`, }, }) if (!apiResponse.ok) { const text = await apiResponse.text() generatePreferencesLinkFailCounter.add(1, { error_type: "http_error", error: JSON.stringify({ status: apiResponse.status, statusText: apiResponse.statusText, text, }), }) console.error( "api.user.subscriberId error ", JSON.stringify({ error: { status: apiResponse.status, statusText: apiResponse.statusText, text, }, }) ) return null } const data = await apiResponse.json() const validatedData = subscriberIdSchema.safeParse(data) if (!validatedData.success) { generatePreferencesLinkSuccessCounter.add(1, { error_type: "validation_error", error: JSON.stringify(validatedData.error), }) console.error( "api.user.generatePreferencesLink validation error", JSON.stringify({ error: validatedData.error, }) ) console.error(validatedData.error.format()) return null } const preferencesLink = new URL(env.SALESFORCE_PREFERENCE_BASE_URL) preferencesLink.searchParams.set("subKey", validatedData.data.subscriberId) generatePreferencesLinkSuccessCounter.add(1) return preferencesLink.toString() }), })