• AI-инструмент копит моды как тогглы; при 3 из 5 признаков нужен рефактор, а не кнопка
  • Основная ось выбора уходит в верхние табы, второстепенные оси остаются внутри панели
  • Компонент на 7 113 строк и пять мод свернулись в четыре таба без потери функций

Задача

Долгоживущий AI-инструмент обрастает модами. Каждая новая функция приземляется как тоггл, свитч или иконка-кнопка рядом с предыдущими, потому что так быстрее всего выпустить. Через несколько кварталов в панели пять перекрывающихся мод, которые выбираются тремя разными типами контролов, а взаимная исключённость сделана через скрытие соседей: включил режим A, контролы режима B исчезли, и пользователь не видит, что потерял.

Обычный путь — добавить ещё одну кнопку — здесь не работает. Новый пользователь не откроет эти моды без проб и ошибок, а старый уже держит карту в голове и не замечает, насколько она сложная. Поверхности нужны раскопки, а не расширение.

Приём

Сначала диагностика. Пять признаков, что поверхность пора вскрывать:

  • один компонент больше ~3 000 строк владеет всей поверхностью;
  • моды выбираются смешанными типами контролов (Switch, иконка, карусель, таб) в одной панели;
  • взаимная исключённость сделана через скрытие соседей;
  • админские тогглы занимают место у обычных пользователей;
  • чтобы узнать про моду, нужно читать код или спрашивать внутреннего пользователя.

Три и больше из пяти — значит рефактор. Дальше пять шагов.

  1. Перечислить все моды, которые поддерживает поверхность. Отметить, что видно пользователю, что только админу, что мёртвый код.
  2. Сгруппировать моды по осям. Почти у любой поверхности есть одна основная ось («что я делаю») и ноль или больше второстепенных («как я это делаю»).
  3. Поднять основную ось в верхние табы. Табы по устройству взаимно исключают друг друга, всегда видны и сами себя подписывают. Проблема обнаружения мод решается лейблами.
  4. Выкинуть мёртвые тогглы: переключатели провайдера и модели, админ-флаги, A/B-свитчи с явным победителем. Отрицательный дифф здесь — часть результата.
  5. Перекомпоновать каждый таб вокруг естественного потока. Если внутри есть шаговая последовательность (персонаж → голос → видео), раскладывать её как главный поток, а не как параллельные контролы.
flowchart TD
    Q{3 из 5<br/>признаков?} -->|да| M[Все моды<br/>поверхности]
    M --> G{Ось?}
    G -->|что я делаю| T[Основная ось:<br/>верхние табы]
    G -->|как я делаю| P[Второстепенные:<br/>внутри панели]
    G -->|мёртвое| X[Выкинуть:<br/>отрицательный дифф]

Почему это работает: исходная панель пыталась быть всеми осями сразу. После рефактора у каждого слоя одна работа: табы держат основной выбор, панель показывает его последствия. Вопрос «в какой я моде?» решается чтением заголовка таба, а не аудитом состояний тогглов.

flowchart TB
    subgraph before[До: одна панель на все оси]
        direction LR
        P0[Тогглы, свитчи,<br/>иконки вперемешку] --> Q0[В какой я моде?<br/>аудит тогглов]
    end
    subgraph after[После: у каждого слоя одна работа]
        direction LR
        T1[Табы:<br/>основной выбор] --> P1[Панель:<br/>последствия выбора]
    end
    before ~~~ after
    classDef key stroke:#FF3600,stroke-width:2px
    class Q0 key

Пример. Поверхность генерации аватаров: один компонент на 7 113 строк, пять перекрывающихся мод (совместная, кампания, раздельный или смешанный контроль, редактирование, голос), каждая со своим типом переключателя, плюс тогглы провайдера и модели промпта, видимые всем. После раскопок:

Табы:      Generate · Campaign · Edit · Voice
Выкинуто:  тогглы provider / prompt-model (админские),
           Separate vs Mixed (оставлен merged, он и так победил)
Voice:     цепочка audio → video разложена как главный поток

Та же функциональность, примерно половина когнитивной нагрузки, и обнаружение мод стало побочным эффектом взгляда на экран.

flowchart LR
    B[Компонент<br/>на 7 113 строк] --> M[Пять мод,<br/>свой переключатель]
    M --> T[Табы: Generate,<br/>Campaign, Edit, Voice]
    M -. админское .-> X[Выкинуто: тогглы<br/>провайдера и модели]

Обновление, сентябрь 2026. Тот же приём прошёл по соседней поверхности инструмента, генерации продуктовых кадров. Там кампания включалась отдельным тогглом поверх карточки товара; тоггл заменён тремя табами: карточка, кампания, соцсети, а таб соцсетей получил пресеты, которые сами задают соотношение сторон. Следом пришло правило для упрощения всего продукта: ни одного параметра не терять. Основной сценарий выходит вперёд крупно, всё второстепенное сворачивается в раздел «Точная настройка». Выкидывается только мёртвое; живой параметр прячется, но остаётся.

Где ломается

  • Табы названы теми же словами, что старые тогглы. Вернувшийся пользователь не заметит перемены и продолжит искать привычный свитч. Нужны новые имена.
  • Расползание табов. Пять уже много; на семи поверхность — на самом деле две поверхности в одном пальто, и их пора разделять.
  • Память последнего таба. Помнить его на пользователя обычно правильно, глобально — нет. Лучше привязывать к сущности: этот аватар и его последний таб, а не «таб аватаров вообще».
  • Рефактор без выброса. Если оставить все старые контролы «на всякий случай», получится та же панель плюс табы сверху.

Итог

  • Признак болезни — не число функций, а число способов их включить.
  • Основная ось — наружу в табы, второстепенные — внутрь панели, мёртвое — прочь.
  • Один рефактор в квартал дешевле, чем одна кнопка в неделю.
  • Проверка результата простая: новый пользователь называет все моды, не кликнув ни разу.
  • Мёртвое выкидывается, живое сворачивается в «Точную настройку», но не удаляется.

© Александр Никулин. Цитирование — с указанием автора и ссылкой · Версия для LLM