feat(billing): resolve prices from the console behind a flag, with the compiled catalog as fallback (#304) - #467
Draft
mahesh-sangawar wants to merge 1 commit into
Draft
feat(billing): resolve prices from the console behind a flag, with the compiled catalog as fallback (#304)#467mahesh-sangawar wants to merge 1 commit into
mahesh-sangawar wants to merge 1 commit into
Conversation
…e compiled catalog as fallback (#304)
This was referenced Aug 29, 2026
Closed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Second half of #304 — the cutover. Deliberately a draft: not to be merged until the parallel run has been clean for several days. One clean check on deploy day is not "durably zero".
Shipped state is off. With
CONSOLE_CATALOG_AUTHORITATIVEunset, behaviour is byte-for-byte what it is today and the console read stays a comparison.Replace the data, keep the API
pricing.Sourceis a two-method interface installed viapricing.UseSource.LookupPPPOptionandDevelopedCurrencyOptionsconsult it first and fall through to the compiled catalog. No call site changes, no signature changes — the issue is explicit that deleting the package was never proposed.After #459 the surface is smaller than #392's original inventory:
update.goreads only lookup keys now, somoney.gois the only runtime reader of amounts.Declining is the entire safety design
The console Source answers only from a catalog it actually fetched. Cold, or failed with nothing cached, it returns
falseand pricing serves the compiled catalog. That fallthrough is the baked-snapshot cold start and the fail-open behaviour — there is no second mechanism, and none is wanted.It must never answer with a zero
Amount:money.goreads a zero as a real price, so a fabricated answer is silent mispricing, strictly worse than a slightly stale one.TestSource_ColdAndFailedDeclinesRatherThanAnsweringZeropins that.Fallthrough is per lookup, not wholesale, so a source carrying most currencies is not abandoned for the one it lacks.
Why a flag rather than a code-only cutover
This is the one code path that decides what a customer is charged. A flag makes reverting one variable and a restart, not a build-and-ship cycle. It also lets this merge safely while the evidence accumulates, so the cutover itself is a config change made deliberately on a day someone chooses.
Two startup decisions worth reviewing
The first refresh is synchronous. Installing the source before it holds a catalog would leave a window where every lookup falls through — harmless in effect, but the first seconds after a deploy would silently behave like the pre-cutover build, which is the kind of thing nobody notices until a price is wrong and the logs say everything was fine.
A failed first refresh is not fatal. The source installs anyway and declines until a refresh succeeds. A console outage must never stop this service starting.
Verification
go build,go vet, full unit suite greengo test -race -count=2clean onpricingandconsolecatalog— the source is installed at startup and refreshed by a ticker while requests read it, so a race here would be a data race on the price of a subscription./internal/billing/...and./internal/handlers/platformadmin/cleanTestSource_InstalledOverAnAgreeingCatalogChangesNothingasserts the property the parallel run has been proving — cutting over while the sources agree is a no-op at the point of useBefore merging
consolecatalog: parity clean differences=0in productionCONSOLE_CATALOG_MODEfor the cutover — currentlytest; live pricing needslive