(workspaceId: string)
| 108 | * @returns Table limits based on the workspace's billing plan |
| 109 | */ |
| 110 | export async function getWorkspaceTableLimits(workspaceId: string): Promise<TablePlanLimits> { |
| 111 | const cached = limitsCache.get(workspaceId) |
| 112 | if (cached) { |
| 113 | if (cached.expiresAt > Date.now()) return cached.limits |
| 114 | limitsCache.delete(workspaceId) |
| 115 | } |
| 116 | |
| 117 | const planLimits = getTablePlanLimits() |
| 118 | |
| 119 | try { |
| 120 | const billedAccountUserId = await getWorkspaceBilledAccountUserId(workspaceId) |
| 121 | |
| 122 | if (!billedAccountUserId) { |
| 123 | logger.warn('No billed account found for workspace, using free tier limits', { workspaceId }) |
| 124 | cacheLimits(workspaceId, planLimits.free) |
| 125 | return planLimits.free |
| 126 | } |
| 127 | |
| 128 | const subscription = await getHighestPrioritySubscription(billedAccountUserId) |
| 129 | const planName = getPlanTypeForLimits(subscription?.plan) as PlanName |
| 130 | |
| 131 | const limits = planLimits[planName] ?? planLimits.free |
| 132 | |
| 133 | logger.info('Retrieved workspace table limits', { |
| 134 | workspaceId, |
| 135 | billedAccountUserId, |
| 136 | planName, |
| 137 | limits, |
| 138 | }) |
| 139 | |
| 140 | cacheLimits(workspaceId, limits) |
| 141 | return limits |
| 142 | } catch (error) { |
| 143 | logger.error('Error getting workspace table limits, falling back to free tier', { |
| 144 | workspaceId, |
| 145 | error, |
| 146 | }) |
| 147 | return planLimits.free |
| 148 | } |
| 149 | } |
| 150 | |
| 151 | function cacheLimits(workspaceId: string, limits: TablePlanLimits): void { |
| 152 | // Keep the Map bounded for a new key: sweep expired entries, then (if a burst of |
no test coverage detected