chore(LOY-175): remove references to old reward endpoints

This commit is contained in:
Christian Andolf
2025-03-10 13:35:07 +01:00
parent 4ff44311a9
commit 0ae4c5db17
8 changed files with 13 additions and 193 deletions

View File

@@ -60,6 +60,5 @@ ENABLE_BOOKING_WIDGET_HOTELRESERVATION_PATH="false"
SHOW_SITE_WIDE_ALERT="false"
SHOW_SIGNUP_FLOW="true"
USE_NEW_REWARDS_ENDPOINT="true"
USE_NEW_REWARD_MODEL="true"

View File

@@ -43,7 +43,6 @@ GOOGLE_STATIC_MAP_ID="test"
GOOGLE_DYNAMIC_MAP_ID="test"
NEXT_PUBLIC_HIDE_FOR_NEXT_RELEASE="true"
SALESFORCE_PREFERENCE_BASE_URL="test"
USE_NEW_REWARDS_ENDPOINT="true"
USE_NEW_REWARD_MODEL="true"
TZ=UTC
@@ -54,4 +53,4 @@ SHOW_SITE_WIDE_ALERT="false"
NEXT_PUBLIC_SENTRY_ENVIRONMENT="test"
NEXT_PUBLIC_SENTRY_CLIENT_SAMPLERATE="0"
SITEMAP_SYNC_SECRET="test
SITEMAP_SYNC_SECRET="test

View File

@@ -31,7 +31,7 @@ export default async function CurrentRewardsBlock({
<SectionHeader title={title} link={link} preamble={subtitle} />
<ClientCurrentRewards
rewards={rewardsResponse.rewards}
showRedeem={env.USE_NEW_REWARDS_ENDPOINT && env.USE_NEW_REWARD_MODEL}
showRedeem={env.USE_NEW_REWARD_MODEL}
membershipNumber={membershipLevel?.membershipNumber}
/>
<SectionLink link={link} variant="mobile" />

View File

@@ -141,13 +141,6 @@ export const env = createEnv({
// transform to boolean
.transform((s) => s === "true")
.default("false"),
USE_NEW_REWARDS_ENDPOINT: z
.string()
// only allow "true" or "false"
.refine((s) => s === "true" || s === "false")
// transform to boolean
.transform((s) => s === "true")
.default("false"),
USE_NEW_REWARD_MODEL: z
.string()
// only allow "true" or "false"
@@ -268,7 +261,6 @@ export const env = createEnv({
GOOGLE_STATIC_MAP_ID: process.env.GOOGLE_STATIC_MAP_ID,
GOOGLE_DYNAMIC_MAP_ID: process.env.GOOGLE_DYNAMIC_MAP_ID,
HIDE_FOR_NEXT_RELEASE: process.env.NEXT_PUBLIC_HIDE_FOR_NEXT_RELEASE,
USE_NEW_REWARDS_ENDPOINT: process.env.USE_NEW_REWARDS_ENDPOINT,
USE_NEW_REWARD_MODEL: process.env.USE_NEW_REWARD_MODEL,
ENABLE_BOOKING_FLOW: process.env.ENABLE_BOOKING_FLOW,
ENABLE_BOOKING_WIDGET: process.env.ENABLE_BOOKING_WIDGET,

View File

@@ -171,10 +171,6 @@ export namespace endpoints {
export const unlink = `${base.path.profile}/${version}/${base.enitity.Profile}/Unlink`
export const matchTier = `${base.path.profile}/${version}/${base.enitity.Profile}/MatchTier`
// TODO: Remove once new endpoints are out in production.
export const reward = `${base.path.profile}/${version}/${base.enitity.Profile}/reward`
export const tierRewards = `${base.path.profile}/${version}/${base.enitity.Profile}/tierRewards`
export function deleteProfile(profileId: string) {
return `${profile}/${profileId}`
}

View File

@@ -12,66 +12,6 @@ import { systemSchema } from "../schemas/system"
import type { RewardCategory } from "@/types/components/myPages/rewards"
const Coupon = z.object({
code: z.string().optional(),
status: z.string().optional(),
createdAt: z.string().datetime({ offset: true }).optional(),
customer: z.object({
id: z.string().optional(),
}),
name: z.string().optional(),
claimedAt: z.string().datetime({ offset: true }).optional(),
redeemedAt: z
.date({ coerce: true })
.optional()
.transform((value) => {
if (value?.getFullYear() === 1) {
return null
}
return value
}),
type: z.string().optional(),
value: z.number().optional(),
pool: z.string().optional(),
cfUnwrapped: z.boolean().default(false),
})
const SurpriseReward = z.object({
title: z.string().optional(),
id: z.string().optional(),
type: z.literal("coupon"),
status: z.string().optional(),
rewardId: z.string().optional(),
redeemLocation: z.string().optional(),
autoApplyReward: z.boolean().default(false),
rewardType: z.string().optional(),
endsAt: z.string().datetime({ offset: true }).optional(),
coupons: z.array(Coupon).optional(),
operaRewardId: z.string().default(""),
})
export const validateApiRewardSchema = z
.object({
data: z.array(
z.discriminatedUnion("type", [
z.object({
title: z.string().optional(),
id: z.string().optional(),
type: z.literal("custom"),
status: z.string().optional(),
rewardId: z.string().optional(),
redeemLocation: z.string().optional(),
autoApplyReward: z.boolean().default(false),
rewardType: z.string().optional(),
rewardTierLevel: z.string().optional(),
operaRewardId: z.string().default(""),
}),
SurpriseReward,
])
),
})
.transform((data) => data.data)
enum TierKey {
tier1 = MembershipLevelEnum.L1,
tier2 = MembershipLevelEnum.L2,
@@ -84,26 +24,6 @@ enum TierKey {
type Key = keyof typeof TierKey
export const validateApiTierRewardsSchema = z.record(
z.nativeEnum(TierKey).transform((data) => {
return TierKey[data as unknown as Key]
}),
z.array(
z.object({
title: z.string().optional(),
id: z.string().optional(),
type: z.string().optional(),
status: z.string().optional(),
rewardId: z.string().optional(),
redeemLocation: z.string().optional(),
autoApplyReward: z.boolean().default(false),
rewardType: z.string().optional(),
rewardTierLevel: z.string().optional(),
operaRewardId: z.string().default(""),
})
)
)
export const validateCmsRewardsSchema = z
.object({
data: z.object({
@@ -168,10 +88,6 @@ export const validateCmsRewardsWithRedeemSchema = z
})
.transform((data) => data.data.all_reward.items)
export type ApiReward = z.output<typeof validateApiRewardSchema>[number]
export type SurpriseReward = z.output<typeof SurpriseReward>
export type CmsRewardsResponse = z.input<typeof validateCmsRewardsSchema>
export type CmsRewardsWithRedeemResponse = z.input<

View File

@@ -1,4 +1,3 @@
import { env } from "@/env/server"
import * as api from "@/lib/api"
import { dt } from "@/lib/dt"
import { notFound } from "@/server/errors/trpc"
@@ -20,11 +19,9 @@ import {
import {
type Reward,
type Surprise,
validateApiRewardSchema,
validateCategorizedRewardsSchema,
} from "./output"
import {
getAllCachedApiRewards,
getAllRewardCounter,
getAllRewardFailCounter,
getAllRewardSuccessCounter,
@@ -52,9 +49,7 @@ export const rewardQueryRouter = router({
.query(async function ({ input, ctx }) {
getAllRewardCounter.add(1)
const allApiRewards = env.USE_NEW_REWARDS_ENDPOINT
? await getCachedAllTierRewards(ctx.serviceToken)
: await getAllCachedApiRewards(ctx.serviceToken)
const allApiRewards = await getCachedAllTierRewards(ctx.serviceToken)
if (!allApiRewards) {
return []
@@ -114,9 +109,9 @@ export const rewardQueryRouter = router({
getByLevelRewardCounter.add(1)
const { level_id } = input
const allUpcomingApiRewards = env.USE_NEW_REWARDS_ENDPOINT
? await getCachedAllTierRewards(ctx.serviceToken)
: await getAllCachedApiRewards(ctx.serviceToken)
const allUpcomingApiRewards = await getCachedAllTierRewards(
ctx.serviceToken
)
if (!allUpcomingApiRewards || !allUpcomingApiRewards[level_id]) {
getByLevelRewardFailCounter.add(1)
@@ -167,10 +162,7 @@ export const rewardQueryRouter = router({
.query(async function ({ ctx }) {
getCurrentRewardCounter.add(1)
const isNewEndpoint = env.USE_NEW_REWARDS_ENDPOINT
const endpoint = isNewEndpoint
? api.endpoints.v1.Profile.Reward.reward
: api.endpoints.v1.Profile.reward
const endpoint = api.endpoints.v1.Profile.Reward.reward
const apiResponse = await api.get(endpoint, {
headers: {
@@ -203,9 +195,8 @@ export const rewardQueryRouter = router({
const data = await apiResponse.json()
const validatedApiRewards = isNewEndpoint
? validateCategorizedRewardsSchema.safeParse(data)
: validateApiRewardSchema.safeParse(data)
const validatedApiRewards =
validateCategorizedRewardsSchema.safeParse(data)
if (!validatedApiRewards.success) {
getCurrentRewardFailCounter.add(1, {
@@ -301,10 +292,7 @@ export const rewardQueryRouter = router({
.query(async ({ ctx }) => {
getCurrentRewardCounter.add(1)
const isNewEndpoint = env.USE_NEW_REWARDS_ENDPOINT
const endpoint = isNewEndpoint
? api.endpoints.v1.Profile.Reward.reward
: api.endpoints.v1.Profile.reward
const endpoint = api.endpoints.v1.Profile.Reward.reward
const apiResponse = await api.get(endpoint, {
cache: undefined,
@@ -337,9 +325,8 @@ export const rewardQueryRouter = router({
}
const data = await apiResponse.json()
const validatedApiRewards = isNewEndpoint
? validateCategorizedRewardsSchema.safeParse(data)
: validateApiRewardSchema.safeParse(data)
const validatedApiRewards =
validateCategorizedRewardsSchema.safeParse(data)
if (!validatedApiRewards.success) {
getCurrentRewardFailCounter.add(1, {

View File

@@ -17,14 +17,12 @@ import {
} from "@/utils/generateTag"
import {
type ApiReward,
type CategorizedApiReward,
type CmsRewardsResponse,
type CmsRewardsWithRedeemResponse,
type GetRewardWithRedeemRefsSchema,
rewardWithRedeemRefsSchema,
validateApiAllTiersSchema,
validateApiTierRewardsSchema,
validateCmsRewardsSchema,
validateCmsRewardsWithRedeemSchema,
} from "./output"
@@ -93,71 +91,6 @@ export function getUniqueRewardIds(rewardIds: string[]) {
return Array.from(uniqueRewardIds)
}
/**
* Uses the legacy profile/v1/Profile/tierRewards endpoint.
* TODO: Delete when the new endpoint is out in production.
*/
export async function getAllCachedApiRewards(token: string) {
const cacheClient = await getCacheClient()
return await cacheClient.cacheOrGet(
"getAllApiRewards",
async () => {
const apiResponse = await api.get(api.endpoints.v1.Profile.tierRewards, {
headers: {
Authorization: `Bearer ${token}`,
},
})
if (!apiResponse.ok) {
const text = await apiResponse.text()
getAllRewardFailCounter.add(1, {
error_type: "http_error",
error: JSON.stringify({
status: apiResponse.status,
statusText: apiResponse.statusText,
text,
}),
})
console.error(
"api.rewards.tierRewards error ",
JSON.stringify({
error: {
status: apiResponse.status,
statusText: apiResponse.statusText,
text,
},
})
)
throw apiResponse
}
const data = await apiResponse.json()
const validatedApiTierRewards =
validateApiTierRewardsSchema.safeParse(data)
if (!validatedApiTierRewards.success) {
getAllRewardFailCounter.add(1, {
error_type: "validation_error",
error: JSON.stringify(validatedApiTierRewards.error),
})
console.error(validatedApiTierRewards.error)
console.error(
"api.rewards validation error",
JSON.stringify({
error: validatedApiTierRewards.error,
})
)
throw validatedApiTierRewards.error
}
return validatedApiTierRewards.data
},
"1h"
)
}
/**
* Cached for 1 hour.
*/
@@ -364,9 +297,7 @@ export async function getCmsRewards(lang: Lang, rewardIds: string[]) {
return validatedCmsRewards.data
}
export function getNonRedeemedRewardIds(
rewards: Array<ApiReward | CategorizedApiReward>
) {
export function getNonRedeemedRewardIds(rewards: Array<CategorizedApiReward>) {
return rewards
.filter((reward) => {
if ("coupon" in reward && reward.coupon.length > 0) {