feat(flags): server-side feature flags + upstream kill switches + live backfill config
Add server-side PostHog feature-flag evaluation to the API and wire three high-leverage uses. The flags live in PostHog (project 127747), dormant and fail-open, so this commit is a no-op until POSTHOG_PERSONAL_API_KEY is set and a switch is flipped. Phase 1 - upstream kill switches: PostHogService gains local flag evaluation (onlyEvaluateLocally + sendFeatureFlagEvents:false -> zero decode latency, no VIN leak) and isSourceLive(). Guards at each source's decode entry (parts-catalogs, emex, pl24 whole-source + per-brand via LEGACY_ARCH_SOURCE_TAG) let a flailing upstream be disabled from the PostHog UI in ~5s instead of a code-fix -> dev -> prod redeploy. Fail-open: any unresolved flag keeps the source live, so a PostHog outage can never black out decoding. Phase 2 - guarded rollout primitive: isEnabled()/variant() with VIN bucketing, ready to ramp a new decode/parser path 0->100% behind a decode-*-v2 flag (recipe in feature-flags-strategy.md). Phase 4 - remote-config ops tuning: prefetch-worker reads cfg-backfill-tuning to retune backfill batchSize/maxBacklog/businessHoursOnly live; malformed/missing -> the compiled-in constants. POSTHOG_PERSONAL_API_KEY wired into the api + worker compose blocks (empty -> flags inert, no added latency). Tests updated for the new constructor params. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -98,6 +98,11 @@ export const envSchema = z.object({
|
||||
// PostHog — product analytics (server-side)
|
||||
POSTHOG_API_KEY: z.string().optional(),
|
||||
POSTHOG_HOST: z.string().url().default("https://t.sase.tr"),
|
||||
// Personal API key (or feature-flags secure key) → enables LOCAL server-side
|
||||
// feature-flag evaluation: source kill switches, guarded decode rollout, and
|
||||
// remote-config ops tuning. Without it those flags fail open (no effect, no
|
||||
// added latency). Keep secret — never expose to the browser.
|
||||
POSTHOG_PERSONAL_API_KEY: z.string().optional(),
|
||||
|
||||
// Sentry — error tracking
|
||||
SENTRY_DSN: z.string().url().optional(),
|
||||
|
||||
Reference in New Issue
Block a user