From f17406d34fd03749224af1b0840d33352c88a053 Mon Sep 17 00:00:00 2001 From: Linus Flood Date: Fri, 14 Mar 2025 14:38:38 +0000 Subject: [PATCH] Merged in fix/reward-remove-cache (pull request #1542) fix(reward): remove cache from profile service * fix(reward): remove cache from profile service Approved-by: Anton Gunnarsson --- .../routers/contentstack/reward/query.ts | 431 +++++++++--------- 1 file changed, 206 insertions(+), 225 deletions(-) diff --git a/apps/scandic-web/server/routers/contentstack/reward/query.ts b/apps/scandic-web/server/routers/contentstack/reward/query.ts index b4497d07d..5566db92c 100644 --- a/apps/scandic-web/server/routers/contentstack/reward/query.ts +++ b/apps/scandic-web/server/routers/contentstack/reward/query.ts @@ -10,8 +10,6 @@ import { } from "@/server/trpc" import { langInput } from "@/server/utils" -import { getCacheClient } from "@/services/dataCache" - import { getAllLoyaltyLevels, getLoyaltyLevel } from "../loyaltyLevel/query" import { rewardsAllInput, @@ -174,139 +172,129 @@ export const rewardQueryRouter = router({ ? api.endpoints.v1.Profile.Reward.reward : api.endpoints.v1.Profile.reward - const cacheClient = await getCacheClient() + const apiResponse = await api.get(endpoint, { + headers: { + Authorization: `Bearer ${ctx.session.token.access_token}`, + }, + }) - return cacheClient.cacheOrGet( - endpoint, - async () => { - const apiResponse = await api.get(endpoint, { - headers: { - Authorization: `Bearer ${ctx.session.token.access_token}`, + if (!apiResponse.ok) { + const text = await apiResponse.text() + getCurrentRewardFailCounter.add(1, { + error_type: "http_error", + error: JSON.stringify({ + status: apiResponse.status, + statusText: apiResponse.statusText, + text, + }), + }) + console.error( + "api.reward error ", + JSON.stringify({ + error: { + status: apiResponse.status, + statusText: apiResponse.statusText, + text, }, }) + ) + return null + } - if (!apiResponse.ok) { - const text = await apiResponse.text() - getCurrentRewardFailCounter.add(1, { - error_type: "http_error", - error: JSON.stringify({ - status: apiResponse.status, - statusText: apiResponse.statusText, - text, - }), - }) - console.error( - "api.reward error ", - JSON.stringify({ - error: { - status: apiResponse.status, - statusText: apiResponse.statusText, - text, - }, - }) - ) - return null - } + const data = await apiResponse.json() - const data = await apiResponse.json() + const validatedApiRewards = isNewEndpoint + ? validateCategorizedRewardsSchema.safeParse(data) + : validateApiRewardSchema.safeParse(data) - const validatedApiRewards = isNewEndpoint - ? validateCategorizedRewardsSchema.safeParse(data) - : validateApiRewardSchema.safeParse(data) + if (!validatedApiRewards.success) { + getCurrentRewardFailCounter.add(1, { + locale: ctx.lang, + error_type: "validation_error", + error: JSON.stringify(validatedApiRewards.error), + }) + console.error(validatedApiRewards.error) + console.error( + "contentstack.rewards validation error", + JSON.stringify({ + query: { locale: ctx.lang }, + error: validatedApiRewards.error, + }) + ) + return null + } - if (!validatedApiRewards.success) { - getCurrentRewardFailCounter.add(1, { - locale: ctx.lang, - error_type: "validation_error", - error: JSON.stringify(validatedApiRewards.error), - }) - console.error(validatedApiRewards.error) - console.error( - "contentstack.rewards validation error", - JSON.stringify({ - query: { locale: ctx.lang }, - error: validatedApiRewards.error, - }) - ) - return null - } + const rewardIds = getNonRedeemedRewardIds(validatedApiRewards.data) - const rewardIds = getNonRedeemedRewardIds(validatedApiRewards.data) + const cmsRewards = await getCmsRewards(ctx.lang, rewardIds) - const cmsRewards = await getCmsRewards(ctx.lang, rewardIds) + if (!cmsRewards) { + return null + } - if (!cmsRewards) { - return null - } + const wrappedSurprisesIds = validatedApiRewards.data + .filter( + (reward) => + reward.type === "coupon" && + reward.rewardType === "Surprise" && + "coupon" in reward && + reward.coupon.some(({ unwrapped }) => !unwrapped) + ) + .map(({ rewardId }) => rewardId) - const wrappedSurprisesIds = validatedApiRewards.data - .filter( - (reward) => - reward.type === "coupon" && - reward.rewardType === "Surprise" && - "coupon" in reward && - reward.coupon.some(({ unwrapped }) => !unwrapped) - ) - .map(({ rewardId }) => rewardId) + const rewards = cmsRewards + .filter( + (cmsReward) => !wrappedSurprisesIds.includes(cmsReward.reward_id) + ) + .map((cmsReward) => { + const apiReward = validatedApiRewards.data.find( + ({ rewardId }) => rewardId === cmsReward.reward_id + ) - const rewards = cmsRewards - .filter( - (cmsReward) => !wrappedSurprisesIds.includes(cmsReward.reward_id) - ) - .map((cmsReward) => { - const apiReward = validatedApiRewards.data.find( - ({ rewardId }) => rewardId === cmsReward.reward_id - ) + const redeemableCoupons = + (apiReward && + "coupon" in apiReward && + apiReward.coupon.filter( + (coupon) => coupon.state !== "redeemed" && coupon.unwrapped + )) || + [] - const redeemableCoupons = - (apiReward && - "coupon" in apiReward && - apiReward.coupon.filter( - (coupon) => coupon.state !== "redeemed" && coupon.unwrapped - )) || - [] - - const firstRedeemableCouponToExpire = redeemableCoupons.reduce( - (earliest, coupon) => { - if (dt(coupon.expiresAt).isBefore(dt(earliest.expiresAt))) { - return coupon - } - return earliest - }, - redeemableCoupons[0] - )?.couponCode - - return { - ...cmsReward, - id: apiReward?.id, - rewardType: apiReward?.rewardType, - redeemLocation: apiReward?.redeemLocation, - rewardTierLevel: - apiReward && "rewardTierLevel" in apiReward - ? apiReward.rewardTierLevel - : undefined, - operaRewardId: - apiReward && "operaRewardId" in apiReward - ? apiReward.operaRewardId - : "", - categories: - apiReward && "categories" in apiReward - ? apiReward.categories || [] - : [], - couponCode: firstRedeemableCouponToExpire, - coupons: - apiReward && "coupon" in apiReward - ? apiReward.coupon || [] - : [], + const firstRedeemableCouponToExpire = redeemableCoupons.reduce( + (earliest, coupon) => { + if (dt(coupon.expiresAt).isBefore(dt(earliest.expiresAt))) { + return coupon } - }) + return earliest + }, + redeemableCoupons[0] + )?.couponCode - getCurrentRewardSuccessCounter.add(1) + return { + ...cmsReward, + id: apiReward?.id, + rewardType: apiReward?.rewardType, + redeemLocation: apiReward?.redeemLocation, + rewardTierLevel: + apiReward && "rewardTierLevel" in apiReward + ? apiReward.rewardTierLevel + : undefined, + operaRewardId: + apiReward && "operaRewardId" in apiReward + ? apiReward.operaRewardId + : "", + categories: + apiReward && "categories" in apiReward + ? apiReward.categories || [] + : [], + couponCode: firstRedeemableCouponToExpire, + coupons: + apiReward && "coupon" in apiReward ? apiReward.coupon || [] : [], + } + }) - return { rewards } - }, - "1h" - ) + getCurrentRewardSuccessCounter.add(1) + + return { rewards } }), surprises: contentStackBaseWithProtectedProcedure .input(langInput.optional()) // lang is required for client, but not for server @@ -318,120 +306,113 @@ export const rewardQueryRouter = router({ ? api.endpoints.v1.Profile.Reward.reward : api.endpoints.v1.Profile.reward - const cacheClient = await getCacheClient() - return await cacheClient.cacheOrGet( - endpoint, - async () => { - const apiResponse = await api.get(endpoint, { - cache: undefined, - headers: { - Authorization: `Bearer ${ctx.session.token.access_token}`, + const apiResponse = await api.get(endpoint, { + cache: undefined, + headers: { + Authorization: `Bearer ${ctx.session.token.access_token}`, + }, + }) + + if (!apiResponse.ok) { + const text = await apiResponse.text() + getCurrentRewardFailCounter.add(1, { + error_type: "http_error", + error: JSON.stringify({ + status: apiResponse.status, + statusText: apiResponse.statusText, + text, + }), + }) + console.error( + "api.reward error ", + JSON.stringify({ + error: { + status: apiResponse.status, + statusText: apiResponse.statusText, + text, }, }) + ) + return null + } - if (!apiResponse.ok) { - const text = await apiResponse.text() - getCurrentRewardFailCounter.add(1, { - error_type: "http_error", - error: JSON.stringify({ - status: apiResponse.status, - statusText: apiResponse.statusText, - text, - }), - }) - console.error( - "api.reward error ", - JSON.stringify({ - error: { - status: apiResponse.status, - statusText: apiResponse.statusText, - text, - }, - }) - ) + const data = await apiResponse.json() + const validatedApiRewards = isNewEndpoint + ? validateCategorizedRewardsSchema.safeParse(data) + : validateApiRewardSchema.safeParse(data) + + if (!validatedApiRewards.success) { + getCurrentRewardFailCounter.add(1, { + locale: ctx.lang, + error_type: "validation_error", + error: JSON.stringify(validatedApiRewards.error), + }) + console.error(validatedApiRewards.error) + console.error( + "contentstack.surprises validation error", + JSON.stringify({ + query: { locale: ctx.lang }, + error: validatedApiRewards.error, + }) + ) + return null + } + + const rewardIds = validatedApiRewards.data + .map((reward) => reward?.rewardId) + .filter((rewardId): rewardId is string => !!rewardId) + .sort() + + const cmsRewards = await getCmsRewards(ctx.lang, rewardIds) + + if (!cmsRewards) { + return null + } + + getCurrentRewardSuccessCounter.add(1) + + const surprises: Surprise[] = validatedApiRewards.data + // TODO: Add predicates once legacy endpoints are removed + .filter((reward) => { + if (reward?.rewardType !== "Surprise") { + return false + } + + if (!("coupon" in reward)) { + return false + } + + const unwrappedCoupons = + reward.coupon.filter((coupon) => !coupon.unwrapped) || [] + if (unwrappedCoupons.length === 0) { + return false + } + + return true + }) + .map((surprise) => { + const reward = cmsRewards.find( + ({ reward_id }) => surprise.rewardId === reward_id + ) + + if (!reward) { return null } - const data = await apiResponse.json() - const validatedApiRewards = isNewEndpoint - ? validateCategorizedRewardsSchema.safeParse(data) - : validateApiRewardSchema.safeParse(data) - - if (!validatedApiRewards.success) { - getCurrentRewardFailCounter.add(1, { - locale: ctx.lang, - error_type: "validation_error", - error: JSON.stringify(validatedApiRewards.error), - }) - console.error(validatedApiRewards.error) - console.error( - "contentstack.surprises validation error", - JSON.stringify({ - query: { locale: ctx.lang }, - error: validatedApiRewards.error, - }) - ) - return null + return { + ...reward, + id: surprise.id, + rewardType: surprise.rewardType, + rewardTierLevel: undefined, + redeemLocation: surprise.redeemLocation, + coupons: "coupon" in surprise ? surprise.coupon || [] : [], + categories: + "categories" in surprise ? surprise.categories || [] : [], } + }) + .flatMap((surprises) => (surprises ? [surprises] : [])) - const rewardIds = validatedApiRewards.data - .map((reward) => reward?.rewardId) - .filter((rewardId): rewardId is string => !!rewardId) - .sort() - - const cmsRewards = await getCmsRewards(ctx.lang, rewardIds) - - if (!cmsRewards) { - return null - } - - getCurrentRewardSuccessCounter.add(1) - - const surprises: Surprise[] = validatedApiRewards.data - // TODO: Add predicates once legacy endpoints are removed - .filter((reward) => { - if (reward?.rewardType !== "Surprise") { - return false - } - - if (!("coupon" in reward)) { - return false - } - - const unwrappedCoupons = - reward.coupon.filter((coupon) => !coupon.unwrapped) || [] - if (unwrappedCoupons.length === 0) { - return false - } - - return true - }) - .map((surprise) => { - const reward = cmsRewards.find( - ({ reward_id }) => surprise.rewardId === reward_id - ) - - if (!reward) { - return null - } - - return { - ...reward, - id: surprise.id, - rewardType: surprise.rewardType, - rewardTierLevel: undefined, - redeemLocation: surprise.redeemLocation, - coupons: "coupon" in surprise ? surprise.coupon || [] : [], - categories: - "categories" in surprise ? surprise.categories || [] : [], - } - }) - .flatMap((surprises) => (surprises ? [surprises] : [])) - - return surprises - }, - "1h" - ) + return surprises }), unwrap: protectedProcedure .input(rewardsUpdateInput)