chore: sync staging

This commit is contained in:
Esdras Renan 2025-11-10 01:57:45 -03:00
parent c5ddd54a3e
commit 561b19cf66
610 changed files with 105285 additions and 1206 deletions

View file

@ -18,6 +18,8 @@ const envSchema = z.object({
SMTP_ENABLE_STARTTLS_AUTO: z.string().optional(),
SMTP_TLS: z.string().optional(),
MAILER_SENDER_EMAIL: z.string().optional(),
REPORTS_CRON_SECRET: z.string().optional(),
REPORTS_CRON_BASE_URL: z.string().url().optional(),
})
const parsed = envSchema.safeParse(process.env)
@ -36,6 +38,8 @@ export const env = {
MACHINE_PROVISIONING_SECRET: parsed.data.MACHINE_PROVISIONING_SECRET,
MACHINE_TOKEN_TTL_MS: parsed.data.MACHINE_TOKEN_TTL_MS,
FLEET_SYNC_SECRET: parsed.data.FLEET_SYNC_SECRET,
REPORTS_CRON_SECRET: parsed.data.REPORTS_CRON_SECRET,
REPORTS_CRON_BASE_URL: parsed.data.REPORTS_CRON_BASE_URL,
SMTP: parsed.data.SMTP_ADDRESS && parsed.data.SMTP_USERNAME && parsed.data.SMTP_PASSWORD
? {
host: parsed.data.SMTP_ADDRESS,

View file

@ -1,5 +1,3 @@
export {}
declare global {
var __performanceMeasurePatched: boolean | undefined
}
@ -9,33 +7,53 @@ function isNegativeTimestampError(error: unknown): boolean {
return error.message.toLowerCase().includes("cannot have a negative time stamp")
}
if (typeof performance !== "undefined" && typeof performance.measure === "function") {
if (!globalThis.__performanceMeasurePatched) {
const originalMeasure = performance.measure.bind(performance)
performance.measure = ((name: string, startOrOptions?: string | PerformanceMeasureOptions, endMark?: string) => {
try {
return originalMeasure(name, startOrOptions as string | PerformanceMeasureOptions, endMark)
} catch (error) {
if (!isNegativeTimestampError(error)) {
throw error
}
// Next.js occasionally triggers an invalid interval when profiling slow routes.
// Clamp the measurement to start at 0 to avoid crashing the page.
if (typeof startOrOptions === "object" && startOrOptions) {
const safeOptions: PerformanceMeasureOptions = {
...startOrOptions,
start: 0,
}
try {
return originalMeasure(name, safeOptions, endMark)
} catch {
return undefined
}
}
return undefined
}
}) as typeof performance.measure
globalThis.__performanceMeasurePatched = true
export function ensurePerformanceMeasurePatched() {
if (typeof performance === "undefined" || typeof performance.measure !== "function") {
return
}
if (globalThis.__performanceMeasurePatched) {
return
}
const originalMeasure = performance.measure.bind(performance)
performance.measure = ((name: string, startOrOptions?: string | PerformanceMeasureOptions, endMark?: string) => {
try {
return originalMeasure(name, startOrOptions as string | PerformanceMeasureOptions, endMark)
} catch (error) {
if (!isNegativeTimestampError(error)) {
throw error
}
if (typeof startOrOptions === "object" && startOrOptions) {
const safeOptions: PerformanceMeasureOptions = {
...startOrOptions,
start: 0,
}
try {
return originalMeasure(name, safeOptions, endMark)
} catch {
return undefined
}
} else if (typeof startOrOptions === "string") {
try {
return originalMeasure(
name,
{
start: 0,
},
endMark
)
} catch {
return undefined
}
}
// swallow invalid marks when start/end names are missing
return undefined
}
}) as typeof performance.measure
globalThis.__performanceMeasurePatched = true
}
ensurePerformanceMeasurePatched()

View file

@ -0,0 +1,27 @@
export type ReportExportKey = "hours" | "backlog" | "sla" | "csat" | "tickets-by-channel"
export const REPORT_EXPORT_DEFINITIONS: Record<
ReportExportKey,
{ label: string; description: string }
> = {
hours: {
label: "Horas por cliente",
description: "Comparativo de horas internas/externas por empresa",
},
backlog: {
label: "Backlog geral",
description: "Distribuição por status, prioridade e fila",
},
sla: {
label: "Produtividade & SLA",
description: "Métricas de resposta, resolução e filas em atraso",
},
csat: {
label: "Satisfação (CSAT)",
description: "Notas médias, distribuição e respostas recentes",
},
"tickets-by-channel": {
label: "Tickets por canal",
description: "Evolução diária de criação por canal de entrada",
},
}

View file

@ -6,6 +6,8 @@ export const ticketSubcategorySchema = z.object({
slug: z.string().optional(),
order: z.number().optional(),
categoryId: z.string().optional(),
createdAt: z.number().optional(),
updatedAt: z.number().optional(),
})
export type TicketSubcategory = z.infer<typeof ticketSubcategorySchema>
@ -15,6 +17,8 @@ export const ticketCategorySchema = z.object({
slug: z.string().optional(),
description: z.string().optional().nullable(),
order: z.number().optional(),
createdAt: z.number().optional(),
updatedAt: z.number().optional(),
secondary: z.array(ticketSubcategorySchema),
})
export type TicketCategory = z.infer<typeof ticketCategorySchema>