Skip to content

refactor(_bidding_strategy): дедуп budget-билдеров и пар search/network стратегий (~2000 строк) #581

@axisrow

Description

@axisrow

Аудит дублирования (xhigh, 4 параллельных аудитора + ручная верификация чтением кода). _bidding_strategy.py — 5547 строк, второй по размеру файл проекта; здесь сосредоточен крупнейший пласт копипасты.

Находки

1. 4 копии _build_*_custom_period_budget (~95% идентичны)

_bidding_strategy.py:1381,3475,4435,5087_build_text_search_, _build_text_network_, _build_unified_network_, _build_unified_search_.

Сверил text-search (1381) и unified-search (5087) построчно: тела возврата, проверка missing, asserts идентичны. Отличия только в:

  • префиксе флага (--text-search- vs --unified-search-);
  • слове в тексте ошибки (TextCampaign vs UnifiedCampaign).

→ Одна функция _build_custom_period_budget(flag_prefix, campaign_label, spend_limit, start_date, end_date, auto_continue). Экономия ~120 строк, логика CustomPeriodBudget в одном месте.

2. 4 копии _build_*_exploration_budget — со СКРЫТЫМ поведенческим расхождением ⚠️

_bidding_strategy.py:1419,3511,4472,5126.

text-search требует is_custom == "YES" (строки 1446–1450, по public-docs constraint #388), а unified-search принимает и YES, и NO (строки 5156–5158, по cached WSDL). Это намеренная разница, но сейчас она «спрятана» в двух из четырёх почти одинаковых копий — при ручной правке одной копии легко занести регрессию.

→ Параметризовать (flag_prefix, label, exploration_yes_only: bool). Дубль уходит, а единственное реальное отличие становится явным аргументом.

3. 6 пар build_*_search_strategy / build_*_network_strategy (70–90% совпадения)

  • text_campaign: 17473540
  • dynamic_text: 24172134
  • smart_campaign: 30573958
  • unified_campaign: 52254574
  • mobile_app: 775975

Каждая пара дублирует весь пайплайн: setup field_support dict, валидация detail-флагов, CPA-обработка, сборка budget-блоков. _TextStrategyConfig(NamedTuple) (1457) — уже начатый правильный путь, но применён только к TextCampaign.

→ Распространить config-объект (search/network как параметр) на остальные типы кампаний. Самый объёмный пласт файла.

4. 3 копии _assemble_*_strategy_block

_bidding_strategy.py:2046,2946,4501 (dynamic/smart/unified) — собирают CustomPeriodBudget/ExplorationBudget по budget-type тремя слегка разными способами. → Общий _assemble_strategy_block с таблицей builder'ов.

Не дефект (проверено)

Приёмка

  • Параметризованные builder'ы вместо 4+4 копий, расхождение YES-only сохранено явным флагом.
  • pytest зелёный (особенно test_dry_run.py, test_wsdl_parity_gate.py).
  • --dry-run паритет: payload идентичен до/после для всех затронутых типов кампаний.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions