Merged in fix/SW-1754-overview-page-rate-limit (pull request #1412)

fix(SW-1754): Fix rate limit issue on Destination Overview Page

* fix(SW-1754): Fix rate limit issue on Destination Overview Page


Approved-by: Matilda Landström
This commit is contained in:
Erik Tiekstra
2025-02-25 14:40:31 +00:00
parent 3867baadd6
commit bc50dcf286
27 changed files with 426 additions and 244 deletions

View File

@@ -2,8 +2,6 @@ import { z } from "zod"
import { discriminatedUnionArray } from "@/lib/discriminatedUnion"
import { removeMultipleSlashes } from "@/utils/url"
import {
cardGalleryRefsSchema,
cardGallerySchema,
@@ -40,27 +38,6 @@ export const destinationOverviewPageSchema = z.object({
}),
})
export const countryPageUrlSchema = z
.object({
all_destination_country_page: z.object({
items: z.array(
z
.object({
url: z.string(),
system: systemSchema,
})
.transform((data) => {
return {
url: removeMultipleSlashes(`/${data.system.locale}/${data.url}`),
}
})
),
}),
})
.transform(
({ all_destination_country_page }) => all_destination_country_page.items[0]
)
/** REFS */
const destinationOverviewPageCardGalleryRef = z
.object({

View File

@@ -19,7 +19,8 @@ import {
getCountries,
getHotelIdsByCityId,
} from "../../hotels/utils"
import { getCityListDataByCityIdentifier } from "../destinationCountryPage/utils"
import { getCityPageUrls } from "../destinationCityPage/utils"
import { getCountryPageUrls } from "../destinationCountryPage/utils"
import {
destinationOverviewPageRefsSchema,
destinationOverviewPageSchema,
@@ -32,7 +33,6 @@ import {
getDestinationOverviewPageRefsSuccessCounter,
getDestinationOverviewPageSuccessCounter,
} from "./telemetry"
import { getCountryPageUrl } from "./utils"
import type { DestinationsData } from "@/types/components/destinationOverviewPage/destinationsList/destinationsData"
import {
@@ -220,8 +220,8 @@ export const destinationOverviewPageQueryRouter = router({
revalidate: env.CACHE_TIME_HOTELS,
},
}
const countries = await getCountries(options, params, ctx.lang)
const countryPages = await getCountryPageUrls(ctx.lang)
if (!countries) {
return null
@@ -237,6 +237,8 @@ export const destinationOverviewPageQueryRouter = router({
true
)
const cityPages = await getCityPageUrls(ctx.lang)
const destinations: DestinationsData = await Promise.all(
Object.entries(citiesByCountry).map(async ([country, cities]) => {
const citiesWithHotelCount = await Promise.all(
@@ -252,29 +254,27 @@ export const destinationOverviewPageQueryRouter = router({
hotelIdsParams
)
let cityUrl
if (city.cityIdentifier) {
cityUrl = await getCityListDataByCityIdentifier(
ctx.lang,
city.cityIdentifier
)
}
const cityPage = cityPages.find(
(cityPage) => cityPage.city === city.cityIdentifier
)
return {
id: city.id,
name: city.name,
hotelIds: hotels,
hotelCount: hotels?.length ?? 0,
url: cityUrl?.url,
url: cityPage?.url,
}
})
)
const countryUrl = await getCountryPageUrl(ctx.lang, country)
const countryPage = countryPages.find(
(countryPage) => countryPage.country === country
)
return {
country,
countryUrl: countryUrl?.url,
countryUrl: countryPage?.url,
numberOfHotels: citiesWithHotelCount.reduce(
(acc, city) => acc + city.hotelCount,
0

View File

@@ -21,15 +21,3 @@ export const getDestinationOverviewPageSuccessCounter = meter.createCounter(
export const getDestinationOverviewPageFailCounter = meter.createCounter(
"trpc.contentstack.destinationOverviewPage.get-fail"
)
export const getCountryPageUrlCounter = meter.createCounter(
"trpc.contentstack.getCountryPageUrl"
)
export const getCountryPageUrlSuccessCounter = meter.createCounter(
"trpc.contentstack.getCountryPageUrl-success"
)
export const getCountryPageUrlFailCounter = meter.createCounter(
"trpc.contentstack.getCountryPageUrl-fail"
)

View File

@@ -1,76 +0,0 @@
import { GetCountryPageUrl } from "@/lib/graphql/Query/DestinationOverviewPage/DestinationOverviewPage.graphql"
import { request } from "@/lib/graphql/request"
import { countryPageUrlSchema } from "./output"
import {
getCountryPageUrlCounter,
getCountryPageUrlFailCounter,
getCountryPageUrlSuccessCounter,
} from "./telemetry"
import type { GetCountryPageUrlData } from "@/types/trpc/routers/contentstack/destinationOverviewPage"
import type { Lang } from "@/constants/languages"
export async function getCountryPageUrl(lang: Lang, country: string) {
getCountryPageUrlCounter.add(1, { lang, country })
console.info(
"contentstack.countryPageUrl start",
JSON.stringify({ query: { lang, country } })
)
const tag = `${lang}:country_page_url:${country}`
const response = await request<GetCountryPageUrlData>(
GetCountryPageUrl,
{
locale: lang,
country,
},
{
cache: "force-cache",
next: {
tags: [tag],
},
}
)
if (!response.data) {
getCountryPageUrlFailCounter.add(1, {
lang,
country,
error_type: "not_found",
error: `Country page not found for country: ${country}`,
})
console.error(
"contentstack.countryPageUrl not found error",
JSON.stringify({ query: { lang, country } })
)
return null
}
const validatedCountryPageUrl = countryPageUrlSchema.safeParse(response.data)
if (!validatedCountryPageUrl.success) {
getCountryPageUrlFailCounter.add(1, {
lang,
country,
error_type: "validation_error",
error: JSON.stringify(validatedCountryPageUrl.error),
})
console.error(
"contentstack.countryPageUrl validation error",
JSON.stringify({
query: { lang, country },
error: validatedCountryPageUrl.error,
})
)
return null
}
getCountryPageUrlSuccessCounter.add(1, { lang, country })
console.info(
"contentstack.countryPageUrl success",
JSON.stringify({ query: { lang, country } })
)
return validatedCountryPageUrl.data
}