Skip to content

Feature: Single Sandbox Resource Metrics#246

Open
ben-fornefeld wants to merge 61 commits intomainfrom
feature/single-sandbox-resource-metrics
Open

Feature: Single Sandbox Resource Metrics#246
ben-fornefeld wants to merge 61 commits intomainfrom
feature/single-sandbox-resource-metrics

Conversation

@ben-fornefeld
Copy link
Member

@ben-fornefeld ben-fornefeld commented Feb 25, 2026

Note

Medium Risk
Moderate risk due to new infra-backed metrics endpoint and a sizable new client-side charting/timeframe state flow; failures would primarily affect the new monitoring UI and query validation.

Overview
Adds a new Sandbox Monitoring page/tab (/dashboard/.../sandboxes/:sandboxId/monitoring) with interactive ECharts-based CPU/RAM/Disk time-series charts, hover readouts, brush-to-zoom, and live/preset/custom time-range controls that persist state via query params.

Introduces backend support for metrics via sandbox.resourceMetrics (validated time windows/retention) and a new repository call to infra GET /sandboxes/{sandboxID}/metrics (ms→s conversion, error mapping). Also refactors shared TimeRangePicker into time-range-picker.logic (parsing/normalization/bounds validation) and updates UsageTimeRangeControls to use the shared parsing + new bounds API.

Includes minor test stability fix for auth integration tests (global.fetch restore) plus new unit tests covering chart model building, monitoring timeframe normalization/query parsing, and time-range picker logic; updates theme graph colors and refreshes bun.lock (notably jsdom/agent deps).

Written by Cursor Bugbot for commit 3a7bcc4. This will update automatically on new commits. Configure here.

- Removed redundant wrapper in SandboxDetailsHeader for SandboxDetailsTitle.
- Updated DashboardLayoutHeader to ensure consistent rendering of ThemeSwitcher.
- Refactored logs handling in VirtualizedLogsBody to utilize state for scroll container, enhancing performance and readability.
- Adjusted event listeners for scroll handling to improve responsiveness.
}

return Math.round(value / (1024 * 1024))
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Inconsistent byte-to-megabyte conversion units in metrics

Medium Severity

toMegabytes divides by 1024 * 1024 assuming the input is in bytes, while formatBytesToGb also divides by 1024^3 assuming bytes. However, the SandboxDetailsDTO has fields named memoryMB and diskSizeMB, suggesting the API may return values in megabytes, not bytes. If memTotal/diskTotal from SandboxMetric are already in MB, both conversions would produce wildly incorrect values.

Additional Locations (1)

Fix in Cursor Fix in Web

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

invalid

Copy link

@cursor cursor bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 2 potential issues.

Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

@@ -1,4 +1,7 @@
import { millisecondsInDay } from 'date-fns/constants'
import { z } from 'zod'
import { SANDBOX_MONITORING_METRICS_RETENTION_MS } from '@/features/dashboard/sandbox/monitoring/utils/constants'
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Server router imports client feature module constant

Low Severity

The server-side tRPC router imports SANDBOX_MONITORING_METRICS_RETENTION_MS from a client feature module path (@/features/dashboard/sandbox/monitoring/utils/constants). This creates a coupling between server and client code layers. If that constants file ever adds a client-only import (e.g., React), the server bundle would break. The shared constant belongs in a shared/server-accessible location like @/configs or @/lib/constants.

Fix in Cursor Fix in Web

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fine

throw apiError(status)
}

return result.data
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Repository returns raw API data without mapping to expected array type

Medium Severity

getSandboxMetrics returns result.data directly from the infra API call without any mapping or shape validation. If the API response wraps metrics in an object (e.g., { metrics: [...] }), the router would return that wrapper object instead of SandboxMetric[]. The controller's useQuery<SandboxMetric[]> type assertion would mask this mismatch at compile time, but the chart would receive no usable data at runtime. Every other repository function in this file maps its response (e.g., mapInfraSandboxDetailsToDTO), but this one does not.

Additional Locations (1)

Fix in Cursor Fix in Web

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fine

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant