diff --git a/apps/api/src/integrations/carcatonline/carcatonline.pacing.spec.ts b/apps/api/src/integrations/carcatonline/carcatonline.pacing.spec.ts index bb600b8..781da08 100644 --- a/apps/api/src/integrations/carcatonline/carcatonline.pacing.spec.ts +++ b/apps/api/src/integrations/carcatonline/carcatonline.pacing.spec.ts @@ -71,7 +71,7 @@ describe("night window (Europe/Istanbul, UTC+3)", () => { dailyCallCap: 100, windowStartHour: 20, windowEndHour: 7, - minIntervalMs: 2200, + minIntervalMs: 7000, }); }); }); diff --git a/apps/api/src/integrations/carcatonline/carcatonline.pacing.ts b/apps/api/src/integrations/carcatonline/carcatonline.pacing.ts index 71e5810..5c52923 100644 --- a/apps/api/src/integrations/carcatonline/carcatonline.pacing.ts +++ b/apps/api/src/integrations/carcatonline/carcatonline.pacing.ts @@ -3,7 +3,7 @@ * the API's on-demand parts fetch). All state lives in Redis so the API and the * worker share one budget: * - min interval between calls (measured 2026-09-26: ~110 calls at 1/2.2 s → 429 + ~40 min lockout; - * the quota looks like ~100 calls per window, so the default is 1 call / 6.5 s ≈ 9/min) + * the quota looks like ~100 calls per window, so the default is 1 call / 7 s ≈ 8.5/min) * - lockout flag set on any 429 * - per-Istanbul-day call counter with a hard cap * - the night window (default 20:00–07:00 Europe/Istanbul) for bulk work @@ -42,7 +42,7 @@ export function carcatConfigFromEnv(env: NodeJS.ProcessEnv = process.env): Carca return Number.isFinite(n) && n >= 0 ? n : d; }; return { - minIntervalMs: num(env.CARCATONLINE_MIN_INTERVAL_MS, 6500), + minIntervalMs: num(env.CARCATONLINE_MIN_INTERVAL_MS, 7000), dailyCallCap: num(env.CARCATONLINE_DAILY_CALL_CAP, 15000), windowStartHour: num(env.CARCATONLINE_WINDOW_START, 20), windowEndHour: num(env.CARCATONLINE_WINDOW_END, 7), diff --git a/docker-compose.coolify.yml b/docker-compose.coolify.yml index 1ba823c..66ec938 100644 --- a/docker-compose.coolify.yml +++ b/docker-compose.coolify.yml @@ -79,14 +79,14 @@ services: - RPARTSTORE_BROKER_URL=${RPARTSTORE_BROKER_URL:-wss://1po-bff.renault-edh.com/ws} - RPARTSTORE_APP_VERSION=${RPARTSTORE_APP_VERSION:-1.34.0.6} # carcatonline (PartsLink24 mirror) — night-window (20:00-07:00 Istanbul) category backfill - # for empty PL24 catalogs + on-demand parts; 1 call/2.2 s, 429 → 40 min lockout, daily cap. + # for empty PL24 catalogs + on-demand parts; 1 call/7 s (~100 calls/window quota), 429 → 40 min lockout, daily cap. - CARCATONLINE_ENABLED=${CARCATONLINE_ENABLED:-false} - CARCATONLINE_EMAIL=${CARCATONLINE_EMAIL:-} - CARCATONLINE_PASSWORD=${CARCATONLINE_PASSWORD:-} - CARCATONLINE_DAILY_CALL_CAP=${CARCATONLINE_DAILY_CALL_CAP:-15000} - CARCATONLINE_WINDOW_START=${CARCATONLINE_WINDOW_START:-20} - CARCATONLINE_WINDOW_END=${CARCATONLINE_WINDOW_END:-7} - - CARCATONLINE_MIN_INTERVAL_MS=${CARCATONLINE_MIN_INTERVAL_MS:-2200} + - CARCATONLINE_MIN_INTERVAL_MS=${CARCATONLINE_MIN_INTERVAL_MS:-7000} - CARCATONLINE_LOCKOUT_SECONDS=${CARCATONLINE_LOCKOUT_SECONDS:-2400} - CARCATONLINE_SCAN_BATCH=${CARCATONLINE_SCAN_BATCH:-20} - POSTAL_API_URL=${POSTAL_API_URL:-} @@ -255,14 +255,14 @@ services: - RPARTSTORE_BROKER_URL=${RPARTSTORE_BROKER_URL:-wss://1po-bff.renault-edh.com/ws} - RPARTSTORE_APP_VERSION=${RPARTSTORE_APP_VERSION:-1.34.0.6} # carcatonline (PartsLink24 mirror) — night-window (20:00-07:00 Istanbul) category backfill - # for empty PL24 catalogs + on-demand parts; 1 call/2.2 s, 429 → 40 min lockout, daily cap. + # for empty PL24 catalogs + on-demand parts; 1 call/7 s (~100 calls/window quota), 429 → 40 min lockout, daily cap. - CARCATONLINE_ENABLED=${CARCATONLINE_ENABLED:-false} - CARCATONLINE_EMAIL=${CARCATONLINE_EMAIL:-} - CARCATONLINE_PASSWORD=${CARCATONLINE_PASSWORD:-} - CARCATONLINE_DAILY_CALL_CAP=${CARCATONLINE_DAILY_CALL_CAP:-15000} - CARCATONLINE_WINDOW_START=${CARCATONLINE_WINDOW_START:-20} - CARCATONLINE_WINDOW_END=${CARCATONLINE_WINDOW_END:-7} - - CARCATONLINE_MIN_INTERVAL_MS=${CARCATONLINE_MIN_INTERVAL_MS:-2200} + - CARCATONLINE_MIN_INTERVAL_MS=${CARCATONLINE_MIN_INTERVAL_MS:-7000} - CARCATONLINE_LOCKOUT_SECONDS=${CARCATONLINE_LOCKOUT_SECONDS:-2400} - CARCATONLINE_SCAN_BATCH=${CARCATONLINE_SCAN_BATCH:-20} # Novu lifecycle e-mail automation — the worker fires trial-ending + win-back diff --git a/packages/config/src/index.ts b/packages/config/src/index.ts index b4f91a5..3bd8d8d 100644 --- a/packages/config/src/index.ts +++ b/packages/config/src/index.ts @@ -108,7 +108,7 @@ export const envSchema = z.object({ CARCATONLINE_DAILY_CALL_CAP: z.coerce.number().int().min(0).default(15000), CARCATONLINE_WINDOW_START: z.coerce.number().int().min(0).max(23).default(20), CARCATONLINE_WINDOW_END: z.coerce.number().int().min(0).max(23).default(7), - CARCATONLINE_MIN_INTERVAL_MS: z.coerce.number().int().min(500).default(2200), + CARCATONLINE_MIN_INTERVAL_MS: z.coerce.number().int().min(500).default(7000), CARCATONLINE_LOCKOUT_SECONDS: z.coerce.number().int().min(60).default(2400), CARCATONLINE_SCAN_BATCH: z.coerce.number().int().min(1).default(20),