-- 157_scrape_proxies.sql -- Хранилище пула прокси для скрейперов (#2161) — АДДИТИВНО. -- -- WHY: -- Сейчас прокси задаются через env (BROWSER_PROXY_AVITO/CIAN/YANDEX и т.п.) — -- один статичный URL на источник, без ротации/health/lease. Таблица даёт -- пул с per-provider affinity, health-трекингом и lease-полями под будущий -- pick/rotate-механизм. Данные (сами прокси с паролями) грузятся ЧЕРЕЗ ручку -- POST /api/v1/admin/proxies/bulk — в миграции секретов НЕТ. -- -- SCOPE (важно): -- Эта миграция ТОЛЬКО создаёт хранилище + индексы. Подключение к боевому -- сбору (pick/lease/rotate из пула вместо env) — отдельные шаги P3/P4. -- Ни один скрейпер здесь не трогается. -- -- IDEMPOTENCY / SAFETY: -- - Весь файл в одной транзакции BEGIN/COMMIT. -- - CREATE TABLE IF NOT EXISTS + CREATE INDEX IF NOT EXISTS → повторный -- прогон no-op (auto-apply strict на деплое это требует). -- - Пустая таблица после первого прогона — нормально; прокси загружаются -- оператором через admin-ручку. BEGIN; CREATE TABLE IF NOT EXISTS scrape_proxies ( id bigserial PRIMARY KEY, label text, url text NOT NULL UNIQUE, kind text NOT NULL DEFAULT 'http' CHECK (kind IN ('http', 'socks5')), provider_affinity text NOT NULL DEFAULT 'any' CHECK (provider_affinity IN ('avito', 'cian', 'yandex', 'generic', 'any')), rotate_url text, enabled boolean NOT NULL DEFAULT true, -- health last_check_at timestamptz, last_ok_at timestamptz, consecutive_fails integer NOT NULL DEFAULT 0, exit_ip text, latency_ms integer, -- lease (run_id арендатора; nullable = свободен) leased_by bigint, leased_at timestamptz, -- meta geo text, operator text, expires_at timestamptz, created_at timestamptz NOT NULL DEFAULT now(), updated_at timestamptz NOT NULL DEFAULT now() ); -- Подбор свободного прокси под провайдера: фильтр по affinity + enabled + свободности. CREATE INDEX IF NOT EXISTS idx_scrape_proxies_pick ON scrape_proxies (provider_affinity, enabled, leased_by); -- Health-скан: активные с накопленными фейлами. CREATE INDEX IF NOT EXISTS idx_scrape_proxies_health ON scrape_proxies (enabled, consecutive_fails); COMMIT;