- AI-инструмент копит моды как тогглы; при 3 из 5 признаков нужен рефактор, а не кнопка
- Основная ось выбора уходит в верхние табы, второстепенные оси остаются внутри панели
- Компонент на 7 113 строк и пять мод свернулись в четыре таба без потери функций
Задача
Долгоживущий AI-инструмент обрастает модами. Каждая новая функция приземляется как тоггл, свитч или иконка-кнопка рядом с предыдущими, потому что так быстрее всего выпустить. Через несколько кварталов в панели пять перекрывающихся мод, которые выбираются тремя разными типами контролов, а взаимная исключённость сделана через скрытие соседей: включил режим A, контролы режима B исчезли, и пользователь не видит, что потерял.
Обычный путь — добавить ещё одну кнопку — здесь не работает. Новый пользователь не откроет эти моды без проб и ошибок, а старый уже держит карту в голове и не замечает, насколько она сложная. Поверхности нужны раскопки, а не расширение.
Приём
Сначала диагностика. Пять признаков, что поверхность пора вскрывать:
- один компонент больше ~3 000 строк владеет всей поверхностью;
- моды выбираются смешанными типами контролов (Switch, иконка, карусель, таб) в одной панели;
- взаимная исключённость сделана через скрытие соседей;
- админские тогглы занимают место у обычных пользователей;
- чтобы узнать про моду, нужно читать код или спрашивать внутреннего пользователя.
Три и больше из пяти — значит рефактор. Дальше пять шагов.
- Перечислить все моды, которые поддерживает поверхность. Отметить, что видно пользователю, что только админу, что мёртвый код.
- Сгруппировать моды по осям. Почти у любой поверхности есть одна основная ось («что я делаю») и ноль или больше второстепенных («как я это делаю»).
- Поднять основную ось в верхние табы. Табы по устройству взаимно исключают друг друга, всегда видны и сами себя подписывают. Проблема обнаружения мод решается лейблами.
- Выкинуть мёртвые тогглы: переключатели провайдера и модели, админ-флаги, A/B-свитчи с явным победителем. Отрицательный дифф здесь — часть результата.
- Перекомпоновать каждый таб вокруг естественного потока. Если внутри есть шаговая последовательность (персонаж → голос → видео), раскладывать её как главный поток, а не как параллельные контролы.
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