| name | ee-billing |
| description | Surface workflow for billing in Grida — Stripe (subscriptions) + Metronome (AI credit ledger). The stable contracts: `grida_billing.*` is not REST-exposed (views/RPCs only), `fn_billing_apply_*` are the single mutation points, webhook receivers are `GRIDA-SEC-001`, BYOK is the `GRIDA-SEC-003` carve-out. Use when touching `editor/lib/billing/`, `editor/scripts/billing/`, the `grida_billing` schema, the webhook receivers, or the entitlement gate. Companion to `ee`.
|
ee-billing
This is the surface skill for billing — the workflow once the
ee anchor has placed billing on the EE side and
the contributor setup is done. Setup itself is documented; cite it,
don't restate it:
Stable surface (the contract)
These shapes are locked. A change that breaks any of them must be
intentional and called out in the PR description.
grida_billing.* schema — not REST-exposed. Public reads go
through v_billing_* views; writes only through fn_billing_*
RPCs. Don't add a new direct-access surface; add a view or an
RPC. Schema discipline lives in
database / supabase/AGENTS.md.
public.fn_billing_apply_stripe_event — the only place
Stripe-driven subscription state mutates. Mutating from a new
direction (UI form, ad-hoc RPC, hand-written migration) corrupts
the projector model.
public.fn_billing_apply_metronome_event — same role for
Metronome credit / alert / payment_gate events.
- Webhook receivers —
/webhooks/stripe and
/webhooks/metronome are the only billing ingress; both are
signature-verified per GRIDA-SEC-001.
editor/lib/billing/metronome.ts — the service module
surface: provisionOrg, addStripeChargedCommit, setAutoReload,
getEntitlement, ingestUsageEvent. New billing actions go
through this module, not adjacent to it.
Substrates
Two external clouds; both use per-contributor sandbox accounts.
Credentials are never shared. Live keys are refused at boot.
- Stripe — subscriptions + payment processing. Provision via
pnpm tsx editor/scripts/billing/cli.ts setup:stripe. Idempotent;
re-run after every supabase db reset (writes price IDs into the
catalog).
- Metronome — AI credit ledger. Provision via
pnpm tsx editor/scripts/billing/cli.ts setup:metronome. Same
idempotency / re-run rule.
editor/scripts/billing/cli.ts is the single entry point for every
billing script; run without arguments for the full subcommand list.
See editor/scripts/billing/README.md.
The seam: how OSS reads entitlement
OSS code that needs to gate on a paid plan, AI credit balance, or
org entitlement does not import billing internals. The seam is
getEntitlement (from editor/lib/billing/metronome.ts) and its
typed wrappers. New gates go through this function so fail-closed
and BYOK behavior stay centralized.
BYOK carve-out — GRIDA-SEC-003
If BYOK_OPENROUTER_API_KEY or BYOK_AI_GATEWAY_API_KEY is set in
editor/.env.local, the AI-SDK text path routes through the
contributor's provider and bypasses billing.
- Auth is never bypassed. A resolvable org is still required.
- Text/chat only. Image and audio still go through Replicate
and still bill, even under BYOK.
- Never set
BYOK_* on a hosted or preview deploy. It disables
billing and the org-id sanity gate for every org. See
SECURITY.md (GRIDA-SEC-003).
Working on billing
- Read docs/contributing/billing
for setup before the first change. Don't skip cloudflared if you
need Metronome — webhook delivery requires public HTTPS.
- Tag every billing file with
GRIDA-EE: billing per the
ee skill.
- Webhook receivers also carry
GRIDA-SEC-001 — the
security review runs first.
- Don't mutate
grida_billing.* outside fn_billing_apply_* or the
migration that creates it.
- Run the E2E suite before opening the PR (refuses to start unless
every channel is demonstrably test-mode):
pnpm --filter editor vitest run lib/billing/__tests__/e2e.
- For schema changes, the
database skill
governs — grida_billing is a regular grida_* schema under
that discipline.
Known issues
docs/wg/platform/billing/known-issues
is the living register (KI-BILL-NNN). Add to it when you mitigate
or accept an issue; don't quietly bake the mitigation into a PR
without registering it.
See also: ee (the EE anchor),
security (GRIDA-SEC-001,
GRIDA-SEC-003), database (schema
discipline for grida_billing).