chore(LOY-175): remove references to old reward endpoints
This commit is contained in:
@@ -60,6 +60,5 @@ ENABLE_BOOKING_WIDGET_HOTELRESERVATION_PATH="false"
|
|||||||
|
|
||||||
SHOW_SITE_WIDE_ALERT="false"
|
SHOW_SITE_WIDE_ALERT="false"
|
||||||
SHOW_SIGNUP_FLOW="true"
|
SHOW_SIGNUP_FLOW="true"
|
||||||
USE_NEW_REWARDS_ENDPOINT="true"
|
|
||||||
|
|
||||||
USE_NEW_REWARD_MODEL="true"
|
USE_NEW_REWARD_MODEL="true"
|
||||||
|
|||||||
@@ -43,7 +43,6 @@ GOOGLE_STATIC_MAP_ID="test"
|
|||||||
GOOGLE_DYNAMIC_MAP_ID="test"
|
GOOGLE_DYNAMIC_MAP_ID="test"
|
||||||
NEXT_PUBLIC_HIDE_FOR_NEXT_RELEASE="true"
|
NEXT_PUBLIC_HIDE_FOR_NEXT_RELEASE="true"
|
||||||
SALESFORCE_PREFERENCE_BASE_URL="test"
|
SALESFORCE_PREFERENCE_BASE_URL="test"
|
||||||
USE_NEW_REWARDS_ENDPOINT="true"
|
|
||||||
USE_NEW_REWARD_MODEL="true"
|
USE_NEW_REWARD_MODEL="true"
|
||||||
|
|
||||||
TZ=UTC
|
TZ=UTC
|
||||||
@@ -54,4 +53,4 @@ SHOW_SITE_WIDE_ALERT="false"
|
|||||||
|
|
||||||
NEXT_PUBLIC_SENTRY_ENVIRONMENT="test"
|
NEXT_PUBLIC_SENTRY_ENVIRONMENT="test"
|
||||||
NEXT_PUBLIC_SENTRY_CLIENT_SAMPLERATE="0"
|
NEXT_PUBLIC_SENTRY_CLIENT_SAMPLERATE="0"
|
||||||
SITEMAP_SYNC_SECRET="test
|
SITEMAP_SYNC_SECRET="test
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ export default async function CurrentRewardsBlock({
|
|||||||
<SectionHeader title={title} link={link} preamble={subtitle} />
|
<SectionHeader title={title} link={link} preamble={subtitle} />
|
||||||
<ClientCurrentRewards
|
<ClientCurrentRewards
|
||||||
rewards={rewardsResponse.rewards}
|
rewards={rewardsResponse.rewards}
|
||||||
showRedeem={env.USE_NEW_REWARDS_ENDPOINT && env.USE_NEW_REWARD_MODEL}
|
showRedeem={env.USE_NEW_REWARD_MODEL}
|
||||||
membershipNumber={membershipLevel?.membershipNumber}
|
membershipNumber={membershipLevel?.membershipNumber}
|
||||||
/>
|
/>
|
||||||
<SectionLink link={link} variant="mobile" />
|
<SectionLink link={link} variant="mobile" />
|
||||||
|
|||||||
8
apps/scandic-web/env/server.ts
vendored
8
apps/scandic-web/env/server.ts
vendored
@@ -141,13 +141,6 @@ export const env = createEnv({
|
|||||||
// transform to boolean
|
// transform to boolean
|
||||||
.transform((s) => s === "true")
|
.transform((s) => s === "true")
|
||||||
.default("false"),
|
.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
|
USE_NEW_REWARD_MODEL: z
|
||||||
.string()
|
.string()
|
||||||
// only allow "true" or "false"
|
// only allow "true" or "false"
|
||||||
@@ -268,7 +261,6 @@ export const env = createEnv({
|
|||||||
GOOGLE_STATIC_MAP_ID: process.env.GOOGLE_STATIC_MAP_ID,
|
GOOGLE_STATIC_MAP_ID: process.env.GOOGLE_STATIC_MAP_ID,
|
||||||
GOOGLE_DYNAMIC_MAP_ID: process.env.GOOGLE_DYNAMIC_MAP_ID,
|
GOOGLE_DYNAMIC_MAP_ID: process.env.GOOGLE_DYNAMIC_MAP_ID,
|
||||||
HIDE_FOR_NEXT_RELEASE: process.env.NEXT_PUBLIC_HIDE_FOR_NEXT_RELEASE,
|
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,
|
USE_NEW_REWARD_MODEL: process.env.USE_NEW_REWARD_MODEL,
|
||||||
ENABLE_BOOKING_FLOW: process.env.ENABLE_BOOKING_FLOW,
|
ENABLE_BOOKING_FLOW: process.env.ENABLE_BOOKING_FLOW,
|
||||||
ENABLE_BOOKING_WIDGET: process.env.ENABLE_BOOKING_WIDGET,
|
ENABLE_BOOKING_WIDGET: process.env.ENABLE_BOOKING_WIDGET,
|
||||||
|
|||||||
@@ -171,10 +171,6 @@ export namespace endpoints {
|
|||||||
export const unlink = `${base.path.profile}/${version}/${base.enitity.Profile}/Unlink`
|
export const unlink = `${base.path.profile}/${version}/${base.enitity.Profile}/Unlink`
|
||||||
export const matchTier = `${base.path.profile}/${version}/${base.enitity.Profile}/MatchTier`
|
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) {
|
export function deleteProfile(profileId: string) {
|
||||||
return `${profile}/${profileId}`
|
return `${profile}/${profileId}`
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,66 +12,6 @@ import { systemSchema } from "../schemas/system"
|
|||||||
|
|
||||||
import type { RewardCategory } from "@/types/components/myPages/rewards"
|
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 {
|
enum TierKey {
|
||||||
tier1 = MembershipLevelEnum.L1,
|
tier1 = MembershipLevelEnum.L1,
|
||||||
tier2 = MembershipLevelEnum.L2,
|
tier2 = MembershipLevelEnum.L2,
|
||||||
@@ -84,26 +24,6 @@ enum TierKey {
|
|||||||
|
|
||||||
type Key = keyof typeof 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
|
export const validateCmsRewardsSchema = z
|
||||||
.object({
|
.object({
|
||||||
data: z.object({
|
data: z.object({
|
||||||
@@ -168,10 +88,6 @@ export const validateCmsRewardsWithRedeemSchema = z
|
|||||||
})
|
})
|
||||||
.transform((data) => data.data.all_reward.items)
|
.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 CmsRewardsResponse = z.input<typeof validateCmsRewardsSchema>
|
||||||
|
|
||||||
export type CmsRewardsWithRedeemResponse = z.input<
|
export type CmsRewardsWithRedeemResponse = z.input<
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
import { env } from "@/env/server"
|
|
||||||
import * as api from "@/lib/api"
|
import * as api from "@/lib/api"
|
||||||
import { dt } from "@/lib/dt"
|
import { dt } from "@/lib/dt"
|
||||||
import { notFound } from "@/server/errors/trpc"
|
import { notFound } from "@/server/errors/trpc"
|
||||||
@@ -20,11 +19,9 @@ import {
|
|||||||
import {
|
import {
|
||||||
type Reward,
|
type Reward,
|
||||||
type Surprise,
|
type Surprise,
|
||||||
validateApiRewardSchema,
|
|
||||||
validateCategorizedRewardsSchema,
|
validateCategorizedRewardsSchema,
|
||||||
} from "./output"
|
} from "./output"
|
||||||
import {
|
import {
|
||||||
getAllCachedApiRewards,
|
|
||||||
getAllRewardCounter,
|
getAllRewardCounter,
|
||||||
getAllRewardFailCounter,
|
getAllRewardFailCounter,
|
||||||
getAllRewardSuccessCounter,
|
getAllRewardSuccessCounter,
|
||||||
@@ -52,9 +49,7 @@ export const rewardQueryRouter = router({
|
|||||||
.query(async function ({ input, ctx }) {
|
.query(async function ({ input, ctx }) {
|
||||||
getAllRewardCounter.add(1)
|
getAllRewardCounter.add(1)
|
||||||
|
|
||||||
const allApiRewards = env.USE_NEW_REWARDS_ENDPOINT
|
const allApiRewards = await getCachedAllTierRewards(ctx.serviceToken)
|
||||||
? await getCachedAllTierRewards(ctx.serviceToken)
|
|
||||||
: await getAllCachedApiRewards(ctx.serviceToken)
|
|
||||||
|
|
||||||
if (!allApiRewards) {
|
if (!allApiRewards) {
|
||||||
return []
|
return []
|
||||||
@@ -114,9 +109,9 @@ export const rewardQueryRouter = router({
|
|||||||
getByLevelRewardCounter.add(1)
|
getByLevelRewardCounter.add(1)
|
||||||
const { level_id } = input
|
const { level_id } = input
|
||||||
|
|
||||||
const allUpcomingApiRewards = env.USE_NEW_REWARDS_ENDPOINT
|
const allUpcomingApiRewards = await getCachedAllTierRewards(
|
||||||
? await getCachedAllTierRewards(ctx.serviceToken)
|
ctx.serviceToken
|
||||||
: await getAllCachedApiRewards(ctx.serviceToken)
|
)
|
||||||
|
|
||||||
if (!allUpcomingApiRewards || !allUpcomingApiRewards[level_id]) {
|
if (!allUpcomingApiRewards || !allUpcomingApiRewards[level_id]) {
|
||||||
getByLevelRewardFailCounter.add(1)
|
getByLevelRewardFailCounter.add(1)
|
||||||
@@ -167,10 +162,7 @@ export const rewardQueryRouter = router({
|
|||||||
.query(async function ({ ctx }) {
|
.query(async function ({ ctx }) {
|
||||||
getCurrentRewardCounter.add(1)
|
getCurrentRewardCounter.add(1)
|
||||||
|
|
||||||
const isNewEndpoint = env.USE_NEW_REWARDS_ENDPOINT
|
const endpoint = api.endpoints.v1.Profile.Reward.reward
|
||||||
const endpoint = isNewEndpoint
|
|
||||||
? api.endpoints.v1.Profile.Reward.reward
|
|
||||||
: api.endpoints.v1.Profile.reward
|
|
||||||
|
|
||||||
const apiResponse = await api.get(endpoint, {
|
const apiResponse = await api.get(endpoint, {
|
||||||
headers: {
|
headers: {
|
||||||
@@ -203,9 +195,8 @@ export const rewardQueryRouter = router({
|
|||||||
|
|
||||||
const data = await apiResponse.json()
|
const data = await apiResponse.json()
|
||||||
|
|
||||||
const validatedApiRewards = isNewEndpoint
|
const validatedApiRewards =
|
||||||
? validateCategorizedRewardsSchema.safeParse(data)
|
validateCategorizedRewardsSchema.safeParse(data)
|
||||||
: validateApiRewardSchema.safeParse(data)
|
|
||||||
|
|
||||||
if (!validatedApiRewards.success) {
|
if (!validatedApiRewards.success) {
|
||||||
getCurrentRewardFailCounter.add(1, {
|
getCurrentRewardFailCounter.add(1, {
|
||||||
@@ -301,10 +292,7 @@ export const rewardQueryRouter = router({
|
|||||||
.query(async ({ ctx }) => {
|
.query(async ({ ctx }) => {
|
||||||
getCurrentRewardCounter.add(1)
|
getCurrentRewardCounter.add(1)
|
||||||
|
|
||||||
const isNewEndpoint = env.USE_NEW_REWARDS_ENDPOINT
|
const endpoint = api.endpoints.v1.Profile.Reward.reward
|
||||||
const endpoint = isNewEndpoint
|
|
||||||
? api.endpoints.v1.Profile.Reward.reward
|
|
||||||
: api.endpoints.v1.Profile.reward
|
|
||||||
|
|
||||||
const apiResponse = await api.get(endpoint, {
|
const apiResponse = await api.get(endpoint, {
|
||||||
cache: undefined,
|
cache: undefined,
|
||||||
@@ -337,9 +325,8 @@ export const rewardQueryRouter = router({
|
|||||||
}
|
}
|
||||||
|
|
||||||
const data = await apiResponse.json()
|
const data = await apiResponse.json()
|
||||||
const validatedApiRewards = isNewEndpoint
|
const validatedApiRewards =
|
||||||
? validateCategorizedRewardsSchema.safeParse(data)
|
validateCategorizedRewardsSchema.safeParse(data)
|
||||||
: validateApiRewardSchema.safeParse(data)
|
|
||||||
|
|
||||||
if (!validatedApiRewards.success) {
|
if (!validatedApiRewards.success) {
|
||||||
getCurrentRewardFailCounter.add(1, {
|
getCurrentRewardFailCounter.add(1, {
|
||||||
|
|||||||
@@ -17,14 +17,12 @@ import {
|
|||||||
} from "@/utils/generateTag"
|
} from "@/utils/generateTag"
|
||||||
|
|
||||||
import {
|
import {
|
||||||
type ApiReward,
|
|
||||||
type CategorizedApiReward,
|
type CategorizedApiReward,
|
||||||
type CmsRewardsResponse,
|
type CmsRewardsResponse,
|
||||||
type CmsRewardsWithRedeemResponse,
|
type CmsRewardsWithRedeemResponse,
|
||||||
type GetRewardWithRedeemRefsSchema,
|
type GetRewardWithRedeemRefsSchema,
|
||||||
rewardWithRedeemRefsSchema,
|
rewardWithRedeemRefsSchema,
|
||||||
validateApiAllTiersSchema,
|
validateApiAllTiersSchema,
|
||||||
validateApiTierRewardsSchema,
|
|
||||||
validateCmsRewardsSchema,
|
validateCmsRewardsSchema,
|
||||||
validateCmsRewardsWithRedeemSchema,
|
validateCmsRewardsWithRedeemSchema,
|
||||||
} from "./output"
|
} from "./output"
|
||||||
@@ -93,71 +91,6 @@ export function getUniqueRewardIds(rewardIds: string[]) {
|
|||||||
return Array.from(uniqueRewardIds)
|
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.
|
* Cached for 1 hour.
|
||||||
*/
|
*/
|
||||||
@@ -364,9 +297,7 @@ export async function getCmsRewards(lang: Lang, rewardIds: string[]) {
|
|||||||
return validatedCmsRewards.data
|
return validatedCmsRewards.data
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getNonRedeemedRewardIds(
|
export function getNonRedeemedRewardIds(rewards: Array<CategorizedApiReward>) {
|
||||||
rewards: Array<ApiReward | CategorizedApiReward>
|
|
||||||
) {
|
|
||||||
return rewards
|
return rewards
|
||||||
.filter((reward) => {
|
.filter((reward) => {
|
||||||
if ("coupon" in reward && reward.coupon.length > 0) {
|
if ("coupon" in reward && reward.coupon.length > 0) {
|
||||||
|
|||||||
Reference in New Issue
Block a user