-- 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;
