mirror of
https://github.com/simstudioai/sim.git
synced 2026-01-08 22:48:14 -05:00
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
This commit is contained in:
@@ -2,9 +2,7 @@ import { Building2 } from 'lucide-react'
|
|||||||
import { Button } from '@/components/ui/button'
|
import { Button } from '@/components/ui/button'
|
||||||
import { Progress } from '@/components/ui/progress'
|
import { Progress } from '@/components/ui/progress'
|
||||||
import { Skeleton } from '@/components/ui/skeleton'
|
import { Skeleton } from '@/components/ui/skeleton'
|
||||||
import { DEFAULT_TEAM_TIER_COST_LIMIT } from '@/lib/billing/constants'
|
import { checkEnterprisePlan, getTeamTierLimitPerSeat } from '@/lib/billing/subscriptions/utils'
|
||||||
import { checkEnterprisePlan } from '@/lib/billing/subscriptions/utils'
|
|
||||||
import { env } from '@/lib/env'
|
|
||||||
|
|
||||||
type Subscription = {
|
type Subscription = {
|
||||||
id: string
|
id: string
|
||||||
@@ -102,7 +100,7 @@ export function TeamSeatsOverview({
|
|||||||
<span className='font-medium text-sm'>Seats</span>
|
<span className='font-medium text-sm'>Seats</span>
|
||||||
{!checkEnterprisePlan(subscriptionData) ? (
|
{!checkEnterprisePlan(subscriptionData) ? (
|
||||||
<span className='text-muted-foreground text-xs'>
|
<span className='text-muted-foreground text-xs'>
|
||||||
(${env.TEAM_TIER_COST_LIMIT ?? DEFAULT_TEAM_TIER_COST_LIMIT}/month each)
|
(${getTeamTierLimitPerSeat()}/month each)
|
||||||
</span>
|
</span>
|
||||||
) : null}
|
) : null}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -17,8 +17,7 @@ import {
|
|||||||
SelectValue,
|
SelectValue,
|
||||||
} from '@/components/ui/select'
|
} from '@/components/ui/select'
|
||||||
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '@/components/ui/tooltip'
|
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '@/components/ui/tooltip'
|
||||||
import { DEFAULT_TEAM_TIER_COST_LIMIT } from '@/lib/billing/constants'
|
import { getTeamTierLimitPerSeat } from '@/lib/billing/subscriptions/utils'
|
||||||
import { env } from '@/lib/env'
|
|
||||||
|
|
||||||
interface TeamSeatsProps {
|
interface TeamSeatsProps {
|
||||||
open: boolean
|
open: boolean
|
||||||
@@ -55,7 +54,7 @@ export function TeamSeats({
|
|||||||
}
|
}
|
||||||
}, [open, initialSeats])
|
}, [open, initialSeats])
|
||||||
|
|
||||||
const costPerSeat = env.TEAM_TIER_COST_LIMIT ?? DEFAULT_TEAM_TIER_COST_LIMIT
|
const costPerSeat = getTeamTierLimitPerSeat()
|
||||||
const totalMonthlyCost = selectedSeats * costPerSeat
|
const totalMonthlyCost = selectedSeats * costPerSeat
|
||||||
const costChange = currentSeats ? (selectedSeats - currentSeats) * costPerSeat : 0
|
const costChange = currentSeats ? (selectedSeats - currentSeats) * costPerSeat : 0
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +1,7 @@
|
|||||||
import { useCallback, useEffect, useState } from 'react'
|
import { useCallback, useEffect, useState } from 'react'
|
||||||
import { Alert, AlertDescription, AlertTitle, Skeleton } from '@/components/ui'
|
import { Alert, AlertDescription, AlertTitle, Skeleton } from '@/components/ui'
|
||||||
import { useSession } from '@/lib/auth-client'
|
import { useSession } from '@/lib/auth-client'
|
||||||
import { DEFAULT_TEAM_TIER_COST_LIMIT } from '@/lib/billing/constants'
|
import { checkEnterprisePlan, getTeamTierLimitPerSeat } from '@/lib/billing/subscriptions/utils'
|
||||||
import { checkEnterprisePlan } from '@/lib/billing/subscriptions/utils'
|
|
||||||
import { env } from '@/lib/env'
|
|
||||||
import { createLogger } from '@/lib/logs/console/logger'
|
import { createLogger } from '@/lib/logs/console/logger'
|
||||||
import {
|
import {
|
||||||
MemberInvitationCard,
|
MemberInvitationCard,
|
||||||
@@ -295,8 +293,7 @@ export function TeamManagement() {
|
|||||||
<ul className='ml-4 list-disc space-y-2 text-muted-foreground text-xs'>
|
<ul className='ml-4 list-disc space-y-2 text-muted-foreground text-xs'>
|
||||||
<li>
|
<li>
|
||||||
Your team is billed a minimum of $
|
Your team is billed a minimum of $
|
||||||
{(subscriptionData?.seats || 0) *
|
{(subscriptionData?.seats || 0) * getTeamTierLimitPerSeat()}
|
||||||
(env.TEAM_TIER_COST_LIMIT ?? DEFAULT_TEAM_TIER_COST_LIMIT)}
|
|
||||||
/month for {subscriptionData?.seats || 0} licensed seats
|
/month for {subscriptionData?.seats || 0} licensed seats
|
||||||
</li>
|
</li>
|
||||||
<li>All team member usage is pooled together from a shared limit</li>
|
<li>All team member usage is pooled together from a shared limit</li>
|
||||||
@@ -414,7 +411,7 @@ export function TeamManagement() {
|
|||||||
open={isAddSeatDialogOpen}
|
open={isAddSeatDialogOpen}
|
||||||
onOpenChange={setIsAddSeatDialogOpen}
|
onOpenChange={setIsAddSeatDialogOpen}
|
||||||
title='Add Team Seats'
|
title='Add Team Seats'
|
||||||
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.`}
|
description={`Each seat costs $${getTeamTierLimitPerSeat()}/month and provides $${getTeamTierLimitPerSeat()} in monthly inference credits. Adjust the number of licensed seats for your team.`}
|
||||||
currentSeats={subscriptionData?.seats || 1}
|
currentSeats={subscriptionData?.seats || 1}
|
||||||
initialSeats={newSeatCount}
|
initialSeats={newSeatCount}
|
||||||
isLoading={isUpdatingSeats}
|
isLoading={isUpdatingSeats}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { useCallback, useEffect, useState } from 'react'
|
import { useCallback, useEffect, useState } from 'react'
|
||||||
import { DEFAULT_FREE_CREDITS } from '@/lib/billing/constants'
|
import { getFreeTierLimit } from '@/lib/billing/subscriptions/utils'
|
||||||
import { createLogger } from '@/lib/logs/console/logger'
|
import { createLogger } from '@/lib/logs/console/logger'
|
||||||
|
|
||||||
const logger = createLogger('useSubscriptionState')
|
const logger = createLogger('useSubscriptionState')
|
||||||
@@ -82,7 +82,7 @@ export function useSubscriptionState() {
|
|||||||
|
|
||||||
usage: {
|
usage: {
|
||||||
current: data?.usage?.current ?? 0,
|
current: data?.usage?.current ?? 0,
|
||||||
limit: data?.usage?.limit ?? DEFAULT_FREE_CREDITS,
|
limit: data?.usage?.limit ?? getFreeTierLimit(),
|
||||||
percentUsed: data?.usage?.percentUsed ?? 0,
|
percentUsed: data?.usage?.percentUsed ?? 0,
|
||||||
isWarning: data?.usage?.isWarning ?? false,
|
isWarning: data?.usage?.isWarning ?? false,
|
||||||
isExceeded: data?.usage?.isExceeded ?? false,
|
isExceeded: data?.usage?.isExceeded ?? false,
|
||||||
@@ -203,9 +203,9 @@ export function useUsageLimit() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
currentLimit: data?.currentLimit ?? DEFAULT_FREE_CREDITS,
|
currentLimit: data?.currentLimit ?? getFreeTierLimit(),
|
||||||
canEdit: data?.canEdit ?? false,
|
canEdit: data?.canEdit ?? false,
|
||||||
minimumLimit: data?.minimumLimit ?? DEFAULT_FREE_CREDITS,
|
minimumLimit: data?.minimumLimit ?? getFreeTierLimit(),
|
||||||
plan: data?.plan ?? 'free',
|
plan: data?.plan ?? 'free',
|
||||||
setBy: data?.setBy,
|
setBy: data?.setBy,
|
||||||
updatedAt: data?.updatedAt ? new Date(data.updatedAt) : null,
|
updatedAt: data?.updatedAt ? new Date(data.updatedAt) : null,
|
||||||
|
|||||||
@@ -1,27 +1,5 @@
|
|||||||
/**
|
|
||||||
* Billing and cost constants shared between client and server code
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Fallback free credits (in dollars) when env var is not set
|
|
||||||
*/
|
|
||||||
export const DEFAULT_FREE_CREDITS = 10
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Default per-user minimum limits (in dollars) for paid plans when env vars are absent
|
|
||||||
*/
|
|
||||||
export const DEFAULT_PRO_TIER_COST_LIMIT = 20
|
|
||||||
export const DEFAULT_TEAM_TIER_COST_LIMIT = 40
|
|
||||||
export const DEFAULT_ENTERPRISE_TIER_COST_LIMIT = 200
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Base charge applied to every workflow execution
|
* Base charge applied to every workflow execution
|
||||||
* This charge is applied regardless of whether the workflow uses AI models
|
* This charge is applied regardless of whether the workflow uses AI models
|
||||||
*/
|
*/
|
||||||
export const BASE_EXECUTION_CHARGE = 0.001
|
export const BASE_EXECUTION_CHARGE = 0.001
|
||||||
|
|
||||||
/**
|
|
||||||
* Default threshold (in dollars) for incremental overage billing
|
|
||||||
* When unbilled overage reaches this amount, an invoice item is created
|
|
||||||
*/
|
|
||||||
export const DEFAULT_OVERAGE_THRESHOLD = 50
|
|
||||||
|
|||||||
@@ -4,15 +4,9 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import { db } from '@sim/db'
|
import { db } from '@sim/db'
|
||||||
import {
|
|
||||||
DEFAULT_ENTERPRISE_STORAGE_LIMIT_GB,
|
|
||||||
DEFAULT_FREE_STORAGE_LIMIT_GB,
|
|
||||||
DEFAULT_PRO_STORAGE_LIMIT_GB,
|
|
||||||
DEFAULT_TEAM_STORAGE_LIMIT_GB,
|
|
||||||
} from '@sim/db/consts'
|
|
||||||
import { organization, subscription, userStats } from '@sim/db/schema'
|
import { organization, subscription, userStats } from '@sim/db/schema'
|
||||||
import { eq } from 'drizzle-orm'
|
import { eq } from 'drizzle-orm'
|
||||||
import { getEnv } from '@/lib/env'
|
import { env } from '@/lib/env'
|
||||||
import { createLogger } from '@/lib/logs/console/logger'
|
import { createLogger } from '@/lib/logs/console/logger'
|
||||||
|
|
||||||
const logger = createLogger('StorageLimits')
|
const logger = createLogger('StorageLimits')
|
||||||
@@ -25,25 +19,16 @@ function gbToBytes(gb: number): number {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get storage limits from environment variables with fallback to constants
|
* Get storage limits from environment variables
|
||||||
* Returns limits in bytes
|
* Returns limits in bytes
|
||||||
|
* Defaults are defined in env.ts and will be applied automatically
|
||||||
*/
|
*/
|
||||||
export function getStorageLimits() {
|
export function getStorageLimits() {
|
||||||
return {
|
return {
|
||||||
free: gbToBytes(
|
free: gbToBytes(env.FREE_STORAGE_LIMIT_GB),
|
||||||
Number.parseInt(getEnv('FREE_STORAGE_LIMIT_GB') || String(DEFAULT_FREE_STORAGE_LIMIT_GB))
|
pro: gbToBytes(env.PRO_STORAGE_LIMIT_GB),
|
||||||
),
|
team: gbToBytes(env.TEAM_STORAGE_LIMIT_GB),
|
||||||
pro: gbToBytes(
|
enterpriseDefault: gbToBytes(env.ENTERPRISE_STORAGE_LIMIT_GB),
|
||||||
Number.parseInt(getEnv('PRO_STORAGE_LIMIT_GB') || String(DEFAULT_PRO_STORAGE_LIMIT_GB))
|
|
||||||
),
|
|
||||||
team: gbToBytes(
|
|
||||||
Number.parseInt(getEnv('TEAM_STORAGE_LIMIT_GB') || String(DEFAULT_TEAM_STORAGE_LIMIT_GB))
|
|
||||||
),
|
|
||||||
enterpriseDefault: gbToBytes(
|
|
||||||
Number.parseInt(
|
|
||||||
getEnv('ENTERPRISE_STORAGE_LIMIT_GB') || String(DEFAULT_ENTERPRISE_STORAGE_LIMIT_GB)
|
|
||||||
)
|
|
||||||
),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -78,7 +63,6 @@ export function getStorageLimitForPlan(plan: string, metadata?: any): number {
|
|||||||
*/
|
*/
|
||||||
export async function getUserStorageLimit(userId: string): Promise<number> {
|
export async function getUserStorageLimit(userId: string): Promise<number> {
|
||||||
try {
|
try {
|
||||||
// Check if user is in a team/enterprise org
|
|
||||||
const { getHighestPrioritySubscription } = await import('@/lib/billing/core/subscription')
|
const { getHighestPrioritySubscription } = await import('@/lib/billing/core/subscription')
|
||||||
const sub = await getHighestPrioritySubscription(userId)
|
const sub = await getHighestPrioritySubscription(userId)
|
||||||
|
|
||||||
@@ -92,9 +76,7 @@ export async function getUserStorageLimit(userId: string): Promise<number> {
|
|||||||
return limits.pro
|
return limits.pro
|
||||||
}
|
}
|
||||||
|
|
||||||
// Team/Enterprise: Use organization limit
|
|
||||||
if (sub.plan === 'team' || sub.plan === 'enterprise') {
|
if (sub.plan === 'team' || sub.plan === 'enterprise') {
|
||||||
// Get organization storage limit
|
|
||||||
const orgRecord = await db
|
const orgRecord = await db
|
||||||
.select({ metadata: subscription.metadata })
|
.select({ metadata: subscription.metadata })
|
||||||
.from(subscription)
|
.from(subscription)
|
||||||
@@ -108,7 +90,6 @@ export async function getUserStorageLimit(userId: string): Promise<number> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Default for team/enterprise
|
|
||||||
return sub.plan === 'enterprise' ? limits.enterpriseDefault : limits.team
|
return sub.plan === 'enterprise' ? limits.enterpriseDefault : limits.team
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -125,12 +106,10 @@ export async function getUserStorageLimit(userId: string): Promise<number> {
|
|||||||
*/
|
*/
|
||||||
export async function getUserStorageUsage(userId: string): Promise<number> {
|
export async function getUserStorageUsage(userId: string): Promise<number> {
|
||||||
try {
|
try {
|
||||||
// Check if user is in a team/enterprise org
|
|
||||||
const { getHighestPrioritySubscription } = await import('@/lib/billing/core/subscription')
|
const { getHighestPrioritySubscription } = await import('@/lib/billing/core/subscription')
|
||||||
const sub = await getHighestPrioritySubscription(userId)
|
const sub = await getHighestPrioritySubscription(userId)
|
||||||
|
|
||||||
if (sub && (sub.plan === 'team' || sub.plan === 'enterprise')) {
|
if (sub && (sub.plan === 'team' || sub.plan === 'enterprise')) {
|
||||||
// Use organization storage
|
|
||||||
const orgRecord = await db
|
const orgRecord = await db
|
||||||
.select({ storageUsedBytes: organization.storageUsedBytes })
|
.select({ storageUsedBytes: organization.storageUsedBytes })
|
||||||
.from(organization)
|
.from(organization)
|
||||||
@@ -140,7 +119,6 @@ export async function getUserStorageUsage(userId: string): Promise<number> {
|
|||||||
return orgRecord.length > 0 ? orgRecord[0].storageUsedBytes || 0 : 0
|
return orgRecord.length > 0 ? orgRecord[0].storageUsedBytes || 0 : 0
|
||||||
}
|
}
|
||||||
|
|
||||||
// Free/Pro: Use user stats
|
|
||||||
const stats = await db
|
const stats = await db
|
||||||
.select({ storageUsedBytes: userStats.storageUsedBytes })
|
.select({ storageUsedBytes: userStats.storageUsedBytes })
|
||||||
.from(userStats)
|
.from(userStats)
|
||||||
|
|||||||
@@ -1,37 +1,31 @@
|
|||||||
import {
|
|
||||||
DEFAULT_ENTERPRISE_TIER_COST_LIMIT,
|
|
||||||
DEFAULT_FREE_CREDITS,
|
|
||||||
DEFAULT_PRO_TIER_COST_LIMIT,
|
|
||||||
DEFAULT_TEAM_TIER_COST_LIMIT,
|
|
||||||
} from '@/lib/billing/constants'
|
|
||||||
import { env } from '@/lib/env'
|
import { env } from '@/lib/env'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the free tier limit from env or fallback to default
|
* Get the free tier limit
|
||||||
*/
|
*/
|
||||||
export function getFreeTierLimit(): number {
|
export function getFreeTierLimit(): number {
|
||||||
return env.FREE_TIER_COST_LIMIT || DEFAULT_FREE_CREDITS
|
return env.FREE_TIER_COST_LIMIT
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the pro tier limit from env or fallback to default
|
* Get the pro tier limit
|
||||||
*/
|
*/
|
||||||
export function getProTierLimit(): number {
|
export function getProTierLimit(): number {
|
||||||
return env.PRO_TIER_COST_LIMIT || DEFAULT_PRO_TIER_COST_LIMIT
|
return env.PRO_TIER_COST_LIMIT
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the team tier limit per seat from env or fallback to default
|
* Get the team tier limit per seat
|
||||||
*/
|
*/
|
||||||
export function getTeamTierLimitPerSeat(): number {
|
export function getTeamTierLimitPerSeat(): number {
|
||||||
return env.TEAM_TIER_COST_LIMIT || DEFAULT_TEAM_TIER_COST_LIMIT
|
return env.TEAM_TIER_COST_LIMIT
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the enterprise tier limit per seat from env or fallback to default
|
* Get the enterprise tier limit per seat
|
||||||
*/
|
*/
|
||||||
export function getEnterpriseTierLimitPerSeat(): number {
|
export function getEnterpriseTierLimitPerSeat(): number {
|
||||||
return env.ENTERPRISE_TIER_COST_LIMIT || DEFAULT_ENTERPRISE_TIER_COST_LIMIT
|
return env.ENTERPRISE_TIER_COST_LIMIT
|
||||||
}
|
}
|
||||||
|
|
||||||
export function checkEnterprisePlan(subscription: any): boolean {
|
export function checkEnterprisePlan(subscription: any): boolean {
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ import { db } from '@sim/db'
|
|||||||
import { member, subscription, userStats } from '@sim/db/schema'
|
import { member, subscription, userStats } from '@sim/db/schema'
|
||||||
import { and, eq, inArray, sql } from 'drizzle-orm'
|
import { and, eq, inArray, sql } from 'drizzle-orm'
|
||||||
import type Stripe from 'stripe'
|
import type Stripe from 'stripe'
|
||||||
import { DEFAULT_OVERAGE_THRESHOLD } from '@/lib/billing/constants'
|
|
||||||
import { calculateSubscriptionOverage, getPlanPricing } from '@/lib/billing/core/billing'
|
import { calculateSubscriptionOverage, getPlanPricing } from '@/lib/billing/core/billing'
|
||||||
import { getHighestPrioritySubscription } from '@/lib/billing/core/subscription'
|
import { getHighestPrioritySubscription } from '@/lib/billing/core/subscription'
|
||||||
import { requireStripeClient } from '@/lib/billing/stripe-client'
|
import { requireStripeClient } from '@/lib/billing/stripe-client'
|
||||||
@@ -11,7 +10,7 @@ import { createLogger } from '@/lib/logs/console/logger'
|
|||||||
|
|
||||||
const logger = createLogger('ThresholdBilling')
|
const logger = createLogger('ThresholdBilling')
|
||||||
|
|
||||||
const OVERAGE_THRESHOLD = env.OVERAGE_THRESHOLD_DOLLARS || DEFAULT_OVERAGE_THRESHOLD
|
const OVERAGE_THRESHOLD = env.OVERAGE_THRESHOLD_DOLLARS
|
||||||
|
|
||||||
function parseDecimal(value: string | number | null | undefined): number {
|
function parseDecimal(value: string | number | null | undefined): number {
|
||||||
if (value === null || value === undefined) return 0
|
if (value === null || value === undefined) return 0
|
||||||
|
|||||||
@@ -41,16 +41,16 @@ export const env = createEnv({
|
|||||||
STRIPE_SECRET_KEY: z.string().min(1).optional(), // Stripe secret key for payment processing
|
STRIPE_SECRET_KEY: z.string().min(1).optional(), // Stripe secret key for payment processing
|
||||||
STRIPE_WEBHOOK_SECRET: z.string().min(1).optional(), // General Stripe webhook secret
|
STRIPE_WEBHOOK_SECRET: z.string().min(1).optional(), // General Stripe webhook secret
|
||||||
STRIPE_FREE_PRICE_ID: z.string().min(1).optional(), // Stripe price ID for free tier
|
STRIPE_FREE_PRICE_ID: z.string().min(1).optional(), // Stripe price ID for free tier
|
||||||
FREE_TIER_COST_LIMIT: z.number().optional(), // Cost limit for free tier users
|
FREE_TIER_COST_LIMIT: z.number().optional().default(10), // Cost limit for free tier users (in dollars)
|
||||||
FREE_STORAGE_LIMIT_GB: z.number().optional().default(5), // Storage limit in GB for free tier users
|
FREE_STORAGE_LIMIT_GB: z.number().optional().default(5), // Storage limit in GB for free tier users
|
||||||
STRIPE_PRO_PRICE_ID: z.string().min(1).optional(), // Stripe price ID for pro tier
|
STRIPE_PRO_PRICE_ID: z.string().min(1).optional(), // Stripe price ID for pro tier
|
||||||
PRO_TIER_COST_LIMIT: z.number().optional(), // Cost limit for pro tier users
|
PRO_TIER_COST_LIMIT: z.number().optional().default(20), // Cost limit for pro tier users (in dollars)
|
||||||
PRO_STORAGE_LIMIT_GB: z.number().optional().default(50), // Storage limit in GB for pro tier users
|
PRO_STORAGE_LIMIT_GB: z.number().optional().default(50), // Storage limit in GB for pro tier users
|
||||||
STRIPE_TEAM_PRICE_ID: z.string().min(1).optional(), // Stripe price ID for team tier
|
STRIPE_TEAM_PRICE_ID: z.string().min(1).optional(), // Stripe price ID for team tier
|
||||||
TEAM_TIER_COST_LIMIT: z.number().optional(), // Cost limit for team tier users
|
TEAM_TIER_COST_LIMIT: z.number().optional().default(40), // Cost limit per seat for team tier (in dollars)
|
||||||
TEAM_STORAGE_LIMIT_GB: z.number().optional().default(500), // Storage limit in GB for team tier organizations (pooled)
|
TEAM_STORAGE_LIMIT_GB: z.number().optional().default(500), // Storage limit in GB for team tier organizations (pooled)
|
||||||
STRIPE_ENTERPRISE_PRICE_ID: z.string().min(1).optional(), // Stripe price ID for enterprise tier
|
STRIPE_ENTERPRISE_PRICE_ID: z.string().min(1).optional(), // Stripe price ID for enterprise tier
|
||||||
ENTERPRISE_TIER_COST_LIMIT: z.number().optional(), // Cost limit for enterprise tier users
|
ENTERPRISE_TIER_COST_LIMIT: z.number().optional().default(200), // Cost limit per seat for enterprise tier (in dollars)
|
||||||
ENTERPRISE_STORAGE_LIMIT_GB: z.number().optional().default(500), // Default storage limit in GB for enterprise tier (can be overridden per org)
|
ENTERPRISE_STORAGE_LIMIT_GB: z.number().optional().default(500), // Default storage limit in GB for enterprise tier (can be overridden per org)
|
||||||
BILLING_ENABLED: z.boolean().optional(), // Enable billing enforcement and usage tracking
|
BILLING_ENABLED: z.boolean().optional(), // Enable billing enforcement and usage tracking
|
||||||
OVERAGE_THRESHOLD_DOLLARS: z.number().optional().default(50), // Dollar threshold for incremental overage billing (default: $50)
|
OVERAGE_THRESHOLD_DOLLARS: z.number().optional().default(50), // Dollar threshold for incremental overage billing (default: $50)
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { create } from 'zustand'
|
import { create } from 'zustand'
|
||||||
import { devtools } from 'zustand/middleware'
|
import { devtools } from 'zustand/middleware'
|
||||||
import { DEFAULT_FREE_CREDITS } from '@/lib/billing/constants'
|
import { getFreeTierLimit } from '@/lib/billing/subscriptions/utils'
|
||||||
import { createLogger } from '@/lib/logs/console/logger'
|
import { createLogger } from '@/lib/logs/console/logger'
|
||||||
import type {
|
import type {
|
||||||
BillingStatus,
|
BillingStatus,
|
||||||
@@ -16,7 +16,7 @@ const CACHE_DURATION = 30 * 1000
|
|||||||
|
|
||||||
const defaultUsage: UsageData = {
|
const defaultUsage: UsageData = {
|
||||||
current: 0,
|
current: 0,
|
||||||
limit: DEFAULT_FREE_CREDITS,
|
limit: getFreeTierLimit(),
|
||||||
percentUsed: 0,
|
percentUsed: 0,
|
||||||
isWarning: false,
|
isWarning: false,
|
||||||
isExceeded: false,
|
isExceeded: false,
|
||||||
|
|||||||
@@ -8,15 +8,6 @@
|
|||||||
*/
|
*/
|
||||||
export const DEFAULT_FREE_CREDITS = 10
|
export const DEFAULT_FREE_CREDITS = 10
|
||||||
|
|
||||||
/**
|
|
||||||
* Storage limit constants (in GB)
|
|
||||||
* Can be overridden via environment variables
|
|
||||||
*/
|
|
||||||
export const DEFAULT_FREE_STORAGE_LIMIT_GB = 5
|
|
||||||
export const DEFAULT_PRO_STORAGE_LIMIT_GB = 50
|
|
||||||
export const DEFAULT_TEAM_STORAGE_LIMIT_GB = 500
|
|
||||||
export const DEFAULT_ENTERPRISE_STORAGE_LIMIT_GB = 500
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tag slots available for knowledge base documents and embeddings
|
* Tag slots available for knowledge base documents and embeddings
|
||||||
*/
|
*/
|
||||||
|
|||||||
Reference in New Issue
Block a user