feat: add unlimited option to tier limits
Use -1 as a sentinel meaning "no cap" in tier_definitions numeric columns. checkAndIncrementTierLimit skips the usage-cap WHERE clause when the limit is -1. Admin tier UI gets an Unlimited switch per field that disables the input and sends -1.
This commit is contained in:
@@ -9,6 +9,9 @@ function currentMonth() {
|
||||
|
||||
export type LimitKey = "recipe" | "aiCall" | "storage";
|
||||
|
||||
/** Sentinel stored in tier_definitions numeric columns to mean "no cap". */
|
||||
export const UNLIMITED = -1;
|
||||
|
||||
export class TierLimitError extends Error {
|
||||
constructor(public readonly limit: LimitKey, public readonly tier: string) {
|
||||
super(`Tier limit reached: ${limit} (tier: ${tier})`);
|
||||
@@ -42,12 +45,13 @@ export async function checkAndIncrementTierLimit(
|
||||
|
||||
if (key === "aiCall") {
|
||||
const limit = tierDef.aiCallsPerMonth;
|
||||
const cap = limit === UNLIMITED ? sql`true` : sql`user_usage.ai_calls_used < ${limit}`;
|
||||
const result = await db.execute(sql`
|
||||
INSERT INTO user_usage (id, user_id, month, ai_calls_used, recipe_count, storage_used_mb)
|
||||
VALUES (${id}, ${userId}, ${month}, 1, 0, 0)
|
||||
ON CONFLICT (user_id, month) DO UPDATE
|
||||
SET ai_calls_used = user_usage.ai_calls_used + 1
|
||||
WHERE user_usage.ai_calls_used < ${limit}
|
||||
WHERE ${cap}
|
||||
RETURNING ai_calls_used
|
||||
`);
|
||||
if (result.length === 0) {
|
||||
@@ -55,12 +59,13 @@ export async function checkAndIncrementTierLimit(
|
||||
}
|
||||
} else {
|
||||
const limit = tierDef.maxRecipes;
|
||||
const cap = limit === UNLIMITED ? sql`true` : sql`user_usage.recipe_count < ${limit}`;
|
||||
const result = await db.execute(sql`
|
||||
INSERT INTO user_usage (id, user_id, month, ai_calls_used, recipe_count, storage_used_mb)
|
||||
VALUES (${id}, ${userId}, ${month}, 0, 1, 0)
|
||||
ON CONFLICT (user_id, month) DO UPDATE
|
||||
SET recipe_count = user_usage.recipe_count + 1
|
||||
WHERE user_usage.recipe_count < ${limit}
|
||||
WHERE ${cap}
|
||||
RETURNING recipe_count
|
||||
`);
|
||||
if (result.length === 0) {
|
||||
|
||||
Reference in New Issue
Block a user