mirror of
https://github.com/fluxerapp/fluxer
synced 2026-10-17 21:15:32 +09:00
feat(api): retire prices safely and add a self-serve switch (#2637)
This commit is contained in:
1 parent
d79cd99050
commit
4a93b677af
77 files changed
+9242
-2542
No files matched your search
@@ -221,6 +221,7 @@ function defaultConfig(): MasterConfig {
|
||||
secret_key: '',
|
||||
webhook_secret: '',
|
||||
prices: {},
|
||||
legacy_prices: {},
|
||||
},
|
||||
ncmec: {
|
||||
enabled: false,
|
||||
|
||||
@@ -268,6 +268,7 @@ export interface MasterConfig {
|
||||
secret_key: string;
|
||||
webhook_secret: string;
|
||||
prices?: Record<string, string | undefined>;
|
||||
legacy_prices?: Record<string, Array<string> | undefined>;
|
||||
};
|
||||
ncmec: {
|
||||
enabled: boolean;
|
||||
|
||||
@@ -155,4 +155,85 @@ describe('buildNamedFluxerEnvOverrides', () => {
|
||||
'FLUXER_LIVEKIT_DEFAULT_REGION must be valid JSON',
|
||||
);
|
||||
});
|
||||
|
||||
test('parses the legacy Stripe price map onto integrations.stripe.legacy_prices', () => {
|
||||
const overrides = buildNamedFluxerEnvOverrides({
|
||||
FLUXER_STRIPE_LEGACY_PRICES:
|
||||
'{"monthly_brl":["price_old_monthly_brl","price_older_monthly_brl"],"yearly_brl":["price_old_yearly_brl"],"monthly_try":["price_archived_monthly_try"],"gift_1_month_brl":["price_old_gift_1_month_brl"],"gift_1_year_brl":["price_old_gift_1_year_brl"]}',
|
||||
});
|
||||
|
||||
expect(overrides).toMatchObject({
|
||||
integrations: {
|
||||
stripe: {
|
||||
legacy_prices: {
|
||||
monthly_brl: ['price_old_monthly_brl', 'price_older_monthly_brl'],
|
||||
yearly_brl: ['price_old_yearly_brl'],
|
||||
monthly_try: ['price_archived_monthly_try'],
|
||||
gift_1_month_brl: ['price_old_gift_1_month_brl'],
|
||||
gift_1_year_brl: ['price_old_gift_1_year_brl'],
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
test('the legacy Stripe price map does not disturb the live price map', () => {
|
||||
const overrides = buildNamedFluxerEnvOverrides({
|
||||
FLUXER_STRIPE_PRICES: '{"monthly_brl":"price_new_monthly_brl"}',
|
||||
FLUXER_STRIPE_LEGACY_PRICES: '{"monthly_brl":["price_old_monthly_brl"]}',
|
||||
});
|
||||
|
||||
const stripe = (overrides.integrations as {stripe: Record<string, unknown>}).stripe;
|
||||
expect(stripe.prices).toEqual({monthly_brl: 'price_new_monthly_brl'});
|
||||
expect(stripe.legacy_prices).toEqual({monthly_brl: ['price_old_monthly_brl']});
|
||||
});
|
||||
|
||||
test('rejects malformed JSON for the legacy Stripe price map', () => {
|
||||
expect(() => buildNamedFluxerEnvOverrides({FLUXER_STRIPE_LEGACY_PRICES: '{"monthly_brl":['})).toThrow(
|
||||
'FLUXER_STRIPE_LEGACY_PRICES must be valid JSON',
|
||||
);
|
||||
});
|
||||
|
||||
test('an individual Stripe price env var wins over the blob, and the blob keys it does not name survive', () => {
|
||||
// The deploy runbook flips one slot at a time with FLUXER_STRIPE_PRICE_* while the blob stays
|
||||
// pinned to the previous release. The individual variable is declared after the blob, so it is
|
||||
// merged into the blob rather than replaced by it.
|
||||
const overrides = buildNamedFluxerEnvOverrides({
|
||||
FLUXER_STRIPE_PRICES:
|
||||
'{"monthly_brl":"price_blob_monthly_brl","yearly_brl":"price_blob_yearly_brl","monthly_usd":"price_blob_monthly_usd"}',
|
||||
FLUXER_STRIPE_PRICE_MONTHLY_BRL: 'price_individual_monthly_brl',
|
||||
});
|
||||
|
||||
expect((overrides.integrations as {stripe: {prices: unknown}}).stripe.prices).toEqual({
|
||||
monthly_brl: 'price_individual_monthly_brl',
|
||||
yearly_brl: 'price_blob_yearly_brl',
|
||||
monthly_usd: 'price_blob_monthly_usd',
|
||||
});
|
||||
});
|
||||
|
||||
test('several individual Stripe price env vars merge into the blob together', () => {
|
||||
const overrides = buildNamedFluxerEnvOverrides({
|
||||
FLUXER_STRIPE_PRICES: '{"monthly_brl":"price_blob_monthly_brl","yearly_brl":"price_blob_yearly_brl"}',
|
||||
FLUXER_STRIPE_PRICE_MONTHLY_BRL: 'price_individual_monthly_brl',
|
||||
FLUXER_STRIPE_PRICE_YEARLY_BRL: 'price_individual_yearly_brl',
|
||||
FLUXER_STRIPE_PRICE_MONTHLY_EUR: 'price_individual_monthly_eur',
|
||||
});
|
||||
|
||||
expect((overrides.integrations as {stripe: {prices: unknown}}).stripe.prices).toEqual({
|
||||
monthly_brl: 'price_individual_monthly_brl',
|
||||
yearly_brl: 'price_individual_yearly_brl',
|
||||
monthly_eur: 'price_individual_monthly_eur',
|
||||
});
|
||||
});
|
||||
|
||||
test('the Stripe price blob applies on its own when no individual price var is set', () => {
|
||||
const overrides = buildNamedFluxerEnvOverrides({
|
||||
FLUXER_STRIPE_PRICES: '{"monthly_brl":"price_blob_monthly_brl","yearly_brl":"price_blob_yearly_brl"}',
|
||||
});
|
||||
|
||||
expect((overrides.integrations as {stripe: {prices: unknown}}).stripe.prices).toEqual({
|
||||
monthly_brl: 'price_blob_monthly_brl',
|
||||
yearly_brl: 'price_blob_yearly_brl',
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -297,6 +297,7 @@ const NAMED_FLUXER_ENV_OVERRIDES: Record<string, NamedEnvOverride> = {
|
||||
FLUXER_STRIPE_SECRET_KEY: {path: ['integrations', 'stripe', 'secret_key']},
|
||||
FLUXER_STRIPE_WEBHOOK_SECRET: {path: ['integrations', 'stripe', 'webhook_secret']},
|
||||
FLUXER_STRIPE_PRICES: {path: ['integrations', 'stripe', 'prices'], parse: parseEnvValue},
|
||||
FLUXER_STRIPE_LEGACY_PRICES: {path: ['integrations', 'stripe', 'legacy_prices'], parse: parseEnvValue},
|
||||
FLUXER_STRIPE_PRICE_MONTHLY_USD: {path: ['integrations', 'stripe', 'prices', 'monthly_usd']},
|
||||
FLUXER_STRIPE_PRICE_MONTHLY_EUR: {path: ['integrations', 'stripe', 'prices', 'monthly_eur']},
|
||||
FLUXER_STRIPE_PRICE_MONTHLY_BRL: {path: ['integrations', 'stripe', 'prices', 'monthly_brl']},
|
||||
|
||||
Reference in new issue
Block a user