Skip to content

Commit 659b46f

Browse files
authored
improvement(consts): removed redundant default consts in favor of envvar defaults for storage & usage limits (#1737)
* improvement(consts): removed redundant default consts in favor of envvar defaults for storage & usage limits * remove unnecessary tests
1 parent fb3d6d4 commit 659b46f

File tree

11 files changed

+33
-99
lines changed

11 files changed

+33
-99
lines changed

apps/sim/app/workspace/[workspaceId]/w/components/sidebar/components/settings-modal/components/team-management/components/team-seats-overview/team-seats-overview.tsx

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,7 @@ import { Building2 } from 'lucide-react'
22
import { Button } from '@/components/ui/button'
33
import { Progress } from '@/components/ui/progress'
44
import { Skeleton } from '@/components/ui/skeleton'
5-
import { DEFAULT_TEAM_TIER_COST_LIMIT } from '@/lib/billing/constants'
6-
import { checkEnterprisePlan } from '@/lib/billing/subscriptions/utils'
7-
import { env } from '@/lib/env'
5+
import { checkEnterprisePlan, getTeamTierLimitPerSeat } from '@/lib/billing/subscriptions/utils'
86

97
type Subscription = {
108
id: string
@@ -102,7 +100,7 @@ export function TeamSeatsOverview({
102100
<span className='font-medium text-sm'>Seats</span>
103101
{!checkEnterprisePlan(subscriptionData) ? (
104102
<span className='text-muted-foreground text-xs'>
105-
(${env.TEAM_TIER_COST_LIMIT ?? DEFAULT_TEAM_TIER_COST_LIMIT}/month each)
103+
(${getTeamTierLimitPerSeat()}/month each)
106104
</span>
107105
) : null}
108106
</div>

apps/sim/app/workspace/[workspaceId]/w/components/sidebar/components/settings-modal/components/team-management/components/team-seats/team-seats.tsx

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,7 @@ import {
1717
SelectValue,
1818
} from '@/components/ui/select'
1919
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '@/components/ui/tooltip'
20-
import { DEFAULT_TEAM_TIER_COST_LIMIT } from '@/lib/billing/constants'
21-
import { env } from '@/lib/env'
20+
import { getTeamTierLimitPerSeat } from '@/lib/billing/subscriptions/utils'
2221

2322
interface TeamSeatsProps {
2423
open: boolean
@@ -55,7 +54,7 @@ export function TeamSeats({
5554
}
5655
}, [open, initialSeats])
5756

58-
const costPerSeat = env.TEAM_TIER_COST_LIMIT ?? DEFAULT_TEAM_TIER_COST_LIMIT
57+
const costPerSeat = getTeamTierLimitPerSeat()
5958
const totalMonthlyCost = selectedSeats * costPerSeat
6059
const costChange = currentSeats ? (selectedSeats - currentSeats) * costPerSeat : 0
6160

apps/sim/app/workspace/[workspaceId]/w/components/sidebar/components/settings-modal/components/team-management/team-management.tsx

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
11
import { useCallback, useEffect, useState } from 'react'
22
import { Alert, AlertDescription, AlertTitle, Skeleton } from '@/components/ui'
33
import { useSession } from '@/lib/auth-client'
4-
import { DEFAULT_TEAM_TIER_COST_LIMIT } from '@/lib/billing/constants'
5-
import { checkEnterprisePlan } from '@/lib/billing/subscriptions/utils'
6-
import { env } from '@/lib/env'
4+
import { checkEnterprisePlan, getTeamTierLimitPerSeat } from '@/lib/billing/subscriptions/utils'
75
import { createLogger } from '@/lib/logs/console/logger'
86
import {
97
MemberInvitationCard,
@@ -295,8 +293,7 @@ export function TeamManagement() {
295293
<ul className='ml-4 list-disc space-y-2 text-muted-foreground text-xs'>
296294
<li>
297295
Your team is billed a minimum of $
298-
{(subscriptionData?.seats || 0) *
299-
(env.TEAM_TIER_COST_LIMIT ?? DEFAULT_TEAM_TIER_COST_LIMIT)}
296+
{(subscriptionData?.seats || 0) * getTeamTierLimitPerSeat()}
300297
/month for {subscriptionData?.seats || 0} licensed seats
301298
</li>
302299
<li>All team member usage is pooled together from a shared limit</li>
@@ -414,7 +411,7 @@ export function TeamManagement() {
414411
open={isAddSeatDialogOpen}
415412
onOpenChange={setIsAddSeatDialogOpen}
416413
title='Add Team Seats'
417-
description={`Each seat costs $${env.TEAM_TIER_COST_LIMIT ?? DEFAULT_TEAM_TIER_COST_LIMIT}/month and provides $${env.TEAM_TIER_COST_LIMIT ?? DEFAULT_TEAM_TIER_COST_LIMIT} in monthly inference credits. Adjust the number of licensed seats for your team.`}
414+
description={`Each seat costs $${getTeamTierLimitPerSeat()}/month and provides $${getTeamTierLimitPerSeat()} in monthly inference credits. Adjust the number of licensed seats for your team.`}
418415
currentSeats={subscriptionData?.seats || 1}
419416
initialSeats={newSeatCount}
420417
isLoading={isUpdatingSeats}

apps/sim/hooks/use-subscription-state.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { useCallback, useEffect, useState } from 'react'
2-
import { DEFAULT_FREE_CREDITS } from '@/lib/billing/constants'
2+
import { getFreeTierLimit } from '@/lib/billing/subscriptions/utils'
33
import { createLogger } from '@/lib/logs/console/logger'
44

55
const logger = createLogger('useSubscriptionState')
@@ -82,7 +82,7 @@ export function useSubscriptionState() {
8282

8383
usage: {
8484
current: data?.usage?.current ?? 0,
85-
limit: data?.usage?.limit ?? DEFAULT_FREE_CREDITS,
85+
limit: data?.usage?.limit ?? getFreeTierLimit(),
8686
percentUsed: data?.usage?.percentUsed ?? 0,
8787
isWarning: data?.usage?.isWarning ?? false,
8888
isExceeded: data?.usage?.isExceeded ?? false,
@@ -203,9 +203,9 @@ export function useUsageLimit() {
203203
}
204204

205205
return {
206-
currentLimit: data?.currentLimit ?? DEFAULT_FREE_CREDITS,
206+
currentLimit: data?.currentLimit ?? getFreeTierLimit(),
207207
canEdit: data?.canEdit ?? false,
208-
minimumLimit: data?.minimumLimit ?? DEFAULT_FREE_CREDITS,
208+
minimumLimit: data?.minimumLimit ?? getFreeTierLimit(),
209209
plan: data?.plan ?? 'free',
210210
setBy: data?.setBy,
211211
updatedAt: data?.updatedAt ? new Date(data.updatedAt) : null,

apps/sim/lib/billing/constants.ts

Lines changed: 0 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,5 @@
1-
/**
2-
* Billing and cost constants shared between client and server code
3-
*/
4-
5-
/**
6-
* Fallback free credits (in dollars) when env var is not set
7-
*/
8-
export const DEFAULT_FREE_CREDITS = 10
9-
10-
/**
11-
* Default per-user minimum limits (in dollars) for paid plans when env vars are absent
12-
*/
13-
export const DEFAULT_PRO_TIER_COST_LIMIT = 20
14-
export const DEFAULT_TEAM_TIER_COST_LIMIT = 40
15-
export const DEFAULT_ENTERPRISE_TIER_COST_LIMIT = 200
16-
171
/**
182
* Base charge applied to every workflow execution
193
* This charge is applied regardless of whether the workflow uses AI models
204
*/
215
export const BASE_EXECUTION_CHARGE = 0.001
22-
23-
/**
24-
* Default threshold (in dollars) for incremental overage billing
25-
* When unbilled overage reaches this amount, an invoice item is created
26-
*/
27-
export const DEFAULT_OVERAGE_THRESHOLD = 50

apps/sim/lib/billing/storage/limits.ts

Lines changed: 7 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,9 @@
44
*/
55

66
import { db } from '@sim/db'
7-
import {
8-
DEFAULT_ENTERPRISE_STORAGE_LIMIT_GB,
9-
DEFAULT_FREE_STORAGE_LIMIT_GB,
10-
DEFAULT_PRO_STORAGE_LIMIT_GB,
11-
DEFAULT_TEAM_STORAGE_LIMIT_GB,
12-
} from '@sim/db/consts'
137
import { organization, subscription, userStats } from '@sim/db/schema'
148
import { eq } from 'drizzle-orm'
15-
import { getEnv } from '@/lib/env'
9+
import { env } from '@/lib/env'
1610
import { createLogger } from '@/lib/logs/console/logger'
1711

1812
const logger = createLogger('StorageLimits')
@@ -25,25 +19,16 @@ function gbToBytes(gb: number): number {
2519
}
2620

2721
/**
28-
* Get storage limits from environment variables with fallback to constants
22+
* Get storage limits from environment variables
2923
* Returns limits in bytes
24+
* Defaults are defined in env.ts and will be applied automatically
3025
*/
3126
export function getStorageLimits() {
3227
return {
33-
free: gbToBytes(
34-
Number.parseInt(getEnv('FREE_STORAGE_LIMIT_GB') || String(DEFAULT_FREE_STORAGE_LIMIT_GB))
35-
),
36-
pro: gbToBytes(
37-
Number.parseInt(getEnv('PRO_STORAGE_LIMIT_GB') || String(DEFAULT_PRO_STORAGE_LIMIT_GB))
38-
),
39-
team: gbToBytes(
40-
Number.parseInt(getEnv('TEAM_STORAGE_LIMIT_GB') || String(DEFAULT_TEAM_STORAGE_LIMIT_GB))
41-
),
42-
enterpriseDefault: gbToBytes(
43-
Number.parseInt(
44-
getEnv('ENTERPRISE_STORAGE_LIMIT_GB') || String(DEFAULT_ENTERPRISE_STORAGE_LIMIT_GB)
45-
)
46-
),
28+
free: gbToBytes(env.FREE_STORAGE_LIMIT_GB),
29+
pro: gbToBytes(env.PRO_STORAGE_LIMIT_GB),
30+
team: gbToBytes(env.TEAM_STORAGE_LIMIT_GB),
31+
enterpriseDefault: gbToBytes(env.ENTERPRISE_STORAGE_LIMIT_GB),
4732
}
4833
}
4934

@@ -78,7 +63,6 @@ export function getStorageLimitForPlan(plan: string, metadata?: any): number {
7863
*/
7964
export async function getUserStorageLimit(userId: string): Promise<number> {
8065
try {
81-
// Check if user is in a team/enterprise org
8266
const { getHighestPrioritySubscription } = await import('@/lib/billing/core/subscription')
8367
const sub = await getHighestPrioritySubscription(userId)
8468

@@ -92,9 +76,7 @@ export async function getUserStorageLimit(userId: string): Promise<number> {
9276
return limits.pro
9377
}
9478

95-
// Team/Enterprise: Use organization limit
9679
if (sub.plan === 'team' || sub.plan === 'enterprise') {
97-
// Get organization storage limit
9880
const orgRecord = await db
9981
.select({ metadata: subscription.metadata })
10082
.from(subscription)
@@ -108,7 +90,6 @@ export async function getUserStorageLimit(userId: string): Promise<number> {
10890
}
10991
}
11092

111-
// Default for team/enterprise
11293
return sub.plan === 'enterprise' ? limits.enterpriseDefault : limits.team
11394
}
11495

@@ -125,12 +106,10 @@ export async function getUserStorageLimit(userId: string): Promise<number> {
125106
*/
126107
export async function getUserStorageUsage(userId: string): Promise<number> {
127108
try {
128-
// Check if user is in a team/enterprise org
129109
const { getHighestPrioritySubscription } = await import('@/lib/billing/core/subscription')
130110
const sub = await getHighestPrioritySubscription(userId)
131111

132112
if (sub && (sub.plan === 'team' || sub.plan === 'enterprise')) {
133-
// Use organization storage
134113
const orgRecord = await db
135114
.select({ storageUsedBytes: organization.storageUsedBytes })
136115
.from(organization)
@@ -140,7 +119,6 @@ export async function getUserStorageUsage(userId: string): Promise<number> {
140119
return orgRecord.length > 0 ? orgRecord[0].storageUsedBytes || 0 : 0
141120
}
142121

143-
// Free/Pro: Use user stats
144122
const stats = await db
145123
.select({ storageUsedBytes: userStats.storageUsedBytes })
146124
.from(userStats)

apps/sim/lib/billing/subscriptions/utils.ts

Lines changed: 8 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,31 @@
1-
import {
2-
DEFAULT_ENTERPRISE_TIER_COST_LIMIT,
3-
DEFAULT_FREE_CREDITS,
4-
DEFAULT_PRO_TIER_COST_LIMIT,
5-
DEFAULT_TEAM_TIER_COST_LIMIT,
6-
} from '@/lib/billing/constants'
71
import { env } from '@/lib/env'
82

93
/**
10-
* Get the free tier limit from env or fallback to default
4+
* Get the free tier limit
115
*/
126
export function getFreeTierLimit(): number {
13-
return env.FREE_TIER_COST_LIMIT || DEFAULT_FREE_CREDITS
7+
return env.FREE_TIER_COST_LIMIT
148
}
159

1610
/**
17-
* Get the pro tier limit from env or fallback to default
11+
* Get the pro tier limit
1812
*/
1913
export function getProTierLimit(): number {
20-
return env.PRO_TIER_COST_LIMIT || DEFAULT_PRO_TIER_COST_LIMIT
14+
return env.PRO_TIER_COST_LIMIT
2115
}
2216

2317
/**
24-
* Get the team tier limit per seat from env or fallback to default
18+
* Get the team tier limit per seat
2519
*/
2620
export function getTeamTierLimitPerSeat(): number {
27-
return env.TEAM_TIER_COST_LIMIT || DEFAULT_TEAM_TIER_COST_LIMIT
21+
return env.TEAM_TIER_COST_LIMIT
2822
}
2923

3024
/**
31-
* Get the enterprise tier limit per seat from env or fallback to default
25+
* Get the enterprise tier limit per seat
3226
*/
3327
export function getEnterpriseTierLimitPerSeat(): number {
34-
return env.ENTERPRISE_TIER_COST_LIMIT || DEFAULT_ENTERPRISE_TIER_COST_LIMIT
28+
return env.ENTERPRISE_TIER_COST_LIMIT
3529
}
3630

3731
export function checkEnterprisePlan(subscription: any): boolean {

apps/sim/lib/billing/threshold-billing.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ import { db } from '@sim/db'
22
import { member, subscription, userStats } from '@sim/db/schema'
33
import { and, eq, inArray, sql } from 'drizzle-orm'
44
import type Stripe from 'stripe'
5-
import { DEFAULT_OVERAGE_THRESHOLD } from '@/lib/billing/constants'
65
import { calculateSubscriptionOverage, getPlanPricing } from '@/lib/billing/core/billing'
76
import { getHighestPrioritySubscription } from '@/lib/billing/core/subscription'
87
import { requireStripeClient } from '@/lib/billing/stripe-client'
@@ -11,7 +10,7 @@ import { createLogger } from '@/lib/logs/console/logger'
1110

1211
const logger = createLogger('ThresholdBilling')
1312

14-
const OVERAGE_THRESHOLD = env.OVERAGE_THRESHOLD_DOLLARS || DEFAULT_OVERAGE_THRESHOLD
13+
const OVERAGE_THRESHOLD = env.OVERAGE_THRESHOLD_DOLLARS
1514

1615
function parseDecimal(value: string | number | null | undefined): number {
1716
if (value === null || value === undefined) return 0

apps/sim/lib/env.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -41,16 +41,16 @@ export const env = createEnv({
4141
STRIPE_SECRET_KEY: z.string().min(1).optional(), // Stripe secret key for payment processing
4242
STRIPE_WEBHOOK_SECRET: z.string().min(1).optional(), // General Stripe webhook secret
4343
STRIPE_FREE_PRICE_ID: z.string().min(1).optional(), // Stripe price ID for free tier
44-
FREE_TIER_COST_LIMIT: z.number().optional(), // Cost limit for free tier users
44+
FREE_TIER_COST_LIMIT: z.number().optional().default(10), // Cost limit for free tier users (in dollars)
4545
FREE_STORAGE_LIMIT_GB: z.number().optional().default(5), // Storage limit in GB for free tier users
4646
STRIPE_PRO_PRICE_ID: z.string().min(1).optional(), // Stripe price ID for pro tier
47-
PRO_TIER_COST_LIMIT: z.number().optional(), // Cost limit for pro tier users
47+
PRO_TIER_COST_LIMIT: z.number().optional().default(20), // Cost limit for pro tier users (in dollars)
4848
PRO_STORAGE_LIMIT_GB: z.number().optional().default(50), // Storage limit in GB for pro tier users
4949
STRIPE_TEAM_PRICE_ID: z.string().min(1).optional(), // Stripe price ID for team tier
50-
TEAM_TIER_COST_LIMIT: z.number().optional(), // Cost limit for team tier users
50+
TEAM_TIER_COST_LIMIT: z.number().optional().default(40), // Cost limit per seat for team tier (in dollars)
5151
TEAM_STORAGE_LIMIT_GB: z.number().optional().default(500), // Storage limit in GB for team tier organizations (pooled)
5252
STRIPE_ENTERPRISE_PRICE_ID: z.string().min(1).optional(), // Stripe price ID for enterprise tier
53-
ENTERPRISE_TIER_COST_LIMIT: z.number().optional(), // Cost limit for enterprise tier users
53+
ENTERPRISE_TIER_COST_LIMIT: z.number().optional().default(200), // Cost limit per seat for enterprise tier (in dollars)
5454
ENTERPRISE_STORAGE_LIMIT_GB: z.number().optional().default(500), // Default storage limit in GB for enterprise tier (can be overridden per org)
5555
BILLING_ENABLED: z.boolean().optional(), // Enable billing enforcement and usage tracking
5656
OVERAGE_THRESHOLD_DOLLARS: z.number().optional().default(50), // Dollar threshold for incremental overage billing (default: $50)

apps/sim/stores/subscription/store.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { create } from 'zustand'
22
import { devtools } from 'zustand/middleware'
3-
import { DEFAULT_FREE_CREDITS } from '@/lib/billing/constants'
3+
import { getFreeTierLimit } from '@/lib/billing/subscriptions/utils'
44
import { createLogger } from '@/lib/logs/console/logger'
55
import type {
66
BillingStatus,
@@ -16,7 +16,7 @@ const CACHE_DURATION = 30 * 1000
1616

1717
const defaultUsage: UsageData = {
1818
current: 0,
19-
limit: DEFAULT_FREE_CREDITS,
19+
limit: getFreeTierLimit(),
2020
percentUsed: 0,
2121
isWarning: false,
2222
isExceeded: false,

0 commit comments

Comments
 (0)