// Effect-mode so it can `yield*` the billing service the framework provides in // the per-request stack. `requireEntitlement` consumes the tenant's metered // `projects` quota (free = 3) and fails typed `EntitlementExceeded` when it's // exhausted — BEFORE the row is written, so an over-quota create never leaves a // partial write. Upgrading to `pro` (via `billing.startCheckout`) lifts the cap // to `unlimited` and the same handler starts succeeding again. import { Effect } from 'effect' import type { AppContext } from '@voltro/runtime' import { EffectStore } from '@voltro/runtime' import { requireEntitlement } from '@voltro/plugin-billing' const execute = (input: { name: string }, ctx: AppContext) => Effect.gen(function* () { // 1. Billing gate — fails closed (typed EntitlementExceeded) when the // tenant has no `projects` quota left. Runs BEFORE the write. yield* requireEntitlement(ctx, 'projects', 1) // 2. Write the row. `tenant()` auto-stamps tenantId + audit columns. const store = yield* EffectStore const row = yield* store.insert('projects', { name: input.name }) return { id: row['id'] as string, name: row['name'] as string, tenantId: row['tenantId'] as string, } }) export default execute