Comfy-Org / Comfy-Org/ComfyUI_frontend
Define billing_rail semantics and the legacy_stripe exit condition
- Dominant language
- TypeScript
- Stars
- 2k
- Forks
- 699
- Avg merge
- 1d 7h
- Merged PRs (30d)
- 490
Description
## Problem
#14645 asks the frontend to consolidate `billing_rail` routing and **document the `legacy_stripe` exit condition**. Items 1 and 2 are frontend work and are actionable today. Item 3 is not: nothing in this repo can answer what the rail values mean or what moves a workspace between them, so #14645 will stall on it unless it is answered separately.
Filing that half here so it has its own owner rather than sitting as an unactionable sub-bullet on someone else's issue.
## What is needed
`billing_rail` is `'legacy_stripe' | 'metronome' | 'stripe'` (`packages/ingest-types/src/types.gen.ts`). The frontend now treats it as the **sole** discriminator for billing routing — the rollout flags that used to sit in front of it were retired in #14612, #14613, #14614, #14615.
1. **What distinguishes `metronome` from `stripe`, for a client?** Two call sites currently disagree, and neither is wrong on its face — `useBillingRouting.ts:32` asks `=== 'legacy_stripe'`, `launchCancellationFlow.ts:30` asks `!== 'stripe'`. They classify `metronome` oppositely. The answer determines which predicate is correct rather than which one we standardise on arbitrarily.
2. **What has to be true for a personal workspace to leave `legacy_stripe`?** Who or what flips it, is it self-service or an operator action, and is it reversible?
3. **What does the frontend do in the window between the backend flipping the rail and the next `/api/billing/status`?** The value is a non-persisted `shallowRef`; a stale tab holds the old rail until something refetches.
4. **Is a fourth rail value plausible?** #14645 proposes an `assertNever` so a new value fails the build instead of silently falling through. That is only the right call if new values are expected to be rare and coordinated.
5. **Rough population on `legacy_stripe` today.** Not needed for correctness, but the standup has carried "legacy rail: unify or retire?" as undecidable-without-volume for over a week, and nobody has pulled it.
## Why this is load-bearing now
`useBillingRouting` fails open. `activeWorkspaceBillingRail` is written only when `status.billing_rail` is truthy, and the generated schema documents the field 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 that is the intended final routing, not a defect. But the previous safety net — flipping `consolidated_billing_enabled` off server-side — no longer exists, so recovery from a misrouted cohort now requires a frontend rollback. That raises the cost of guessing wrong about rail semantics.
## Suggested outcome
A written answer on this issue is enough to unblock #14645. If it turns out to be more than a paragraph, a short ADR in `docs/adr/` alongside ADR-0011 (auth invariants) and ADR-0014 (billing telemetry) would be the better home — the FE/BE rollout-retirement contract from this stack currently exists only in PR bodies.
## References
- Blocks item 3 of #14645
- Flag-retirement stack: #14612, #14613, #14614, #14615
- Related contract question already with you: #14743
Contributor guide
Assessment
This issue has not been assessed yet.