gendesign/tradein-mvp/backend/data/sql/157_scrape_proxies.sql
lekss361 90e4a741f7
Some checks failed
Deploy Trade-In / changes (push) Successful in 12s
Deploy Trade-In / build-browser (push) Has been skipped
Deploy Trade-In / build-frontend (push) Successful in 33s
Deploy Trade-In / test (push) Failing after 1m32s
Deploy Trade-In / build-backend (push) Has been skipped
Deploy Trade-In / deploy (push) Has been skipped
feat(proxy-pool): scrape_proxies table + admin bulk-load/list endpoints (#2161)
2026-07-02 16:31:21 +00:00

64 lines
3 KiB
PL/PgSQL
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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