All files / src/business plan.ts

0% Statements 0/28
100% Branches 1/1
100% Functions 1/1
0% Lines 0/28

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43                                                                                     
/**
 * User Subscription Plan Logic
 *
 * Centralized business logic for determining user subscription plans.
 */
 
import { logger } from "@snapback/infrastructure";
import { db } from "@snapback/platform";
import { subscriptions } from "@snapback/platform/db/schema/postgres";
import { eq } from "drizzle-orm";
 
export type SubscriptionPlan = "free" | "pro" | "team" | "enterprise";
 
/**
 * Get user's current subscription plan
 * @returns Plan name, defaults to "free" if no active subscription
 */
export async function getUserPlan(userId: string): Promise<SubscriptionPlan> {
	if (!db) {
		logger.warn("Database not available for plan lookup");
		return "free";
	}
	try {
		const sub = await db
			.select({ plan: subscriptions.plan, status: subscriptions.status })
			.from(subscriptions)
			.where(eq(subscriptions.userId, userId))
			.limit(1)
			.then((rows: { plan: string; status: string }[]) => rows[0] || null);
 
		if (sub && (sub.status === "active" || sub.status === "trialing")) {
			return sub.plan as SubscriptionPlan;
		}
		return "free";
	} catch (error) {
		logger.error("Failed to get user plan", {
			userId,
			error: error instanceof Error ? error.message : String(error),
		});
		return "free";
	}
}