Comfy-Org / Comfy-Org/ComfyUI_frontend
Consolidate billing_rail routing and document the legacy_stripe exit condition
- Dominant language
- TypeScript
- Stars
- 2k
- Forks
- 699
- Avg merge
- 1d 7h
- Merged PRs (30d)
- 490
Description
## Problem
After the rollout-flag retirement stack (#14612, #14613, #14614, #14615), Cloud billing
behaviour is a function of four inputs: distribution, whether the workspace is loaded, the
workspace type, and `billing_rail`. That decision is not expressed in one place, and two
call sites read the same `billing_rail` input with predicates that disagree.
`billing_rail` has three values, `'legacy_stripe' | 'metronome' | 'stripe'`
(`packages/ingest-types/src/types.gen.ts`, re-exported as `BillingRail` at
`src/platform/workspace/api/workspaceApi.ts:20-22`).
- `src/composables/billing/useBillingRouting.ts:32` asks `=== 'legacy_stripe'`, so
`metronome` routes to workspace billing.
- `src/platform/cloud/subscription/launchCancellationFlow.ts:30` asks `!== 'stripe'`, so
`metronome` takes the non-Churnkey fallback dialog.
A `metronome` workspace is therefore classified one way for billing routing and the other
way for cancellation. Neither site is wrong on its own; they simply encode different
questions about the same field, and nothing forces them to agree.
Both predicates predate the retirement stack. What changed is that the feature flags which
used to sit in front of them are gone, so `billing_rail` is now the sole discriminator and
these disagreements are no longer masked.
## Also worth capturing
`useBillingRouting` fails open. `activeWorkspaceBillingRail` is written only by
`useWorkspaceBilling.ts:174` and `useSubscription.ts:342`, only when `status.billing_rail`
is truthy, and it is a non-persisted `shallowRef`. The generated schema documents
`billing_rail` as omitted by older servers and billing-disabled deployments. So a failed
`/api/billing/status`, an omitted rail, and an unrecognised rail all resolve to
`'workspace'`.
Per the discussion on #14615 this is the intended final routing, not a defect. It should be
written down somewhere other than a review thread, because the previous safety net (flipping
`consolidated_billing_enabled` off server-side) no longer exists and recovery now requires a
frontend rollback.
## Suggested work
1. Put the routing decision in one place that both consumers call, so a rail value cannot be
classified two ways.
2. Make the union exhaustive at that single site, with an `assertNever` so a fourth
`billing_rail` value from the backend fails the build instead of silently falling through
to workspace billing.
3. Document the `legacy_stripe` exit condition: what has to be true for a personal workspace
to leave the legacy rail, who flips it, and what the frontend does in the window between
the backend flipping it and the next `/api/billing/status`.
4. Consider a short ADR. The repo already has ADR-0011 for auth invariants and ADR-0014 for
billing telemetry, and the FE/BE rollout-retirement contract from this stack currently
exists only in PR bodies.
## References
- Stack: #14612, #14613, #14614, #14615
- Raised while reviewing #14615: https://github.com/Comfy-Org/ComfyUI_frontend/pull/14615#pullrequestreview-4849151766
Contributor guide
Assessment
This issue has not been assessed yet.