Billing
Let internal and founder accounts use a metered product for free without special-casing call sites: an isOwner flag read from the user row, honored inside the debit itself.
1 file
Description
Let internal and founder accounts use a metered product for free without special-casing call sites: an isOwner flag read from the user row, honored inside the debit itself.
A credit-metered product where the founder, internal team, or demo accounts must never be charged, but every other user pays normally.
Store an isOwner boolean on the balance row and check it inside the deduct function, not at each call site. Every metered action already routes through deduct, so one check there covers the whole app and no feature can forget it.
export async function deduct(clerkId: string, amount: number, reason: string) {
const info = await getBalance(clerkId);
if (info.isOwner) return { ok: true, balance: info.balance, owner: true }; // never charged
// ... atomic conditional decrement for everyone else ...
}
Keep an OWNER_CLERK_ID env list of ids that are always owners. On balance lookup, if the id is in that list but the stored flag is stale (false), promote the row. This means a founder is free from the very first request, before anyone hand-sets a database flag, and a new environment inherits the bypass from config.
const envOwner = ownerEnvIds().has(clerkId);
if (envOwner && !row.isOwner) await db.update(balances).set({ isOwner: true }).where(eq(balances.clerkId, clerkId));
return { balance: row.balance, isOwner: row.isOwner || envOwner };
Return an owner: true marker from the debit so the UI can show "free (owner)" and traces can record that no credits were spent. A silent bypass makes it hard to tell a free owner action from a billing bug.
if (user.isOwner) return runAction() sprinkled everywhere) guarantees some path forgets it. Honor the flag once, inside the debit.Added 2026-07-01. Back to the Skill Library.

New tutorials, open-source projects, and deep dives on coding agents - delivered weekly.