refactor(LOY-175): rewrite reward types according to new api endpoints

This commit is contained in:
Christian Andolf
2025-03-11 16:09:15 +01:00
parent 0ae4c5db17
commit b86347b4f4
15 changed files with 196 additions and 246 deletions

View File

@@ -1,5 +1,4 @@
import * as api from "@/lib/api"
import { dt } from "@/lib/dt"
import { notFound } from "@/server/errors/trpc"
import {
contentStackBaseWithProtectedProcedure,
@@ -9,6 +8,8 @@ import {
} from "@/server/trpc"
import { langInput } from "@/server/utils"
import { getReedemableCoupons } from "@/utils/rewards"
import { getAllLoyaltyLevels, getLoyaltyLevel } from "../loyaltyLevel/query"
import {
rewardsAllInput,
@@ -16,11 +17,7 @@ import {
rewardsRedeemInput,
rewardsUpdateInput,
} from "./input"
import {
type Reward,
type Surprise,
validateCategorizedRewardsSchema,
} from "./output"
import { type Surprise, validateCategorizedRewardsSchema } from "./output"
import {
getAllRewardCounter,
getAllRewardFailCounter,
@@ -33,7 +30,6 @@ import {
getCurrentRewardCounter,
getCurrentRewardFailCounter,
getCurrentRewardSuccessCounter,
getNonRedeemedRewardIds,
getRedeemCounter,
getRedeemFailCounter,
getRedeemSuccessCounter,
@@ -41,8 +37,16 @@ import {
getUnwrapSurpriseCounter,
getUnwrapSurpriseFailCounter,
getUnwrapSurpriseSuccessCounter,
isSurpriseReward,
} from "./utils"
import type {
Reward,
RewardWithRedeem,
} from "@/types/components/myPages/rewards"
const ONE_HOUR = 60 * 60
export const rewardQueryRouter = router({
all: contentStackBaseWithServiceProcedure
.input(rewardsAllInput)
@@ -215,71 +219,37 @@ export const rewardQueryRouter = router({
return null
}
const rewardIds = getNonRedeemedRewardIds(validatedApiRewards.data)
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
}
const wrappedSurprisesIds = validatedApiRewards.data
const rewards: Array<Reward | RewardWithRedeem> = cmsRewards
.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)
(cmsReward) =>
// filters out any rewards tied to wrapped surprises
!validatedApiRewards.data
.filter(isSurpriseReward)
.filter((reward) =>
reward.coupon.some(({ unwrapped }) => !unwrapped)
)
.map(({ rewardId }) => rewardId)
.includes(cmsReward.reward_id)
)
.map((cmsReward) => {
// Non-null assertion is used here because we know our reward exist
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 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 || [] : [],
data: apiReward,
}
})
@@ -346,12 +316,11 @@ export const rewardQueryRouter = router({
}
const rewardIds = validatedApiRewards.data
.map((reward) => reward?.rewardId)
.filter((reward) => getReedemableCoupons(reward).length)
.map((reward) => reward.rewardId)
.filter((rewardId): rewardId is string => !!rewardId)
.sort()
const cmsRewards = await getCmsRewards(ctx.lang, rewardIds)
if (!cmsRewards) {
return null
}
@@ -359,42 +328,25 @@ export const rewardQueryRouter = router({
getCurrentRewardSuccessCounter.add(1)
const surprises: Surprise[] = validatedApiRewards.data
// TODO: Add predicates once legacy endpoints are removed
.filter(isSurpriseReward)
.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
return unwrappedCoupons.length
})
.map((surprise) => {
const reward = cmsRewards.find(
const cmsReward = cmsRewards.find(
({ reward_id }) => surprise.rewardId === reward_id
)
if (!reward) {
if (!cmsReward) {
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 || [] : [],
...cmsReward,
data: surprise,
}
})
.flatMap((surprises) => (surprises ? [surprises] : []))