Оба места утверждали, что у Домклика один выделенный резидентный прокси и пула нет. Это перестало быть правдой ещё в #2800 (миграция 253 сняла резервацию узла), но текст остался — и именно на него опирался тикет #3189, поставленный под «калибровку» ограничения, которого не существует. Свип к тому же ходит через пул давно (serp.py:359), а бэкфилл подключён к нему в PR #3222. Заодно докстринг называл не тот ограничитель: свип кладёт не счётчик провалов lease, а break по первому DomClickBlockedError (#2854) — до ротации дело не доходит ни при каком счётчике, отсюда buckets_completed=0. Только комментарии, поведение не меняется. Миграция 175 уже применена, а _schema_migrations трекает по имени файла без checksum — правка текста её не перезапустит.
66 lines
2.8 KiB
PL/PgSQL
66 lines
2.8 KiB
PL/PgSQL
-- 90_user_weight_profiles.sql
|
||
-- User-defined POI weight profiles для site_finder/analyze_parcel.
|
||
-- Per #114 (Макс feedback): разные веса для разных категорий (садики ≠ Мегамарт).
|
||
--
|
||
-- Apply order: после 89_drop_dead_brin_rosreestr_deals.sql
|
||
-- Dependencies: нет (standalone table, no FK to other tables)
|
||
--
|
||
-- POI categories compatible with _POI_WEIGHTS in backend/app/api/v1/parcels.py:
|
||
-- school, kindergarten, pharmacy, hospital, shop_mall, shop_supermarket,
|
||
-- shop_small, park, bus_stop, metro_stop, tram_stop
|
||
--
|
||
-- Idempotent: safe to run multiple times.
|
||
|
||
BEGIN;
|
||
|
||
CREATE TABLE IF NOT EXISTS user_weight_profiles (
|
||
id SERIAL PRIMARY KEY,
|
||
user_id TEXT NOT NULL, -- пока admin token / простой ID; auth в Sprint 5
|
||
profile_name TEXT NOT NULL,
|
||
weights JSONB NOT NULL DEFAULT '{}'::jsonb,
|
||
is_default BOOLEAN NOT NULL DEFAULT FALSE,
|
||
description TEXT,
|
||
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||
UNIQUE (user_id, profile_name)
|
||
);
|
||
|
||
CREATE INDEX IF NOT EXISTS user_weight_profiles_user_idx
|
||
ON user_weight_profiles (user_id);
|
||
|
||
-- Partial index для быстрого fetch default profile per user
|
||
CREATE INDEX IF NOT EXISTS user_weight_profiles_default_idx
|
||
ON user_weight_profiles (user_id) WHERE is_default = TRUE;
|
||
|
||
-- Trigger function для auto-update updated_at (shared, reusable across tables)
|
||
CREATE OR REPLACE FUNCTION set_updated_at() RETURNS TRIGGER AS $$
|
||
BEGIN
|
||
NEW.updated_at = NOW();
|
||
RETURN NEW;
|
||
END;
|
||
$$ LANGUAGE plpgsql;
|
||
|
||
-- Drop trigger если ранее существовал (idempotent)
|
||
DROP TRIGGER IF EXISTS user_weight_profiles_updated_at ON user_weight_profiles;
|
||
CREATE TRIGGER user_weight_profiles_updated_at
|
||
BEFORE UPDATE ON user_weight_profiles
|
||
FOR EACH ROW EXECUTE FUNCTION set_updated_at();
|
||
|
||
COMMENT ON TABLE user_weight_profiles IS
|
||
'POI weight profiles для site_finder. Per #114 (Макс feedback). '
|
||
'weights = {"school": 1.5, "kindergarten": 1.5, "shop_mall": 1.2, ...}';
|
||
|
||
COMMENT ON COLUMN user_weight_profiles.weights IS
|
||
'JSONB map: poi_category → weight (float, typically -1.5..2.5). '
|
||
'Совместимо с _POI_WEIGHTS default в backend/app/api/v1/parcels.py. '
|
||
'Категории: school, kindergarten, pharmacy, hospital, shop_mall, '
|
||
'shop_supermarket, shop_small, park, bus_stop, metro_stop, tram_stop.';
|
||
|
||
COMMENT ON COLUMN user_weight_profiles.user_id IS
|
||
'Простой строковый ID пользователя. Full auth integration — Sprint 5.';
|
||
|
||
COMMENT ON COLUMN user_weight_profiles.is_default IS
|
||
'TRUE = профиль используется по умолчанию для этого user_id. '
|
||
'Partial index user_weight_profiles_default_idx ускоряет lookup.';
|
||
|
||
COMMIT;
|