feat(SW-497): Added global alerts query and typings

This commit is contained in:
Erik Tiekstra
2024-09-30 13:11:27 +02:00
parent fb68759720
commit 78569fcb21
7 changed files with 297 additions and 89 deletions

View File

@@ -15,6 +15,7 @@ import { removeMultipleSlashes } from "@/utils/url"
import { systemSchema } from "../schemas/system"
import { Image } from "@/types/image"
import { GlobalAlertType } from "@/types/trpc/routers/contentstack/siteConfiguration"
// Help me write this zod schema based on the type ContactConfig
export const validateContactConfigSchema = z.object({
@@ -39,10 +40,12 @@ export const validateContactConfigSchema = z.object({
phone: z.object({
number: z.string().nullable(),
name: z.string().nullable(),
footnote: z.string().nullable(),
}),
phone_loyalty: z.object({
number: z.string().nullable(),
name: z.string().nullable(),
footnote: z.string().nullable(),
}),
visiting_address: z.object({
zip: z.string().nullable(),
@@ -660,3 +663,53 @@ export const headerSchema = z
},
}
})
export const globalAlertSchema = z.object({
type: z.nativeEnum(GlobalAlertType),
text: z.string(),
heading: z.string(),
phone_contact: z.object({
display_text: z.string(),
phone_number: z.string(),
footnote: z.string(),
}),
})
export const siteConfigurationSchema = z
.object({
all_site_configuration: z.object({
items: z
.array(
z.object({
sitewide_alert: z.object({
booking_widget_disabled: z.boolean(),
alertConnection: z.object({
edges: z
.array(
z.object({
node: globalAlertSchema,
})
)
.max(1),
}),
}),
})
)
.max(1),
}),
})
.transform((data) => {
if (!data.all_site_configuration.items.length) {
return {
globalAlert: null,
bookingWidgetDisabled: false,
}
}
const { sitewide_alert } = data.all_site_configuration.items[0]
return {
globalAlert: sitewide_alert.alertConnection.edges[0]?.node || null,
bookingWidgetDisabled: sitewide_alert.booking_widget_disabled,
}
})

View File

@@ -1,5 +1,3 @@
import { metrics } from "@opentelemetry/api"
import { GetContactConfig } from "@/lib/graphql/Query/ContactConfig.graphql"
import {
GetCurrentFooter,
@@ -11,6 +9,7 @@ import {
} from "@/lib/graphql/Query/Current/Header.graphql"
import { GetFooter, GetFooterRef } from "@/lib/graphql/Query/Footer.graphql"
import { GetHeader, GetHeaderRef } from "@/lib/graphql/Query/Header.graphql"
import { GetSiteConfiguration } from "@/lib/graphql/Query/SiteConfiguration.graphql"
import { request } from "@/lib/graphql/request"
import { notFound } from "@/server/errors/trpc"
import { contentstackBaseProcedure, router } from "@/server/trpc"
@@ -31,12 +30,41 @@ import {
type GetCurrentHeaderData,
headerRefsSchema,
headerSchema,
siteConfigurationSchema,
validateContactConfigSchema,
validateCurrentFooterConfigSchema,
validateCurrentHeaderConfigSchema,
validateFooterConfigSchema,
validateFooterRefConfigSchema,
} from "./output"
import {
getContactConfigCounter,
getContactConfigFailCounter,
getContactConfigSuccessCounter,
getCurrentFooterCounter,
getCurrentFooterFailCounter,
getCurrentFooterRefCounter,
getCurrentFooterSuccessCounter,
getCurrentHeaderCounter,
getCurrentHeaderFailCounter,
getCurrentHeaderRefCounter,
getCurrentHeaderSuccessCounter,
getFooterCounter,
getFooterFailCounter,
getFooterRefCounter,
getFooterRefFailCounter,
getFooterRefSuccessCounter,
getFooterSuccessCounter,
getHeaderCounter,
getHeaderFailCounter,
getHeaderRefsCounter,
getHeaderRefsFailCounter,
getHeaderRefsSuccessCounter,
getHeaderSuccessCounter,
getSiteConfigurationCounter,
getSiteConfigurationFailCounter,
getSiteConfigurationSuccessCounter,
} from "./telemetry"
import { getConnections, getFooterConnections } from "./utils"
import type {
@@ -47,93 +75,7 @@ import type {
GetHeader as GetHeaderData,
GetHeaderRefs,
} from "@/types/trpc/routers/contentstack/header"
const meter = metrics.getMeter("trpc.contentstack.base")
// OpenTelemetry metrics: ContactConfig
const getContactConfigCounter = meter.createCounter(
"trpc.contentstack.contactConfig.get"
)
const getContactConfigSuccessCounter = meter.createCounter(
"trpc.contentstack.contactConfig.get-success"
)
const getContactConfigFailCounter = meter.createCounter(
"trpc.contentstack.contactConfig.get-fail"
)
// OpenTelemetry metrics: CurrentHeader
const getCurrentHeaderRefCounter = meter.createCounter(
"trpc.contentstack.currentHeader.ref.get"
)
const getCurrentHeaderRefSuccessCounter = meter.createCounter(
"trpc.contentstack.currentHeader.ref.get-success"
)
const getCurrentHeaderRefFailCounter = meter.createCounter(
"trpc.contentstack.currentHeader.ref.get-fail"
)
const getCurrentHeaderCounter = meter.createCounter(
"trpc.contentstack.currentHeader.get"
)
const getCurrentHeaderSuccessCounter = meter.createCounter(
"trpc.contentstack.currentHeader.get-success"
)
const getCurrentHeaderFailCounter = meter.createCounter(
"trpc.contentstack.currentHeader.get-fail"
)
// OpenTelemetry metrics: Header
const getHeaderRefsCounter = meter.createCounter(
"trpc.contentstack.header.ref.get"
)
const getHeaderRefsSuccessCounter = meter.createCounter(
"trpc.contentstack.header.ref.get-success"
)
const getHeaderRefsFailCounter = meter.createCounter(
"trpc.contentstack.header.ref.get-fail"
)
const getHeaderCounter = meter.createCounter("trpc.contentstack.header.get")
const getHeaderSuccessCounter = meter.createCounter(
"trpc.contentstack.header.get-success"
)
const getHeaderFailCounter = meter.createCounter(
"trpc.contentstack.header.get-fail"
)
// OpenTelemetry metrics: CurrentHeader
const getCurrentFooterRefCounter = meter.createCounter(
"trpc.contentstack.currentFooter.ref.get"
)
const getCurrentFooterRefSuccessCounter = meter.createCounter(
"trpc.contentstack.currentFooter.ref.get-success"
)
const getCurrentFooterRefFailCounter = meter.createCounter(
"trpc.contentstack.currentFooter.ref.get-fail"
)
const getCurrentFooterCounter = meter.createCounter(
"trpc.contentstack.currentFooter.get"
)
const getCurrentFooterSuccessCounter = meter.createCounter(
"trpc.contentstack.currentFooter.get-success"
)
const getCurrentFooterFailCounter = meter.createCounter(
"trpc.contentstack.currentFooter.get-fail"
)
// OpenTelemetry metrics: Footer
const getFooterRefCounter = meter.createCounter(
"trpc.contentstack.footer.ref.get"
)
const getFooterRefSuccessCounter = meter.createCounter(
"trpc.contentstack.footer.ref.get-success"
)
const getFooterRefFailCounter = meter.createCounter(
"trpc.contentstack.footer.ref.get-fail"
)
const getFooterCounter = meter.createCounter("trpc.contentstack.footer.get")
const getFooterSuccessCounter = meter.createCounter(
"trpc.contentstack.footer.get-success"
)
const getFooterFailCounter = meter.createCounter(
"trpc.contentstack.footer.get-fail"
)
import type { GetSiteConfigurationData } from "@/types/trpc/routers/contentstack/siteConfiguration"
export const baseQueryRouter = router({
contact: contentstackBaseProcedure.query(async ({ ctx }) => {
@@ -652,4 +594,67 @@ export const baseQueryRouter = router({
return validatedFooterConfig.data
}),
siteConfiguration: contentstackBaseProcedure.query(async ({ ctx }) => {
const { lang } = ctx
getSiteConfigurationCounter.add(1, { lang })
console.info(
"contentstack.siteConfiguration start",
JSON.stringify({ query: { lang } })
)
const response = await request<GetSiteConfigurationData>(
GetSiteConfiguration,
{
locale: lang,
},
{
cache: "force-cache",
next: {
tags: [`${lang}:siteConfiguration`],
},
}
)
if (!response.data) {
const notFoundError = notFound(response)
getSiteConfigurationFailCounter.add(1, {
lang,
error_type: "not_found",
error: JSON.stringify({ code: notFoundError.code }),
})
console.error(
"contentstack.siteConfiguration not found error",
JSON.stringify({ query: { lang }, error: { code: notFoundError.code } })
)
throw notFoundError
}
const validatedSiteConfiguration = siteConfigurationSchema.safeParse(
response.data
)
if (!validatedSiteConfiguration.success) {
getSiteConfigurationFailCounter.add(1, {
lang,
error_type: "validation_error",
error: JSON.stringify(validatedSiteConfiguration.error),
})
console.error(
"contentstack.siteConfiguration validation error",
JSON.stringify({
query: { lang },
error: validatedSiteConfiguration.error,
})
)
return null
}
getSiteConfigurationSuccessCounter.add(1, { lang })
console.info(
"contentstack.siteConfiguration success",
JSON.stringify({ query: { lang } })
)
return validatedSiteConfiguration.data
}),
})

View File

@@ -0,0 +1,103 @@
import { metrics } from "@opentelemetry/api"
const meter = metrics.getMeter("trpc.contentstack.base")
// OpenTelemetry metrics: ContactConfig
export const getContactConfigCounter = meter.createCounter(
"trpc.contentstack.contactConfig.get"
)
export const getContactConfigSuccessCounter = meter.createCounter(
"trpc.contentstack.contactConfig.get-success"
)
export const getContactConfigFailCounter = meter.createCounter(
"trpc.contentstack.contactConfig.get-fail"
)
// OpenTelemetry metrics: CurrentHeader
export const getCurrentHeaderRefCounter = meter.createCounter(
"trpc.contentstack.currentHeader.ref.get"
)
export const getCurrentHeaderRefSuccessCounter = meter.createCounter(
"trpc.contentstack.currentHeader.ref.get-success"
)
export const getCurrentHeaderRefFailCounter = meter.createCounter(
"trpc.contentstack.currentHeader.ref.get-fail"
)
export const getCurrentHeaderCounter = meter.createCounter(
"trpc.contentstack.currentHeader.get"
)
export const getCurrentHeaderSuccessCounter = meter.createCounter(
"trpc.contentstack.currentHeader.get-success"
)
export const getCurrentHeaderFailCounter = meter.createCounter(
"trpc.contentstack.currentHeader.get-fail"
)
// OpenTelemetry metrics: Header
export const getHeaderRefsCounter = meter.createCounter(
"trpc.contentstack.header.ref.get"
)
export const getHeaderRefsSuccessCounter = meter.createCounter(
"trpc.contentstack.header.ref.get-success"
)
export const getHeaderRefsFailCounter = meter.createCounter(
"trpc.contentstack.header.ref.get-fail"
)
export const getHeaderCounter = meter.createCounter(
"trpc.contentstack.header.get"
)
export const getHeaderSuccessCounter = meter.createCounter(
"trpc.contentstack.header.get-success"
)
export const getHeaderFailCounter = meter.createCounter(
"trpc.contentstack.header.get-fail"
)
// OpenTelemetry metrics: CurrentFooter
export const getCurrentFooterRefCounter = meter.createCounter(
"trpc.contentstack.currentFooter.ref.get"
)
export const getCurrentFooterRefSuccessCounter = meter.createCounter(
"trpc.contentstack.currentFooter.ref.get-success"
)
export const getCurrentFooterRefFailCounter = meter.createCounter(
"trpc.contentstack.currentFooter.ref.get-fail"
)
export const getCurrentFooterCounter = meter.createCounter(
"trpc.contentstack.currentFooter.get"
)
export const getCurrentFooterSuccessCounter = meter.createCounter(
"trpc.contentstack.currentFooter.get-success"
)
export const getCurrentFooterFailCounter = meter.createCounter(
"trpc.contentstack.currentFooter.get-fail"
)
// OpenTelemetry metrics: Footer
export const getFooterRefCounter = meter.createCounter(
"trpc.contentstack.footer.ref.get"
)
export const getFooterRefSuccessCounter = meter.createCounter(
"trpc.contentstack.footer.ref.get-success"
)
export const getFooterRefFailCounter = meter.createCounter(
"trpc.contentstack.footer.ref.get-fail"
)
export const getFooterCounter = meter.createCounter(
"trpc.contentstack.footer.get"
)
export const getFooterSuccessCounter = meter.createCounter(
"trpc.contentstack.footer.get-success"
)
export const getFooterFailCounter = meter.createCounter(
"trpc.contentstack.footer.get-fail"
)
// OpenTelemetry metrics: SiteConfiguration
export const getSiteConfigurationCounter = meter.createCounter(
"trpc.contentstack.SiteConfiguration.get"
)
export const getSiteConfigurationSuccessCounter = meter.createCounter(
"trpc.contentstack.SiteConfiguration.get-success"
)
export const getSiteConfigurationFailCounter = meter.createCounter(
"trpc.contentstack.SiteConfiguration.get-fail"
)