diff --git a/src/app/api/teams/[teamSlug]/metrics/types.ts b/src/app/api/teams/[teamSlug]/metrics/types.ts index d32af3573..429ceb9b7 100644 --- a/src/app/api/teams/[teamSlug]/metrics/types.ts +++ b/src/app/api/teams/[teamSlug]/metrics/types.ts @@ -1,6 +1,9 @@ import { z } from 'zod' import type { ClientTeamMetrics } from '@/core/modules/sandboxes/models.client' -import { MAX_DAYS_AGO } from '@/features/dashboard/sandboxes/monitoring/time-picker/constants' +import { + MAX_DAYS_AGO, + MAX_DAYS_AGO_BUFFER, +} from '@/features/dashboard/sandboxes/monitoring/time-picker/constants' export const TeamMetricsRequestSchema = z .object({ @@ -12,7 +15,7 @@ export const TeamMetricsRequestSchema = z .refine( (start) => { const now = Date.now() - return start >= now - MAX_DAYS_AGO + return start >= now - MAX_DAYS_AGO_BUFFER }, { message: `Start date cannot be more than ${MAX_DAYS_AGO / (1000 * 60 * 60 * 24)} days ago`, @@ -29,7 +32,7 @@ export const TeamMetricsRequestSchema = z }) .refine( (data) => { - return data.end - data.start <= MAX_DAYS_AGO + return data.end - data.start <= MAX_DAYS_AGO_BUFFER }, { message: `Date range cannot exceed ${MAX_DAYS_AGO / (1000 * 60 * 60 * 24)} days`, diff --git a/src/configs/mock-data.ts b/src/configs/mock-data.ts index bd8d40b57..864316a5a 100644 --- a/src/configs/mock-data.ts +++ b/src/configs/mock-data.ts @@ -1082,18 +1082,18 @@ export function calculateTeamMetricsStep( /** * Generate mock team metrics for monitoring charts * Supports small, medium, and large teams with realistic patterns - * Can generate data for the past 30 days from now + * Can generate data for the past 90 days from now */ export function generateMockTeamMetrics( startMs: number, endMs: number ): { metrics: ClientTeamMetrics; step: number } { const now = Date.now() - const thirtyDaysAgo = now - 30 * 24 * 60 * 60 * 1000 + const ninetyDaysAgo = now - 90 * 24 * 60 * 60 * 1000 - // Clamp start time to no earlier than 30 days ago - if (startMs < thirtyDaysAgo) { - startMs = thirtyDaysAgo + // Clamp start time to no earlier than 90 days ago + if (startMs < ninetyDaysAgo) { + startMs = ninetyDaysAgo } // Don't generate data beyond current time diff --git a/src/core/modules/sandboxes/schemas.ts b/src/core/modules/sandboxes/schemas.ts index 18b4d280c..2708019c1 100644 --- a/src/core/modules/sandboxes/schemas.ts +++ b/src/core/modules/sandboxes/schemas.ts @@ -1,5 +1,8 @@ import { z } from 'zod' -import { MAX_DAYS_AGO } from '@/features/dashboard/sandboxes/monitoring/time-picker/constants' +import { + MAX_DAYS_AGO, + MAX_DAYS_AGO_BUFFER, +} from '@/features/dashboard/sandboxes/monitoring/time-picker/constants' // PRIVATE @@ -12,7 +15,7 @@ const _startDateSchema = z (start) => { const now = Date.now() - return start >= now - MAX_DAYS_AGO + return start >= now - MAX_DAYS_AGO_BUFFER }, { message: `Start date cannot be more than ${MAX_DAYS_AGO / (1000 * 60 * 60 * 24)} days ago`, @@ -29,7 +32,7 @@ const _endDateSchema = z }) const _dateRangeRefine = (data: { startDate: number; endDate: number }) => { - return data.endDate - data.startDate <= MAX_DAYS_AGO + return data.endDate - data.startDate <= MAX_DAYS_AGO_BUFFER } const _dateRangeRefineMessage = { diff --git a/src/core/server/functions/sandboxes/get-team-metrics-max.ts b/src/core/server/functions/sandboxes/get-team-metrics-max.ts index 9a5a4a066..c3bfb667c 100644 --- a/src/core/server/functions/sandboxes/get-team-metrics-max.ts +++ b/src/core/server/functions/sandboxes/get-team-metrics-max.ts @@ -12,7 +12,10 @@ import { handleDefaultInfraError } from '@/core/server/actions/utils' import { infra } from '@/core/shared/clients/api' import { l } from '@/core/shared/clients/logger/logger' import { TeamSlugSchema } from '@/core/shared/schemas/team' -import { MAX_DAYS_AGO } from '@/features/dashboard/sandboxes/monitoring/time-picker/constants' +import { + MAX_DAYS_AGO, + MAX_DAYS_AGO_BUFFER, +} from '@/features/dashboard/sandboxes/monitoring/time-picker/constants' export const GetTeamMetricsMaxSchema = z .object({ @@ -26,7 +29,7 @@ export const GetTeamMetricsMaxSchema = z (start) => { const now = Date.now() - return start >= now - MAX_DAYS_AGO + return start >= now - MAX_DAYS_AGO_BUFFER }, { message: `Start date cannot be more than ${MAX_DAYS_AGO / (1000 * 60 * 60 * 24)} days ago`, @@ -44,7 +47,7 @@ export const GetTeamMetricsMaxSchema = z }) .refine( (data) => { - return data.endDate - data.startDate <= MAX_DAYS_AGO + return data.endDate - data.startDate <= MAX_DAYS_AGO_BUFFER }, { message: `Date range cannot exceed ${MAX_DAYS_AGO / (1000 * 60 * 60 * 24)} days`, diff --git a/src/core/server/functions/sandboxes/get-team-metrics.ts b/src/core/server/functions/sandboxes/get-team-metrics.ts index cc90ddacf..6031236a7 100644 --- a/src/core/server/functions/sandboxes/get-team-metrics.ts +++ b/src/core/server/functions/sandboxes/get-team-metrics.ts @@ -8,7 +8,10 @@ import { import { returnServerError } from '@/core/server/actions/utils' import { getPublicErrorMessage } from '@/core/shared/errors' import { TeamSlugSchema } from '@/core/shared/schemas/team' -import { MAX_DAYS_AGO } from '@/features/dashboard/sandboxes/monitoring/time-picker/constants' +import { + MAX_DAYS_AGO, + MAX_DAYS_AGO_BUFFER, +} from '@/features/dashboard/sandboxes/monitoring/time-picker/constants' import { getTeamMetricsCore } from './get-team-metrics-core' export const GetTeamMetricsSchema = z @@ -23,7 +26,7 @@ export const GetTeamMetricsSchema = z (start) => { const now = Date.now() - return start >= now - MAX_DAYS_AGO + return start >= now - MAX_DAYS_AGO_BUFFER }, { message: `Start date cannot be more than ${MAX_DAYS_AGO / (1000 * 60 * 60 * 24)} days ago`, @@ -40,7 +43,7 @@ export const GetTeamMetricsSchema = z }) .refine( (data) => { - return data.endDate - data.startDate <= MAX_DAYS_AGO + return data.endDate - data.startDate <= MAX_DAYS_AGO_BUFFER }, { message: `Date range cannot exceed ${MAX_DAYS_AGO / (1000 * 60 * 60 * 24)} days`, diff --git a/src/features/dashboard/sandboxes/monitoring/header.tsx b/src/features/dashboard/sandboxes/monitoring/header.tsx index 2e038efe0..5398ca536 100644 --- a/src/features/dashboard/sandboxes/monitoring/header.tsx +++ b/src/features/dashboard/sandboxes/monitoring/header.tsx @@ -86,7 +86,7 @@ export default function SandboxesMonitoringHeader({ Peak Concurrent Sandboxes
- (30-day max) + (90-day max)
diff --git a/src/features/dashboard/sandboxes/monitoring/hooks/use-timeframe.ts b/src/features/dashboard/sandboxes/monitoring/hooks/use-timeframe.ts index fe66cd2c9..828e01847 100644 --- a/src/features/dashboard/sandboxes/monitoring/hooks/use-timeframe.ts +++ b/src/features/dashboard/sandboxes/monitoring/hooks/use-timeframe.ts @@ -9,7 +9,7 @@ import { import { TIME_RANGES, type TimeRangeKey } from '@/lib/utils/timeframe' import { calculateIsLive } from '../utils' -const MAX_DAYS_AGO = 31 * 24 * 60 * 60 * 1000 +const MAX_DAYS_AGO = 90 * 24 * 60 * 60 * 1000 const MIN_RANGE_MS = 1.5 * 60 * 1000 const getStableNow = () => { diff --git a/src/features/dashboard/sandboxes/monitoring/time-picker/constants.ts b/src/features/dashboard/sandboxes/monitoring/time-picker/constants.ts index da73bb297..dd22d5799 100644 --- a/src/features/dashboard/sandboxes/monitoring/time-picker/constants.ts +++ b/src/features/dashboard/sandboxes/monitoring/time-picker/constants.ts @@ -67,10 +67,17 @@ export const TIME_OPTIONS: TimeOption[] = [ shortcut: '30D', rangeMs: 30 * 24 * 60 * 60 * 1000, }, + { + label: `Last 90 days`, + value: '90d', + shortcut: '90D', + rangeMs: 90 * 24 * 60 * 60 * 1000, + }, ] // constraints -export const MAX_DAYS_AGO = 31 * 24 * 60 * 60 * 1000 // 31 days in ms +export const MAX_DAYS_AGO = 90 * 24 * 60 * 60 * 1000 // 90 days in ms +export const MAX_DAYS_AGO_BUFFER = MAX_DAYS_AGO + 60 * 1000 // validation buffer to prevent preset race conditions export const MIN_RANGE_MS = 1.5 * 60 * 1000 // 1.5 minutes minimum export const CLOCK_SKEW_TOLERANCE = 60 * 1000 // 60 seconds export const DEFAULT_RANGE_MS = 60 * 60 * 1000 // 1 hour default diff --git a/src/features/dashboard/sandboxes/monitoring/time-picker/time-panel.tsx b/src/features/dashboard/sandboxes/monitoring/time-picker/time-panel.tsx index 8add8c0d7..669ece03a 100644 --- a/src/features/dashboard/sandboxes/monitoring/time-picker/time-panel.tsx +++ b/src/features/dashboard/sandboxes/monitoring/time-picker/time-panel.tsx @@ -153,7 +153,7 @@ export const TimePanel = forwardRef( const { minDate, maxDate } = useMemo(() => { const now = new Date() - // create new Date object for minDate (31 days ago) + // create new Date object for minDate (MAX_DAYS_AGO ago) const minDate = new Date(now.getTime() - MAX_DAYS_AGO) minDate.setHours(0, 0, 0, 0) diff --git a/src/features/dashboard/sandboxes/monitoring/time-picker/validation.ts b/src/features/dashboard/sandboxes/monitoring/time-picker/validation.ts index 89f904448..aebd430a5 100644 --- a/src/features/dashboard/sandboxes/monitoring/time-picker/validation.ts +++ b/src/features/dashboard/sandboxes/monitoring/time-picker/validation.ts @@ -4,7 +4,12 @@ import { z } from 'zod' import { combineDateTimeStrings } from '@/lib/utils/formatting' -import { CLOCK_SKEW_TOLERANCE, MAX_DAYS_AGO, MIN_RANGE_MS } from './constants' +import { + CLOCK_SKEW_TOLERANCE, + MAX_DAYS_AGO, + MAX_DAYS_AGO_BUFFER, + MIN_RANGE_MS, +} from './constants' export const customTimeFormSchema = z .object({ @@ -39,11 +44,11 @@ export const customTimeFormSchema = z const now = Date.now() const startTimestamp = startDateTime.getTime() - // validate start date is not more than 31 days ago - if (startTimestamp < now - MAX_DAYS_AGO) { + // validate start date is not more than MAX_DAYS_AGO + if (startTimestamp < now - MAX_DAYS_AGO_BUFFER) { ctx.addIssue({ code: z.ZodIssueCode.custom, - message: 'Start date cannot be more than 31 days ago', + message: `Start date cannot be more than ${MAX_DAYS_AGO / (1000 * 60 * 60 * 24)} days ago`, path: ['startDate'], }) return @@ -105,10 +110,10 @@ export const customTimeFormSchema = z } // ensure range doesn't exceed maximum - if (endTimestamp - startTimestamp > MAX_DAYS_AGO) { + if (endTimestamp - startTimestamp > MAX_DAYS_AGO_BUFFER) { ctx.addIssue({ code: z.ZodIssueCode.custom, - message: 'Date range cannot exceed 31 days', + message: `Date range cannot exceed ${MAX_DAYS_AGO / (1000 * 60 * 60 * 24)} days`, path: ['endDate'], }) return diff --git a/src/lib/utils/timeframe.ts b/src/lib/utils/timeframe.ts index fb73ba654..ade35e5d0 100644 --- a/src/lib/utils/timeframe.ts +++ b/src/lib/utils/timeframe.ts @@ -21,6 +21,7 @@ export const TIME_RANGES = { '6h': 1000 * 60 * 60 * 6, '24h': 1000 * 60 * 60 * 24, '30d': 1000 * 60 * 60 * 24 * 30, + '90d': 1000 * 60 * 60 * 24 * 90, } as const export type TimeRangeKey = keyof typeof TIME_RANGES