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