import { getCacheClient } from "@scandic-hotels/common/dataCache" import { createCounter } from "@scandic-hotels/common/telemetry" import * as api from "../../../api" import { notFound } from "../../../errors" import { GetRewards as GetRewards, GetRewardsRef as GetRewardsRef, } from "../../../graphql/Query/RewardsWithRedeem.graphql" import { request } from "../../../graphql/request" import { generateLoyaltyConfigTag, generateRefsResponseTag, } from "../../../utils/generateTag" import { rewardRefsSchema, validateApiAllTiersSchema, validateCmsRewardsSchema, } from "./output" import type { Lang } from "@scandic-hotels/common/constants/language" import type { CMSRewardsResponse, GetRewardRefsSchema, } from "../../../types/reward" export function getUniqueRewardIds(rewardIds: string[]) { const uniqueRewardIds = new Set(rewardIds) return Array.from(uniqueRewardIds) } /** * Cached for 1 hour. */ export async function getCachedAllTierRewards(token: string) { const cacheClient = await getCacheClient() return await cacheClient.cacheOrGet( "getAllTierRewards", async () => { const getApiRewardAllTiersCounter = createCounter( "trpc.api.reward.allTiers" ) const metricsGetApiRewardAllTiers = getApiRewardAllTiersCounter.init() metricsGetApiRewardAllTiers.start() const apiResponse = await api.get( api.endpoints.v2.Profile.Reward.allTiers, { headers: { Authorization: `Bearer ${token}`, }, } ) if (!apiResponse.ok) { metricsGetApiRewardAllTiers.httpError(apiResponse) throw apiResponse } const data = await apiResponse.json() const validatedApiAllTierRewards = validateApiAllTiersSchema.safeParse(data) if (!validatedApiAllTierRewards.success) { metricsGetApiRewardAllTiers.validationError( validatedApiAllTierRewards.error ) throw validatedApiAllTierRewards.error } metricsGetApiRewardAllTiers.success() return validatedApiAllTierRewards.data }, "1h" ) } export async function getCmsRewards(lang: Lang, rewardIds: string[]) { if (!rewardIds.length) { return null } const tags = rewardIds.map((id) => generateLoyaltyConfigTag(lang, "reward", id) ) const getContentstackRewardAllRefsCounter = createCounter( "trpc.contentstack.reward.all.refs" ) const metricsGetContentstackRewardAllRefs = getContentstackRewardAllRefsCounter.init({ lang, rewardIds }) metricsGetContentstackRewardAllRefs.start() const refsResponse = await request( GetRewardsRef, { locale: lang, rewardIds, }, { key: rewardIds.map((rewardId) => generateRefsResponseTag(lang, rewardId)), ttl: "max", } ) if (!refsResponse.data) { const notFoundError = notFound(refsResponse) metricsGetContentstackRewardAllRefs.noDataError() throw notFoundError } const validatedRefsData = rewardRefsSchema.safeParse(refsResponse) if (!validatedRefsData.success) { metricsGetContentstackRewardAllRefs.validationError(validatedRefsData.error) return null } metricsGetContentstackRewardAllRefs.success() const getContentstackRewardAllCounter = createCounter( "trpc.contentstack.reward.all" ) const metricsGetContentstackRewardAll = getContentstackRewardAllCounter.init({ lang, rewardIds, }) const cmsRewardsResponse = await request( GetRewards, { locale: lang, rewardIds, }, { key: tags, ttl: "max", } ) if (!cmsRewardsResponse.data) { const notFoundError = notFound(cmsRewardsResponse) metricsGetContentstackRewardAll.noDataError() throw notFoundError } const validatedCmsRewards = validateCmsRewardsSchema.safeParse(cmsRewardsResponse) if (!validatedCmsRewards.success) { metricsGetContentstackRewardAll.validationError(validatedCmsRewards.error) return null } metricsGetContentstackRewardAll.success() return validatedCmsRewards.data }