Files
web/apps/scandic-web/server/routers/contentstack/reward/utils.ts
2025-04-23 22:40:46 +00:00

167 lines
4.0 KiB
TypeScript

import * as api from "@/lib/api"
import {
GetRewards as GetRewards,
GetRewardsRef as GetRewardsRef,
} from "@/lib/graphql/Query/RewardsWithRedeem.graphql"
import { request } from "@/lib/graphql/request"
import { notFound } from "@/server/errors/trpc"
import { createCounter } from "@/server/telemetry"
import { getCacheClient } from "@/services/dataCache"
import {
generateLoyaltyConfigTag,
generateRefsResponseTag,
} from "@/utils/generateTag"
import {
rewardRefsSchema,
validateApiAllTiersSchema,
validateCmsRewardsSchema,
} from "./output"
import type {
CMSRewardsResponse,
GetRewardRefsSchema,
} from "@/types/trpc/routers/contentstack/reward"
import type { Lang } from "@/constants/languages"
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.v1.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<GetRewardRefsSchema>(
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<CMSRewardsResponse>(
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
}