Floxy residential proxy bitince/çökünce (402 bakiye veya tünel reddi —
ERR_TUNNEL_CONNECTION_FAILED), EMEX + pcat decode istekleri ölü proxy'ye
çarpıp decode başarı oranını çökertiyordu (2026-06-13: ~17k tünel hatası/24s,
decode %78→%45). Önceki "DataImpulse last-ditch fallback" tarayıcı yolunda hiç
yoktu ve HTTP yolunda her istekte 2 ölü Floxy denemesi ziyan ediyordu.
Paylaşılan ProxyHealthService kapısı (in-memory cooldown): herhangi bir tüketici
bir Floxy bağlantı hatası görünce kapıyı tetikler; cooldown boyunca TÜM tüketiciler
DataImpulse'a düşer. Floxy'den ilk başarılı yanıt veya cooldown bitişi kapıyı
temizler (kendi kendini iyileştirir, periyodik yeniden-deneme). FLOXY_FAILOVER_COOLDOWN_MS
ile ayarlanır (varsayılan 180s).
Bağlanan tüketiciler:
- EMEX HTTP (fetchEmexHtml): kapı açıkken DataImpulse-öncelikli zamanlama
- EMEX tarayıcı (Playwright): launch'ta dinamik sağlayıcı seçimi + ensureSession
health-gate'i (Floxy ölünce DataImpulse'a relaunch, kapı temizlenince Floxy'i
yeniden dene); scrape-içi tünel ölümünde tripFloxyFailover
- pcat (buildProxy): hem call hem capture (Playwright JWT) bacakları DataImpulse'a düşer
isProxyConnectFailure(): yalnız gerçek bağlantı hatalarında tetikler — yavaş-ama-
canlı exit'in nav timeout'u failover'ı tetiklemez.
Test: ProxyHealthService + isProxyConnectFailure birim testleri; tüm api suite (303) yeşil.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
One row per proxied upstream attempt (pcat call/capture/validate, emex http)
written fire-and-forget by the new ProxyTelemetryService (buffered, capped,
errors swallowed — telemetry can never hurt the request path).
- banned = upstream 403/429 (IP-block signal), distinct from auth/data errors
- sticky legs (pcat capture, emex floxy) carry a session_key; pcat capture
also resolves the actual residential exit IP via a parallel ipify probe
through the same sticky session → concrete banned-IP tracking
- rotating legs log provider + outcome (ban *rate* instead of per-IP)
- 30-day retention piggybacked on the query-cleanup job
Feeds the Süper Panel /analytics/proxy page (provider grading + banned IPs).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
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>
ConfigService.get<number>("EMEX_PROXY_PORT_START") returns the raw env
STRING; the port-pick arithmetic then string-concatenated it
(45 + "10001" = "4510001"), producing an out-of-range port that made
undici's `new URL` throw "Invalid URL" at EmexService construction —
crashing the entire API on boot.
A single-port range (823) happened to concat to a still-parseable "0823",
which masked the bug for months. It surfaced the moment the prod
EMEX_PROXY_PORT range was widened (823 -> 10001-10099) to let Q1's
per-request port rotation work: prod crash-looped until the env was
reverted. Coerce to a validated integer port (1-65535) with default
fallback so a real range is safe.
Regression test: constructing EmexService with string port env over a
real range must not throw.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>