feat: update current & surprise queries to support new endpoint
This commit is contained in:
@@ -91,22 +91,6 @@ export const validateApiTierRewardsSchema = z.record(
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
export const validateApiAllTiersSchema = z.record(
|
|
||||||
z.nativeEnum(TierKey).transform((data) => {
|
|
||||||
return TierKey[data as unknown as Key]
|
|
||||||
}),
|
|
||||||
z.array(
|
|
||||||
z.object({
|
|
||||||
id: z.string().optional(),
|
|
||||||
status: z.string().optional(),
|
|
||||||
rewardId: z.string().optional(),
|
|
||||||
rewardTierLevel: z.string().optional(),
|
|
||||||
rewardType: z.string().optional(),
|
|
||||||
title: z.string().optional(),
|
|
||||||
})
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
export const validateCmsRewardsSchema = z
|
export const validateCmsRewardsSchema = z
|
||||||
.object({
|
.object({
|
||||||
data: z.object({
|
data: z.object({
|
||||||
@@ -138,3 +122,61 @@ export type SurpriseReward = z.output<typeof SurpriseReward>
|
|||||||
export type CmsRewardsResponse = z.input<typeof validateCmsRewardsSchema>
|
export type CmsRewardsResponse = z.input<typeof validateCmsRewardsSchema>
|
||||||
|
|
||||||
export type Reward = z.output<typeof validateCmsRewardsSchema>[0]
|
export type Reward = z.output<typeof validateCmsRewardsSchema>[0]
|
||||||
|
|
||||||
|
// New endpoint related types and schemas.
|
||||||
|
|
||||||
|
const BenefitReward = z.object({
|
||||||
|
title: z.string().optional(),
|
||||||
|
id: z.string().optional(),
|
||||||
|
status: z.string().optional(),
|
||||||
|
rewardId: z.string().optional(),
|
||||||
|
rewardType: z.string().optional(),
|
||||||
|
rewardTierLevel: z.string().optional(),
|
||||||
|
})
|
||||||
|
|
||||||
|
const CouponState = z.enum(["claimed", "redeemed", "viewed"])
|
||||||
|
const CouponData = z.object({
|
||||||
|
couponCode: z.string().optional(),
|
||||||
|
unwrapped: z.boolean().default(false),
|
||||||
|
state: CouponState,
|
||||||
|
expiresAt: z.string().datetime({ offset: true }).optional(),
|
||||||
|
})
|
||||||
|
|
||||||
|
const CouponReward = z.object({
|
||||||
|
title: z.string().optional(),
|
||||||
|
id: z.string().optional(),
|
||||||
|
rewardId: z.string().optional(),
|
||||||
|
rewardType: z.string().optional(),
|
||||||
|
status: z.string().optional(),
|
||||||
|
coupon: z.array(CouponData).optional(),
|
||||||
|
})
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Schema for the new /profile/v1/Reward endpoint.
|
||||||
|
*
|
||||||
|
* TODO: Once we fully migrate to the new endpoint:
|
||||||
|
* 1. Remove the data transform and use the categorized structure directly.
|
||||||
|
* 2. Simplify surprise filtering in the query.
|
||||||
|
*/
|
||||||
|
export const validateCategorizedRewardsSchema = z
|
||||||
|
.object({
|
||||||
|
benefits: z.array(BenefitReward),
|
||||||
|
coupons: z.array(CouponReward),
|
||||||
|
})
|
||||||
|
.transform((data) => [
|
||||||
|
...data.benefits.map((benefit) => ({
|
||||||
|
...benefit,
|
||||||
|
type: "custom" as const, // Added for legacy compatibility.
|
||||||
|
})),
|
||||||
|
...data.coupons.map((coupon) => ({
|
||||||
|
...coupon,
|
||||||
|
type: "coupon" as const, // Added for legacy compatibility.
|
||||||
|
})),
|
||||||
|
])
|
||||||
|
|
||||||
|
export const validateApiAllTiersSchema = z.record(
|
||||||
|
z.nativeEnum(TierKey).transform((data) => {
|
||||||
|
return TierKey[data as unknown as Key]
|
||||||
|
}),
|
||||||
|
z.array(BenefitReward)
|
||||||
|
)
|
||||||
|
|||||||
@@ -14,7 +14,12 @@ import {
|
|||||||
rewardsCurrentInput,
|
rewardsCurrentInput,
|
||||||
rewardsUpdateInput,
|
rewardsUpdateInput,
|
||||||
} from "./input"
|
} from "./input"
|
||||||
import { Reward, SurpriseReward, validateApiRewardSchema } from "./output"
|
import {
|
||||||
|
Reward,
|
||||||
|
SurpriseReward,
|
||||||
|
validateApiRewardSchema,
|
||||||
|
validateCategorizedRewardsSchema,
|
||||||
|
} from "./output"
|
||||||
import {
|
import {
|
||||||
getAllCachedApiRewards,
|
getAllCachedApiRewards,
|
||||||
getAllRewardCounter,
|
getAllRewardCounter,
|
||||||
@@ -33,6 +38,8 @@ import {
|
|||||||
|
|
||||||
import { Surprise } from "@/types/components/blocks/surprises"
|
import { Surprise } from "@/types/components/blocks/surprises"
|
||||||
|
|
||||||
|
const ONE_HOUR = 60 * 60
|
||||||
|
|
||||||
export const rewardQueryRouter = router({
|
export const rewardQueryRouter = router({
|
||||||
all: contentStackBaseWithServiceProcedure
|
all: contentStackBaseWithServiceProcedure
|
||||||
.input(rewardsAllInput)
|
.input(rewardsAllInput)
|
||||||
@@ -154,12 +161,17 @@ export const rewardQueryRouter = router({
|
|||||||
|
|
||||||
const { limit, cursor } = input
|
const { limit, cursor } = input
|
||||||
|
|
||||||
const apiResponse = await api.get(api.endpoints.v1.Profile.reward, {
|
const isNewEndpoint = !!env.USE_NEW_REWARDS_ENDPOINT
|
||||||
|
const endpoint = isNewEndpoint
|
||||||
|
? api.endpoints.v1.Profile.Reward.reward
|
||||||
|
: api.endpoints.v1.Profile.reward
|
||||||
|
|
||||||
|
const apiResponse = await api.get(endpoint, {
|
||||||
cache: undefined, // override defaultOptions
|
cache: undefined, // override defaultOptions
|
||||||
headers: {
|
headers: {
|
||||||
Authorization: `Bearer ${ctx.session.token.access_token}`,
|
Authorization: `Bearer ${ctx.session.token.access_token}`,
|
||||||
},
|
},
|
||||||
next: { revalidate: 60 * 60 },
|
next: { revalidate: ONE_HOUR },
|
||||||
})
|
})
|
||||||
|
|
||||||
if (!apiResponse.ok) {
|
if (!apiResponse.ok) {
|
||||||
@@ -186,8 +198,9 @@ export const rewardQueryRouter = router({
|
|||||||
}
|
}
|
||||||
|
|
||||||
const data = await apiResponse.json()
|
const data = await apiResponse.json()
|
||||||
|
const validatedApiRewards = isNewEndpoint
|
||||||
const validatedApiRewards = validateApiRewardSchema.safeParse(data)
|
? validateCategorizedRewardsSchema.safeParse(data)
|
||||||
|
: validateApiRewardSchema.safeParse(data)
|
||||||
|
|
||||||
if (!validatedApiRewards.success) {
|
if (!validatedApiRewards.success) {
|
||||||
getCurrentRewardFailCounter.add(1, {
|
getCurrentRewardFailCounter.add(1, {
|
||||||
@@ -243,12 +256,17 @@ export const rewardQueryRouter = router({
|
|||||||
surprises: contentStackBaseWithProtectedProcedure.query(async ({ ctx }) => {
|
surprises: contentStackBaseWithProtectedProcedure.query(async ({ ctx }) => {
|
||||||
getCurrentRewardCounter.add(1)
|
getCurrentRewardCounter.add(1)
|
||||||
|
|
||||||
const apiResponse = await api.get(api.endpoints.v1.Profile.reward, {
|
const isNewEndpoint = !!env.USE_NEW_REWARDS_ENDPOINT
|
||||||
cache: undefined, // override defaultOptions
|
const endpoint = isNewEndpoint
|
||||||
|
? api.endpoints.v1.Profile.Reward.reward
|
||||||
|
: api.endpoints.v1.Profile.reward
|
||||||
|
|
||||||
|
const apiResponse = await api.get(endpoint, {
|
||||||
|
cache: undefined,
|
||||||
headers: {
|
headers: {
|
||||||
Authorization: `Bearer ${ctx.session.token.access_token}`,
|
Authorization: `Bearer ${ctx.session.token.access_token}`,
|
||||||
},
|
},
|
||||||
next: { revalidate: 60 * 60 },
|
next: { revalidate: ONE_HOUR },
|
||||||
})
|
})
|
||||||
|
|
||||||
if (!apiResponse.ok) {
|
if (!apiResponse.ok) {
|
||||||
@@ -275,8 +293,9 @@ export const rewardQueryRouter = router({
|
|||||||
}
|
}
|
||||||
|
|
||||||
const data = await apiResponse.json()
|
const data = await apiResponse.json()
|
||||||
|
const validatedApiRewards = isNewEndpoint
|
||||||
const validatedApiRewards = validateApiRewardSchema.safeParse(data)
|
? validateCategorizedRewardsSchema.safeParse(data)
|
||||||
|
: validateApiRewardSchema.safeParse(data)
|
||||||
|
|
||||||
if (!validatedApiRewards.success) {
|
if (!validatedApiRewards.success) {
|
||||||
getCurrentRewardFailCounter.add(1, {
|
getCurrentRewardFailCounter.add(1, {
|
||||||
|
|||||||
@@ -53,8 +53,8 @@ export function getUniqueRewardIds(rewardIds: string[]) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Uses profile/v1/Profile/tierRewards.
|
* Uses the legacy profile/v1/Profile/tierRewards endpoint.
|
||||||
* Will be removed when new endpoint is out in production.
|
* TODO: Delete when the new endpoint is out in production.
|
||||||
*/
|
*/
|
||||||
export const getAllCachedApiRewards = unstable_cache(
|
export const getAllCachedApiRewards = unstable_cache(
|
||||||
async function (token) {
|
async function (token) {
|
||||||
|
|||||||
Reference in New Issue
Block a user