(params: {
category: LimitCategory
billedUserId: string
workspaceId: string
currentUsage: number
limit: number
usageLabel: string
limitLabel: string
/** Re-arm only, never send — for usage-decrease callers. See {@link maybeSendLimitThresholdEmail}. */
rearmOnly?: boolean
subscription?: HighestPrioritySubscription | null
})
| 272 | * the `getHighestPrioritySubscription` lookup on hot paths; omit to fetch here. |
| 273 | */ |
| 274 | export async function maybeNotifyLimit(params: { |
| 275 | category: LimitCategory |
| 276 | billedUserId: string |
| 277 | workspaceId: string |
| 278 | currentUsage: number |
| 279 | limit: number |
| 280 | usageLabel: string |
| 281 | limitLabel: string |
| 282 | /** Re-arm only, never send — for usage-decrease callers. See {@link maybeSendLimitThresholdEmail}. */ |
| 283 | rearmOnly?: boolean |
| 284 | subscription?: HighestPrioritySubscription | null |
| 285 | }): Promise<void> { |
| 286 | try { |
| 287 | const sub = |
| 288 | params.subscription === undefined |
| 289 | ? await getHighestPrioritySubscription(params.billedUserId) |
| 290 | : params.subscription |
| 291 | const isOrg = Boolean(sub && isOrgScopedSubscription(sub, params.billedUserId)) |
| 292 | |
| 293 | const percent = params.limit > 0 ? (params.currentUsage / params.limit) * 100 : 0 |
| 294 | let userEmail: string | undefined |
| 295 | let userName: string | undefined |
| 296 | if (!isOrg && !params.rearmOnly && percent >= WARN_THRESHOLD) { |
| 297 | const [row] = await db |
| 298 | .select({ email: user.email, name: user.name }) |
| 299 | .from(user) |
| 300 | .where(eq(user.id, params.billedUserId)) |
| 301 | .limit(1) |
| 302 | userEmail = row?.email |
| 303 | userName = row?.name || undefined |
| 304 | } |
| 305 | |
| 306 | await maybeSendLimitThresholdEmail({ |
| 307 | category: params.category, |
| 308 | scope: isOrg ? 'organization' : 'user', |
| 309 | workspaceId: params.workspaceId, |
| 310 | currentUsage: params.currentUsage, |
| 311 | limit: params.limit, |
| 312 | usageLabel: params.usageLabel, |
| 313 | limitLabel: params.limitLabel, |
| 314 | rearmOnly: params.rearmOnly, |
| 315 | userId: params.billedUserId, |
| 316 | userEmail, |
| 317 | userName, |
| 318 | organizationId: isOrg ? sub?.referenceId : undefined, |
| 319 | }) |
| 320 | } catch (error) { |
| 321 | logger.error('Failed to resolve scope for usage-limit notification', { |
| 322 | category: params.category, |
| 323 | billedUserId: params.billedUserId, |
| 324 | error, |
| 325 | }) |
| 326 | } |
| 327 | } |
no test coverage detected