Files

42 lines
1.5 KiB
TypeScript
Raw Permalink Normal View History

import { eq } from "drizzle-orm"
import { db } from "@/lib/db"
import { profiles } from "@/lib/db/schema"
import { PLAN_LIMITS } from "@/lib/stripe/plans"
import { getUserStorageBytes } from "@/lib/storage"
import type { Plan } from "@/types"
/**
* Server-side plan-limit enforcement helpers. Single source of truth is
* PLAN_LIMITS in lib/stripe/plans.ts — never hardcode limit numbers in routes.
*/
/** The user's current plan (defaults to "starter" if no profile row). */
export async function getUserPlan(userId: string): Promise<Plan> {
const profile = await db.query.profiles.findFirst({
where: eq(profiles.id, userId),
columns: { plan: true },
})
return (profile?.plan ?? "starter") as Plan
}
/**
* Returns an error message if storing `incomingBytes` more would exceed the
* user's plan storage cap, otherwise null. Reads actual usage from the storage
* backend so it stays accurate regardless of which tables reference the files.
*/
export async function checkStorageLimit(
userId: string,
incomingBytes: number
): Promise<string | null> {
const plan = await getUserPlan(userId)
const maxBytes = PLAN_LIMITS[plan].maxStorageMB * 1024 * 1024
if (!Number.isFinite(maxBytes)) return null // unlimited plan
const used = await getUserStorageBytes(userId)
if (used + incomingBytes > maxBytes) {
const limitMb = PLAN_LIMITS[plan].maxStorageMB
return `Storage limit reached (${limitMb} MB on your plan). Upgrade for more space.`
}
return null
}