mirror of
https://github.com/prowler-cloud/prowler.git
synced 2026-07-23 12:31:54 +00:00
refactor(ui): rename reserved billing flag to CLOUD_BILLING_ENABLED (#11920)
Co-authored-by: Pablo F.G <pablo.fernandez@prowler.com>
This commit is contained in:
committed by
GitHub
parent
2a077cae5e
commit
892cc2bc07
@@ -62,6 +62,7 @@ describe("lib/env gated integration validation", () => {
|
||||
"POSTHOG_KEY",
|
||||
"UI_POSTHOG_HOST",
|
||||
"POSTHOG_HOST",
|
||||
"CLOUD_BILLING_ENABLED",
|
||||
] as const;
|
||||
|
||||
beforeEach(() => {
|
||||
@@ -141,4 +142,30 @@ describe("lib/env gated integration validation", () => {
|
||||
|
||||
await expect(import("@/lib/env")).rejects.toThrow("POSTHOG_HOST");
|
||||
});
|
||||
|
||||
it("throws when CLOUD_BILLING_ENABLED is metronome but PostHog is not enabled", async () => {
|
||||
// metronome billing routes per tenant via the BILLING_SYSTEM_METRONOME
|
||||
// PostHog flag, so PostHog must be enabled.
|
||||
vi.stubEnv("CLOUD_BILLING_ENABLED", "metronome");
|
||||
|
||||
await expect(import("@/lib/env")).rejects.toThrow(
|
||||
"PostHog is required for per-tenant billing routing",
|
||||
);
|
||||
});
|
||||
|
||||
it("resolves when CLOUD_BILLING_ENABLED is metronome and PostHog is enabled", async () => {
|
||||
vi.stubEnv("CLOUD_BILLING_ENABLED", "metronome");
|
||||
vi.stubEnv("UI_POSTHOG_ENABLE", "true");
|
||||
vi.stubEnv("UI_POSTHOG_KEY", "phc_key");
|
||||
vi.stubEnv("UI_POSTHOG_HOST", "https://eu.i.posthog.com");
|
||||
|
||||
await expect(import("@/lib/env")).resolves.toBeDefined();
|
||||
});
|
||||
|
||||
it("resolves when CLOUD_BILLING_ENABLED is legacy without PostHog", async () => {
|
||||
// legacy billing forces V1 and never touches PostHog.
|
||||
vi.stubEnv("CLOUD_BILLING_ENABLED", "legacy");
|
||||
|
||||
await expect(import("@/lib/env")).resolves.toBeDefined();
|
||||
});
|
||||
});
|
||||
|
||||
+14
-1
@@ -2,7 +2,7 @@ import {
|
||||
assertGatedIntegrations,
|
||||
warnGatedIntegrationsMisconfig,
|
||||
} from "@/lib/integrations";
|
||||
import { readEnv } from "@/lib/runtime-env";
|
||||
import { readBoolEnv, readEnv } from "@/lib/runtime-env";
|
||||
|
||||
// Boot-time required-env assertion so a misconfigured container fails fast
|
||||
// with a clear message. A key with a deprecated legacy name is satisfied by
|
||||
@@ -23,6 +23,19 @@ for (const { key, legacy } of REQUIRED) {
|
||||
}
|
||||
|
||||
assertGatedIntegrations();
|
||||
|
||||
// `metronome` billing evaluates the BILLING_SYSTEM_METRONOME PostHog flag per
|
||||
// tenant, so PostHog must be enabled or every tenant would be misrouted to the
|
||||
// wrong billing system. Fail fast instead of degrading silently.
|
||||
if (
|
||||
readEnv("CLOUD_BILLING_ENABLED") === "metronome" &&
|
||||
!readBoolEnv("UI_POSTHOG_ENABLE")
|
||||
) {
|
||||
throw new Error(
|
||||
'CLOUD_BILLING_ENABLED is "metronome" but UI_POSTHOG_ENABLE is not "true"; PostHog is required for per-tenant billing routing.',
|
||||
);
|
||||
}
|
||||
|
||||
warnGatedIntegrationsMisconfig();
|
||||
|
||||
export {};
|
||||
|
||||
@@ -98,7 +98,7 @@ describe("getRuntimeConfigClient", () => {
|
||||
[
|
||||
"apiBaseUrl",
|
||||
"apiDocsUrl",
|
||||
"billingCloudEnable",
|
||||
"cloudBillingEnabled",
|
||||
"googleTagManagerId",
|
||||
"posthogHost",
|
||||
"posthogKey",
|
||||
@@ -108,9 +108,9 @@ describe("getRuntimeConfigClient", () => {
|
||||
].sort(),
|
||||
);
|
||||
expect(config.apiBaseUrl).toBe("https://api.example.com/api/v1");
|
||||
// billingCloudEnable is a boolean flag, so it defaults to false (not null)
|
||||
// cloudBillingEnabled is a boolean flag, so it defaults to false (not null)
|
||||
// when absent from the island.
|
||||
expect(config.billingCloudEnable).toBe(false);
|
||||
expect(config.cloudBillingEnabled).toBe(false);
|
||||
expect(
|
||||
(config as unknown as Record<string, unknown>).notAllowlisted,
|
||||
).toBeUndefined();
|
||||
|
||||
@@ -20,7 +20,7 @@ const pickConfig = (
|
||||
posthogKey: parsed.posthogKey ?? null,
|
||||
posthogHost: parsed.posthogHost ?? null,
|
||||
reoDevClientId: parsed.reoDevClientId ?? null,
|
||||
billingCloudEnable: parsed.billingCloudEnable ?? false,
|
||||
cloudBillingEnabled: parsed.cloudBillingEnabled ?? false,
|
||||
});
|
||||
|
||||
// Reads the <head> island once (memoized); all-null during SSR or if it's
|
||||
|
||||
@@ -9,7 +9,7 @@ export interface RuntimePublicConfig {
|
||||
posthogKey: string | null; // reserved
|
||||
posthogHost: string | null; // reserved
|
||||
reoDevClientId: string | null; // reserved
|
||||
billingCloudEnable: boolean;
|
||||
cloudBillingEnabled: boolean;
|
||||
}
|
||||
|
||||
export const RUNTIME_CONFIG_SCRIPT_ID = "__PROWLER_RUNTIME_CONFIG__";
|
||||
@@ -24,5 +24,5 @@ export const EMPTY_RUNTIME_PUBLIC_CONFIG: RuntimePublicConfig = {
|
||||
posthogKey: null,
|
||||
posthogHost: null,
|
||||
reoDevClientId: null,
|
||||
billingCloudEnable: false,
|
||||
cloudBillingEnabled: false,
|
||||
};
|
||||
|
||||
@@ -4,7 +4,7 @@ import { connection } from "next/server";
|
||||
|
||||
import { readGatedEnv } from "@/lib/integrations";
|
||||
import type { RuntimePublicConfig } from "@/lib/runtime-config.shared";
|
||||
import { readBoolEnv, readEnv } from "@/lib/runtime-env";
|
||||
import { readEnv } from "@/lib/runtime-env";
|
||||
|
||||
// `connection()` forces a per-request runtime read (never build-snapshotted);
|
||||
// only this allowlist reaches the client. Each migrated key falls back to its
|
||||
@@ -44,6 +44,10 @@ export async function getRuntimePublicConfig(): Promise<RuntimePublicConfig> {
|
||||
"POSTHOG_HOST",
|
||||
),
|
||||
reoDevClientId: readEnv("REO_DEV_CLIENT_ID"),
|
||||
billingCloudEnable: readBoolEnv("BILLING_CLOUD_ENABLE"),
|
||||
// Install-level selector "legacy" | "metronome" | "false"; the client only
|
||||
// needs on/off, so expose a derived boolean (the raw selector is read
|
||||
// server-side for V1/V2 routing). Default (unset) is off.
|
||||
cloudBillingEnabled:
|
||||
(readEnv("CLOUD_BILLING_ENABLED") ?? "false") !== "false",
|
||||
};
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@ export const RUNTIME_CONFIG_KEYS = [
|
||||
"posthogKey",
|
||||
"posthogHost",
|
||||
"reoDevClientId",
|
||||
"billingCloudEnable",
|
||||
"cloudBillingEnabled",
|
||||
] as const satisfies ReadonlyArray<keyof RuntimePublicConfig>;
|
||||
|
||||
/**
|
||||
|
||||
Vendored
+1
-1
@@ -28,7 +28,7 @@ declare global {
|
||||
NEXT_PUBLIC_SENTRY_ENVIRONMENT?: string;
|
||||
UI_SENTRY_ENVIRONMENT?: string;
|
||||
|
||||
BILLING_CLOUD_ENABLE?: "true" | "false";
|
||||
CLOUD_BILLING_ENABLED?: "legacy" | "metronome" | "false";
|
||||
|
||||
// Build-time public config
|
||||
NEXT_PUBLIC_IS_CLOUD_ENV?: "true" | "false";
|
||||
|
||||
Reference in New Issue
Block a user