Commit Graph
6 Commits
Author SHA1 Message Date
Neil ff64af20b0 fix(cloud-setup): the composer follows its setup session; billing reaches the control plane for GitHub
- The composer read the setup session with a bare readCloudSetupSession() call in render. The React
  Compiler memoizes that on the session id, so the panel kept its first (empty) read: rows never
  moved past 'In browser', the finished session never auto-started the workspace, and the GitHub
  row stayed 'Needed' after the browser said 'You're all set'. Read it through
  useCloudSetupSession (useSyncExternalStore with a per-poll cached snapshot) instead.
- Billing asked the control plane for the GitHub install URL with a plain fetch to its workers.dev
  origin. Same-account Workers can't do that (Cloudflare error 1042), so every setup GitHub step
  showed 'Orca Cloud setup is unavailable'. Bind the control plane as a service (SANDBOX_CONTROL)
  in the dev config and send the request through it when bound.

Found by the NP-4 end-to-end run (np4-e2e) on m4air against staging.
2026-11-10 14:32:37 -08:00
Neil c14d5856f2 feat(billing): cloud setup sessions (N1) and team-first Checkout (N4/O1)
Setup session API on the billing Worker: the desktop creates a session after
sign-in and polls its steps (account, team, plan/trial, github); the setup pages
on Orca Cloud auth redeem a one-time browser ticket, bind the team (granting the
trial through a port np4-trial's module plugs into), open Checkout that returns
to the setup pages, and ask the control plane for the GitHub install URL. The
control plane flips the GitHub step via POST /v1/internal/cloud-setup/github.

Checkout now refuses personal accounts with 409 team_required: a user: plan
could never move to a team later.
2026-11-10 06:07:27 -08:00
Neil dd34314dc0 feat(billing): bill overage by the minute, put sandboxes to sleep at the cap (U22, U24)
- Overage stays $1.00 per sandbox hour (ORCA_CLOUD_OVERAGE_CENTS_PER_HOUR) and is now billed by
  the minute: a per-minute metered TEST price (unit_amount_decimal = rate / 60 to 12 decimals,
  transform_quantity divide_by 60, round up), created the same way by stripe-test-setup.ts.
  capSeconds rounds the cap down to whole minutes and spentCents mirrors the invoice, so the
  cap math matches Stripe. The meter still counts seconds.
- Opting in re-prices an overage item still on an older price (e.g. $0.75 / h) instead of adding
  a second item on the same meter, and removes any extra stale one.
- Alerts at 75%, 90% and 100% of included hours (warnAtPercent).
- New top-level entitlement.suspendRunning: payment grace expired, or at the limit (out of hours
  with overage off, or at the spend cap). The start check and usage answers carry it, so the
  control plane puts running sandboxes to sleep (snapshot kept, never deleted). Payment fields and
  /v1/internal/suspensions stay payment-only, so no data-retention clock starts at a cap.
- Copy (desktop billing panel, plan card, build sheet, phone, CLI): "billed by the minute" after
  the rate; at the limit "Running sandboxes go to sleep and new ones can't start. Nothing is
  deleted, and your files are safe."
2026-11-10 04:33:07 -08:00
Neil dc0bf820ea feat(billing): overage $1.00 per sandbox hour (interim); plans.ts is the single source (setup script, e2e and spend-cap math read it); new Stripe TEST price 2026-11-10 01:26:39 -08:00
Neil 702ce21a21 feat(billing): dev Worker trusts staging auth and reads staging seat counts (dev only) 2026-11-09 07:01:19 -08:00
Neil c4550cc781 feat(billing): Team pricing, opt-in overage, Stripe test-mode e2e, dev deploy (#18)
* feat(billing): Team-only pricing, opt-in overage with spend cap, live Stripe test-mode e2e

- Catalog: Team $50/seat/mo or $480/seat/yr, 60 Standard h/seat/month pooled
  (monthly windows on annual plans), Large 2x, 3 running/seat, 15-min idle sleep;
  Enterprise is contact-only. All numbers/labels in BILLING_PLANS defaults.
- Overage is opt-in (adds the metered item), $0.75/h, monthly spend cap (default
  $25, admin-raisable) enforced in the meter outbox; 80%/100% usage warnings.
- Checkout: plan/interval/seats with adjustable quantity; portal configuration var.
- Workers reject fetch redirect 'error': use 'manual'. Log route errors.
- scripts/stripe-test-setup.ts creates the test catalog + portal configuration;
  scripts/e2e-test-mode.ts drives Checkout (headless, test card), overage, meter,
  cap, annual, test-clock renewal, payment failure and cancel.
- Desktop: Team/Enterprise cards with interval + seats, usage warnings, overage
  toggle + cap; split into copy/offers/usage modules.

* feat(billing): dev deployment config, dev operator keys, return page

- wrangler.dev.jsonc for orca-billing-dev (workers.dev, dev D1, test-mode prices).
- BILLING_DEV_JWKS (issuer orca-billing-dev-test) accepted only when BILLING_ENV
  is not prod, for e2e runs until auth mints billing tokens.
- GET /return: static 'return to Orca' page for Checkout/Portal redirects.
- Design doc: final pricing, dev URL and resources for the control plane.
2026-11-08 23:06:48 -08:00