Skip to content

Commit 38684b8

Browse files
authored
Use team limits instead of tiers (#172)
<!-- CURSOR_SUMMARY --> > [!NOTE] > Switches monitoring to use per-team limits via new `getTeamLimits` service (with memoized DB fetch) and updates Supabase types/schema accordingly. > > - **Server**: > - Add `getTeamLimits` action and memoized fetch `get-team-limits-memo` querying `public.team_limits`. > - Remove tier-based memo (`get-team-tier-limits-memo`) and related types; unify on `TeamLimits`. > - **UI (Monitoring)**: > - Update `charts.tsx` and header components to use `getTeamLimits` instead of tier limits. > - Minor: render LIMIT label with truthy check `!!(limit)`. > - **Types/Schema**: > - Refresh `src/types/database.types.ts` to add `public.team_limits` (and relationships) and adjust multiple table fields/requirements and functions/enums (e.g., `deployment_state`). > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 24d9272. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY -->
1 parent e7dfc15 commit 38684b8

File tree

8 files changed

+316
-189
lines changed

8 files changed

+316
-189
lines changed

bun.lock

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -151,11 +151,11 @@
151151
},
152152
},
153153
"overrides": {
154-
"@nodelib/fs.scandir": "2.1.5",
155-
"@nodelib/fs.stat": "2.0.5",
156154
"@shikijs/core": "2.3.2",
157155
"@shikijs/themes": "2.3.2",
158156
"shiki": "2.3.2",
157+
"@nodelib/fs.stat": "2.0.5",
158+
"@nodelib/fs.scandir": "2.1.5",
159159
"whatwg-url": "^13",
160160
},
161161
"packages": {

src/features/dashboard/sandboxes/monitoring/charts/charts.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import {
55
import { TEAM_METRICS_INITIAL_RANGE_MS } from '@/configs/intervals'
66
import { resolveTeamIdInServerComponent } from '@/lib/utils/server'
77
import { getTeamMetrics } from '@/server/sandboxes/get-team-metrics'
8-
import { getTeamTierLimits } from '@/server/team/get-team-tier-limits'
8+
import { getTeamLimits } from '@/server/team/get-team-limits'
99
import { Suspense } from 'react'
1010
import { TeamMetricsChartsProvider } from '../charts-context'
1111
import ConcurrentChartClient from './concurrent-chart'
@@ -60,7 +60,7 @@ async function TeamMetricsChartsResolver({
6060
startDate: start,
6161
endDate: end,
6262
}),
63-
getTeamTierLimits({ teamId }),
63+
getTeamLimits({ teamId }),
6464
])
6565

6666
if (

src/features/dashboard/sandboxes/monitoring/header.client.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ export function ConcurrentSandboxesClient({
3131
value={lastConcurrentSandboxes}
3232
className="prose-value-big mt-1"
3333
/>
34-
{limit && (
34+
{!!(limit) && (
3535
<span className="absolute right-3 bottom-3 md:right-6 md:bottom-4 text-fg-tertiary prose-label">
3636
LIMIT: {formatNumber(limit)}
3737
</span>

src/features/dashboard/sandboxes/monitoring/header.tsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { formatNumber } from '@/lib/utils/formatting'
33
import { getNowMemo, resolveTeamIdInServerComponent } from '@/lib/utils/server'
44
import { getTeamMetrics } from '@/server/sandboxes/get-team-metrics'
55
import { getTeamMetricsMax } from '@/server/sandboxes/get-team-metrics-max'
6-
import { getTeamTierLimits } from '@/server/team/get-team-tier-limits'
6+
import { getTeamLimits } from '@/server/team/get-team-limits'
77
import ErrorTooltip from '@/ui/error-tooltip'
88
import { SemiLiveBadge } from '@/ui/live'
99
import { Skeleton } from '@/ui/primitives/skeleton'
@@ -111,7 +111,7 @@ export const ConcurrentSandboxes = async ({
111111
startDate: start,
112112
endDate: now,
113113
}),
114-
getTeamTierLimits({ teamId }),
114+
getTeamLimits({ teamId }),
115115
])
116116

117117
if (!teamMetricsResult?.data || teamMetricsResult.serverError) {
@@ -179,7 +179,7 @@ export const MaxConcurrentSandboxes = async ({
179179
endDate: end,
180180
metric: 'concurrent_sandboxes',
181181
}),
182-
getTeamTierLimits({ teamId }),
182+
getTeamLimits({ teamId }),
183183
])
184184

185185
if (!teamMetricsResult?.data || teamMetricsResult.serverError) {
@@ -200,7 +200,7 @@ export const MaxConcurrentSandboxes = async ({
200200
<span className="prose-value-big mt-1">
201201
{formatNumber(concurrentSandboxes)}
202202
</span>
203-
{limit && (
203+
{!!(limit) && (
204204
<span className="absolute right-3 bottom-1 md:right-6 md:bottom-4 prose-label text-fg-tertiary ">
205205
LIMIT: {formatNumber(limit)}
206206
</span>
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
import 'server-cli-only'
2+
3+
import { l } from '@/lib/clients/logger/logger'
4+
import { supabaseAdmin } from '@/lib/clients/supabase/admin'
5+
import { cache } from 'react'
6+
import { serializeError } from 'serialize-error'
7+
import type { TeamLimits } from './get-team-limits'
8+
9+
/**
10+
* Internal function to fetch team limits from the database
11+
*/
12+
async function _getTeamLimits(
13+
teamId: string,
14+
userId: string
15+
): Promise<TeamLimits | null> {
16+
try {
17+
const { data: teamData, error: teamError } = await supabaseAdmin
18+
.from('team_limits')
19+
.select('*')
20+
.eq('id', teamId)
21+
.single()
22+
23+
if (teamError) {
24+
l.error({
25+
key: 'get_team_limits_memo:team_query_error',
26+
message: teamError.message,
27+
error: serializeError(teamError),
28+
team_id: teamId,
29+
user_id: userId,
30+
})
31+
return null
32+
}
33+
34+
if (!teamData) {
35+
l.error({
36+
key: 'get_team_limits_memo:no_team_data',
37+
message: 'No data found for team',
38+
team_id: teamId,
39+
user_id: userId,
40+
})
41+
return null
42+
}
43+
44+
return {
45+
concurrentInstances: teamData.concurrent_sandboxes || 0,
46+
diskMb: teamData.disk_mb || 0,
47+
maxLengthHours: teamData.max_length_hours || 0,
48+
maxRamMb: teamData.max_ram_mb || 0,
49+
maxVcpu: teamData.max_vcpu || 0,
50+
}
51+
} catch (error) {
52+
l.error({
53+
key: 'get_team_limits_memo:unexpected_error',
54+
message: 'Unexpected error fetching team limits',
55+
error: serializeError(error),
56+
team_id: teamId,
57+
user_id: userId,
58+
})
59+
return null
60+
}
61+
}
62+
63+
const getTeamLimitsMemo = cache(_getTeamLimits)
64+
65+
export default getTeamLimitsMemo

src/server/team/get-team-tier-limits.ts renamed to src/server/team/get-team-limits.ts

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,33 +4,31 @@ import { USE_MOCK_DATA } from '@/configs/flags'
44
import { authActionClient } from '@/lib/clients/action'
55
import { returnServerError } from '@/lib/utils/action'
66
import { z } from 'zod'
7-
import getTeamTierLimitsMemo from './get-team-tier-limits-memo'
7+
import getTeamLimitsMemo from './get-team-limits-memo'
88

9-
export interface TeamTierLimits {
9+
export interface TeamLimits {
1010
concurrentInstances: number
1111
diskMb: number
1212
maxLengthHours: number
1313
maxRamMb: number
1414
maxVcpu: number
15-
tierName: string
1615
}
1716

18-
const MOCK_TIER_LIMITS: TeamTierLimits = {
17+
const MOCK_TIER_LIMITS: TeamLimits = {
1918
concurrentInstances: 100_000,
2019
diskMb: 102400,
2120
maxLengthHours: 24,
2221
maxRamMb: 65536,
2322
maxVcpu: 32,
24-
tierName: 'Enterprise',
2523
}
2624

2725
const GetTeamTierLimitsSchema = z.object({
2826
teamId: z.uuid(),
2927
})
3028

31-
export const getTeamTierLimits = authActionClient
29+
export const getTeamLimits = authActionClient
3230
.schema(GetTeamTierLimitsSchema)
33-
.metadata({ serverFunctionName: 'getTeamTierLimits' })
31+
.metadata({ serverFunctionName: 'getTeamLimits' })
3432
.action(async ({ parsedInput, ctx }) => {
3533
const { user } = ctx
3634
const { teamId } = parsedInput
@@ -39,10 +37,10 @@ export const getTeamTierLimits = authActionClient
3937
return MOCK_TIER_LIMITS
4038
}
4139

42-
const tierLimits = await getTeamTierLimitsMemo(teamId, user.id)
40+
const tierLimits = await getTeamLimitsMemo(teamId, user.id)
4341

4442
if (!tierLimits) {
45-
return returnServerError('Failed to fetch team tier limits')
43+
return returnServerError('Failed to fetch team limits')
4644
}
4745

4846
return tierLimits

src/server/team/get-team-tier-limits-memo.ts

Lines changed: 0 additions & 81 deletions
This file was deleted.

0 commit comments

Comments
 (0)