Files
Linus Flood 5fc93472f4 Merged in feat/rework-contentstack (pull request #3493)
Feat(SW-3708): refactor contentstack fetching (removing all refs) and cache invalidation

* Remove all REFS

* Revalidate correct language

* PR fixes

* PR fixes

* Throw when errors from contentstack api


Approved-by: Joakim Jäderberg
2026-01-27 12:38:36 +00:00

121 lines
3.1 KiB
TypeScript

import { getCacheClient } from "@scandic-hotels/common/dataCache"
import { createCounter } from "@scandic-hotels/common/telemetry"
import * as api from "../../../api"
import { notFoundError } from "../../../errors"
import { GetRewards } from "../../../graphql/Query/RewardsWithRedeem.graphql"
import { request } from "../../../graphql/request"
import { generateLoyaltyConfigTag } from "../../../utils/generateTag"
import { validateApiAllTiersSchema, validateCmsRewardsSchema } from "./output"
import type { Lang } from "@scandic-hotels/common/constants/language"
import type { CMSRewardsResponse } 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 getContentstackRewardAllCounter = createCounter(
"trpc.contentstack.reward.all"
)
const metricsGetContentstackRewardAll = getContentstackRewardAllCounter.init({
lang,
rewardIds,
})
metricsGetContentstackRewardAll.start()
const cmsRewardsResponse = await request<CMSRewardsResponse>(
GetRewards,
{
locale: lang,
rewardIds,
},
{
key: tags,
ttl: "max",
}
)
if (!cmsRewardsResponse.data) {
metricsGetContentstackRewardAll.noDataError()
throw notFoundError({
message: "GetRewards not found",
errorDetails: { lang, rewardIds },
})
}
const validatedCmsRewards =
validateCmsRewardsSchema.safeParse(cmsRewardsResponse)
if (!validatedCmsRewards.success) {
metricsGetContentstackRewardAll.validationError(validatedCmsRewards.error)
return null
}
metricsGetContentstackRewardAll.success()
return validatedCmsRewards.data
}