12 апр. 2025 г.·6 мин чтения

Моделирование домена фронтенда для сложных B2B‑экранов

Моделирование домена на фронтенде связывает компоненты, состояние и маршруты с реальными бизнес‑терминами, чтобы сложные B2B‑экраны оставались понятными и простыми для обучения.

Моделирование домена фронтенда для сложных B2B‑экранов

Почему эти экраны сложно объяснить\n\nНовый коллега открывает B2B-экран и видит вкладки, фильтры, выдвижные панели и формы. Он может нажимать всё подряд, но не видит бизнес-потока. Неясно, что должно происходить первым, кто может что менять и какое действие превращает черновик в финальную запись.\n\nПроблема часто начинается с языка. Отдел продаж говорит «account», саппорт — «customer», а код называет это «entity». Эти слова могут указывать на одно и то же или почти одно и то же, и этот маленький разрыв создаёт реальную путаницу. Люди перестают спрашивать «какое правило?» и начинают уточнять «как это здесь называется?»\n\nЕщё одна распространённая проблема — область ответственности. Одна страница превращается в инструмент поиска, очередь на проверку, редактор, шаг утверждения и вид аудита одновременно. Это кажется эффективным какое‑то время. Затем никто не может объяснить экран в одном предложении, потому что пользователи выполняют несколько задач в одном месте, и для каждой задачи свои правила.\n\nОбщие имена в коде усугубляют ситуацию. Когда UI собирают из компонентов с именами MainPanel, InfoBlock или DataTable, бизнес‑смысл исчезает. Новый инженер может прочитать код и всё равно не заметить, что один раздел нужен только для финансов, а одна кнопка меняет статус и запускает последующие задачи для операционной команды.\n\nИменно поэтому имена так важны в B2B‑продуктах. Если слова в компонентах, состоянии и маршрутах не совпадают со словами, которые люди используют на встречах, экран становится тем, что команде приходится запоминать. Когда экран требует длинного объяснения, прежде чем кто‑то сможет безопасно его править, именование уже провалилось.\n\n## Начните со слов, которые люди уже используют\n\nБольшинство запутанных B2B‑экранов разваливаются на этапе именования. UI говорит одно, отдел продаж — другое, поддержка — третье. Новичкам приходится учить продукт дважды: один раз на бизнес‑языке и второй — на языке экрана.\n\nНачните с существительных, которые уже используются. Посмотрите заметки продаж, тикеты поддержки, материалы для онбординга и записанные демо. Если люди постоянно говорят «purchase request», «approver», «vendor» и «credit limit», это не случайные метки — это слова, которые бизнес использует для описания работы.\n\nОдин концепт — одно имя. Если команда говорит «purchase request», не переименовывайте его в «item», «record» или «submission» только потому, что так короче в UI. Кажется безобидным, но пользователи подразумевают: разные слова — разные вещи.\n\nНеоднозначные метки быстро создают проблемы. «Item», «data», «details» и «panel» выглядят аккуратно в коде, но ничего не объясняют. ApprovalQueue говорит команде, что туда относится. DataPanel — нет.\n\nНекоторым терминам нужна однострочная дефиниция, потому что команды их путают. «Order» и «purchase request» часто звучат похоже, но могут находиться в разных точках процесса. «Approver» и «reviewer» тоже могут означать разные права. Напишите одно простое предложение для каждого термина и держите эту заметку в доступе для продукта, дизайна и инженеров.\n\nЭто маленькая привычка, но она экономит время. Экран становится проще объяснить, легче назвать в коде и безопаснее менять без превращения в словесную головоломку.\n\n## Называйте компоненты именами домена\n\nИмя компонента должно говорить, какой бизнес‑объект оно показывает или какое бизнес‑действие обрабатывает. Если в встречах уже используют термин «buyer», «approver» или «account manager», код должен использовать тот же термин.\n\nИмена вроде RightPanel, TableSection или StepTwoForm недолговечны. Они описывают позицию, а не смысл. Через месяц после смены макета имя перестанет иметь смысл.\n\nЧёткие имена переживут редизайн. PurchaseRequestSummary, ApprovalDecisionForm, SupplierTermsCard и ShipmentExceptionList учат тому, что находится на экране, уже при чтении дерева компонентов. Новый разработчик может открыть страницу и догадаться о потоке, не прося провести экскурсию.\n\nДержите части раскладки отдельно от бизнес‑компонентов. Sidebar, PageHeader и TwoColumnLayout подходят, если они только отвечают за отступы и размещение. В тот момент, когда компонент берёт на себя бизнес‑правило, дайте ему деловое имя.\n\nС общими компонентами нужно соблюдать умеренность. Универсальная DataCard может сэкономить несколько строк сейчас, но размывает смысл, если каждая карточка на странице следует разным правилам. Повторно используйте обвёртку, но заверните её в доменное имя вроде CreditLimitCard или ApprovalHistoryPanel.\n\nЕсть простой тест: прочитайте дерево компонентов вслух. «PurchaseRequestPage > PurchaseRequestSummary > ApprovalDecisionForm» звучит как настоящий экран. «Page > RightPanel > WidgetBox» звучит как мебель в офисе.\n\n## Пусть состояние отражает ту же модель\n\nЭкран быстро становится запутанным, когда дерево состояния смешивает бизнес‑факты с деталями UI. Если бизнес говорит о request, approver и decision, код должен использовать те же понятия.\n\nЭкран утверждения покупки — хороший пример. Храните request, approver и decision как отдельные концепты, даже если одна форма редактирует все три. Они меняются по разным причинам. Request содержит факты о том, что было запрошено. Approver — это человек или роль, имеющие право действовать. Decision — это результат с собственным статусом, заметкой и временем.\n\nДержите UI‑состояние отдельно. Открытие модального окна, переключение вкладки или индикатор загрузки — это не бизнес‑данные. Когда всё находится в одной большой «каше», люди перестают доверять форме состояния, потому что всё выглядит одинаково постоянным.\n\nРазделение обычно простое. Бизнес‑состояние выглядит как request.status, request.amount, approver.id, decision.result. UI‑состояние выглядит как isReasonDialogOpen, activeTab, isSubmitting.\n\nИмена важны не меньше структуры. Используйте названия, которые описывают реальные факты, а не то, где поле расположено на экране. billingContact стареет хорошо. leftPanelContact — нет. decision.reason ясно. secondStepValue — будущая ошибка.\n\nОбъекты‑«ловушки» обычно усугубляют проблему. formData начинается небольшим, а потом превращается в ящик для хлама полей, флагов и временных значений. Через несколько недель никто не знает, какие свойства сохраняются, а какие служат только для работы экрана.\n\nПолезное правило: новый сотрудник должен понимать форму состояния, не видя UI. Если он может прочитать её и сказать «это запрос в ожидании решения утверждающего», экран останется объяснимым.\n\n## Делайте маршруты соответствующими рабочему процессу\n\nМаршруты должны быстро отвечать на два вопроса: какая запись и на каком шаге пользователь находится? Если менеджер по продажам попадает на экран утверждения покупки, маршрут должен указывать на это утверждение первым, а не на расплывчатое имя страницы или UI‑контейнер.\n\nПоместите основной бизнес‑объект в форму маршрута и сохраняйте его там, даже если макет меняется. Люди запоминают «purchase approval» или «vendor invoice». Они не запоминают «details page» или «workspace view».\n\nПараметры маршрута заслуживают того же внимания. Используйте имя ID, которое люди используют в тикетах, документации и чатах поддержки. Если бизнес говорит approvalId, используйте его. Не прячьте за расплывчатыми именами вроде id или itemId. Новый коллега должен уметь прочитать конфиг маршрута и понять, какую запись загружает экран, не открывая три другие файла.\n\nМаршрут должен следовать за самой работой. Если пользователи переходят от черновика к ревью к утверждению, это реальные состояния маршрута. Переключение вкладки, скрытая панель или фильтр обычно — нет. Макет меняется, а шаги рабочего процесса живут дольше.\n\nМодальные окна требуют более строгого правила. Большинство модалей — временный UI и должны оставаться локальными к состоянию страницы. Давайте модали собственный маршрут только когда её можно объяснить в простых словах и поделиться ссылкой. «Открыть спор для утверждения 1842» легко объяснить. «Открыть третий оверлей на экране ревью» — нет.\n\nЭто звучит мелко, но сильно влияет на объяснимость экрана. Когда маршруты соответствуют работе, звонки в поддержку короче, а передача задач — чище.\n\n## Простой процесс для нового экрана\n\nНачните с того, чтобы уложить экран в одно простое предложение. Если вы не можете сказать, что делает экран на повседневном языке, UI будет дрейфовать. «Review and resolve an invoice dispute» — ясно. «Manage dispute workflows» — нет.\n\nЭто предложение даёт экрану задачу. Оно же удерживает именование в деловой терминологии, а не в жаргоне интерфейса, понятном лишь команде.\n\nПрежде чем открывать редактор, запишите три вещи: объекты на экране, действия, которые можно совершать, и правила, ограничивающие эти действия. Для экрана спора по счёту объекты могут быть dispute, invoice, customer и resolution. Действия — assign, approve, reject, request documents. Правило — только менеджеры по финансам могут утвердить кредит.\n\nКак только слова зафиксированы, используйте их везде. Выберите имя маршрута, форму состояния и имена компонентов на ранней стадии, пока модель ещё мала. Маршрут disputes/:id/review даёт больше информации, чем расплывчатый путь workspace/item/123. Имена состояния вроде disputeStatus и resolutionDraft легче читать, чем currentData или formState.\n\nПостройте сначала основной путь. Пока игнорируйте странные ветки и сделайте так, чтобы общий сценарий работал от начала до конца. Может ли человек открыть спор, прочитать факты, выбрать решение и отправить его, не угадывая? Если нет, крайние случаи лишь усложнят следование по экрану.\n\nКороткий процесс помогает:\n\n1. Напишите задачу экрана в одном предложении.\n2. Назовите бизнес‑объекты и действия.\n3. Зафиксируйте имена маршрутов, состояния и компонентов.\n4. Реализуйте «happy path».\n5. Добавьте исключения после того, как основной поток очевиден.\n\nЗатем протестируйте экран по‑человечески. Попросите коллегу взглянуть на него две минуты и объяснить, для чего экран, что он позволяет делать и что произойдёт дальше. Не подсказывайте. Если он использует другие слова, чем UI, или пропускает важное правило, экран всё ещё обучает неправильной модели.\n\nТакой тест ловит путаницу рано. Это намного дешевле, чем переписывать экран, когда он вырос в десять модалей и пять вкладок.\n\n## Пример: утверждение покупки в оптовом приложении\n\nОптовая команда не думает в общих терминах UI вроде review, item или submit. Они говорят о purchase requests, approvers, бюджетных заметках, замечаниях финансов и approval decisions. Если экран использует те же слова, люди его быстрее усваивают, а разработчики делают меньше неверных предположений.\n\nНачните с маршрута. Путь вроде purchase-request/123 говорит команде, о чём страница ещё до открытия кода. review/123 слишком расплывчато. Через пару месяцев никто не вспомнит, о каком именно review шла речь, и маршрут перестанет чему‑то учить.\n\nТо же правило помогает с именами компонентов. PurchaseRequestSummary понятно. ApprovalDecisionForm тоже понятно. Разработчик может просканировать дерево файлов и понять страницу без открытия десяти файлов. Сравните с HeaderCard, MainForm или ReviewPanel — такие имена описывают макет, а не бизнес‑задачу.\n\nСостояние должно следовать той же модели. Держите request, approver, comments и decision отдельными частями состояния. Это небольшое решение важно: если утверждение ломается потому, что изменился approver, вы знаете, где искать. Если финансы хотят сохранять комментарии черновиком, не придётся распутывать один большой объект, смешивающий всё подряд.\n\nМетки, которые видит пользователь, должны соответствовать модели. Если закупщики говорят «purchase request», а финансы — «approval decision», UI должен говорить то же самое. Не переименовывайте их в мягкие продуктовые слова вроде «task» или «response» только потому, что короче. Короче не значит яснее.\n\nПредставьте покупателя, открывающего запрос 123, проверяющего позиции и отправляющего его в финансы. Когда страница, состояние и имена компонентов соответствуют этой задаче, экран становится намного легче объяснить. Новые сотрудники могут проследовать по коду тем же путём, что и пользователи по экрану.\n\n## Когда один экран делает больше одной работы\n\nБольшинство запутанных B2B‑экранов ломаются, когда одна страница пытается быть рабочим пространством, журналом аудита, чатом и админ‑панелью одновременно. Люди перестают объяснять экран бизнес‑словами и начинают говорить позиционно: «вкладка справа» или «кнопка у футера». Обычно это значит, что у страницы потерялся центр.\n\nВыберите один объект, который ведёт страницу. Это может быть purchase request, invoice, shipment или contract. Заголовок страницы, маршрут, основной summary и первичные действия должны указывать на этот объект. Пользователи должны понимать, что перед ними, за пару секунд.\n\nРазделите остальные задачи на очевидные части. Комментарии должны ощущаться как комментарии, а не как заметки к утверждению, перемешанные со случайными обновлениями. Утверждения нуждаются в собственной области со статусом, владельцем и шагом далее. История должна оставаться только для чтения и легко сканируемой, потому что люди открывают её, чтобы быстро ответить «что изменилось».\n\nИспользуйте деловые термины, которые люди уже знают. Назовите секции «Approval», «Comments» и «History», если это реальные имена. Избегайте меток вроде «side rail» или «activity module». Команды могут научить бизнес‑словам. Они не научат долго словам макета.\n\nПобочная задача заслуживает собственной страницы, когда она начинает отвлекать от главного объекта. Обычно это видно: люди проводят в боковой задаче больше времени, чем в основном рекорде; у неё другие права; нужны собственные фильтры или массовые действия; или она создаёт и редактирует другой бизнес‑объект.\n\nОптовый экран утверждения — хороший пример. Если страница про один заказ на покупку, держите утверждение, отклонение, комментарии и историю ревью там. Но если пользователи начинают редактировать условия поставщика, менять правила склада или управлять ролями пользователей с того же экрана, страница взяла на себя слишком много обязанностей.\n\nВот где команды и запутываются. Страница для одного заказа не должна медленно превращаться в управление поставщиками. Если действие относится к другому объекту — перенесите его на другую страницу и свяжите через понятные имена, а не загромождением.\n\n## Ошибки, которые путают команду\n\nПлохое именование редко ломает экран в первый день. Сначала оно ломает доверие. Коллега открывает код, видит знакомые слова и затем выясняет, что эти слова означают не то, что он думал.\n\nОдна распространённая проблема — имена компонентов. Если OrderPanel иногда показывает котировку, иногда purchase request, а иногда счёт, имя перестаёт что‑то объяснять. Тогда люди читают пропсы, поля API и старые комментарии, чтобы понять, с каким объектом они имеют дело.\n\nОбщие хуки создают ту же проблему тихо. Хук useEditor или useWorkflow звучит аккуратно, но становится проблемой, когда прячет реальные бизнес‑правила. Если этот хук решает, кто может утвердить скидку, кто может переоткрыть запрос или когда форма блокируется, логика утекла от бизнес‑терминов, которые команда использует каждый день.\n\nДрейф меток — ещё одна беда. Поддержка начинает называть что‑то «approval request», а код всё ещё называет это «ticket». UI, маршрут и состояние теперь говорят на трёх разных диалектах. Новые разработчики теряются быстро, а баг‑репорты дольше отлавливаются.\n\nМаршруты тоже дрейфуют. Если пользователи говорят о purchase approvals, а URL — manage/items/123, маршрут перестаёт помогать. Хорошие имена маршрутов действуют как маленькая документация. Расплывчатые — усложняют объяснение.\n\nБольшие объекты состояния — ещё одна ловушка. Команды часто складывают все редактируемые поля в гигантский объект, потому что так быстрее. Через месяц изменение заметки запускает валидацию для вложений, сбрасывает утверждающих или помечает весь экран как «грязный».\n\nЕсли нужны быстрые индикаторы, ищите: одно имя компонента для нескольких бизнес‑объектов, общие хуки, владеющие бизнес‑правилами, рассинхрон меток и кодовых имён, или один объект состояния, управляющий несвязанными частями экрана.\n\nЕсли у оптового экрана утверждения есть детали запроса, утверждающие, комментарии и вложения, эти части должны существовать в коде как отдельные концепты. Когда имена соответствуют бизнесу, экран остаётся объяснимым.\n\n## Быстрая проверка перед релизом\n\nПолезный тест прост: спрячьте дизайн и прочитайте имена. Посмотрите маршрут, заголовок страницы, имена компонентов и поля состояния. Если новый сотрудник может угадать задачу страницы за минуту, работать с экраном, отлаживать и обучать будет проще.\n\nЗадайте прямой вопрос: «Для чего эта страница?» Если ответ — «approval queue» или «supplier dispute review», вы в порядке. Если ответ — «дашборд с карточками и фильтрами», наименования всё ещё следуют макету, а не бизнес‑задаче.\n\nКороткий ревью ловит большинство проблем. Маршрут, видимые метки и имена компонентов должны использовать одни и те же существительные. Поля состояния должны описывать бизнес‑факты, а не просто поведение UI. Вы должны уметь указать на каждую основную секцию и назвать бизнес‑действие, которое она поддерживает. А коллега должен объяснить экран, не употребляя «виджет», «панель» или «табличка».\n\nТест существительного строже, чем кажется. Если URL говорит «requests», вкладка — «Approvals», а код — ReviewBoard, люди будут тратить время на перевод. Выберите одно слово для одной концепции и используйте его везде.\n\nСостояние требует той же дисциплины. approvalStatus, reviewerId и creditLimitExceeded соответствуют реальным фактам. leftPaneOpen и activeCard могут существовать, но должны оставаться локальными к представлению. Когда общее состояние полно визуальных терминов, модель бизнеса потеряна.\n\nОдин небольшой приём перед релизом работает хорошо. Попросите продакт‑менеджера, представителя поддержки или нового инженера объяснить экран, используя только бизнес‑слова. Если они спотыкаются — переименуйте сначала. Эти слова станут языком, которым команда будет учить других.\n\n## Что делать дальше с командой\n\nВыберите один экран, к которому люди боятся прикоснуться. Обычно это тот, что рос со временем, несёт слишком много исключений и использует слова, которые по‑разному понимают продукт, продажи и инженерия. Сначала приведение в порядок этого экрана. Если команда сможет превратить один запутанный экран в чистый пример, следующие экраны станут проще.\n\nДержите перепись небольшой. Не нужен полный редизайн. Переименуйте части, которые соответствуют бизнесу, уберите состояние, смешивающее несвязанные идеи, и сделайте маршрут читаемым как рабочий процесс.\n\nХорошо работает простой проход команды. Выберите экран, который постоянно вызывает путаницу в ревью, QA или поддержке. Составьте список бизнес‑терминов из встреч и тикетов. Согласуйте одно имя для каждого понятия и используйте его в UI, компонентах, состоянии и маршрутах. Сохраните эти имена в короткой заметке, которую принимают продукт и инженерия.\n\nЭта заметка должна быть специально скучной. Десять‑пятнадцать терминов достаточно. Если продукт‑менеджер говорит «approval request», а разработчик — «review item», выберите одно и придерживайтесь. Команды работают быстрее, когда перестают постоянно переводить одно и то же понятие.\n\nНе считайте заметку неизменной. Пересматривайте её при изменении рабочего процесса, появлении новых крайних случаев или когда другая команда начинает использовать иные слова. Если бизнес‑модель смещается, модель экрана должна сместиться вместе с ней.\n\nНекоторым командам нужен внешний взгляд, когда язык продукта и структура экранов уже сплелись в узел. Тогда fractional CTO может помочь пересмотреть архитектуру продукта до того, как путаница распространится. Oleg Sotnikov at oleg.is делает такой консалтинг для стартапов и небольших компаний, особенно когда язык продукта, фронтенд‑структура и доставка разошлись.\n\nХорошее первое действие на этой неделе простое: выберите экран, запланируйте сессию по именованию и перепишите заметку в тот же день.

Часто задаваемые вопросы

Почему наименования так важны на сложных B2B экранах?

Потому что люди сначала изучают продукт через слова. Если UI называет одно, служба поддержки — другое, а код — третье, коллегам приходится переводить термины вместо того, чтобы понимать рабочий процесс.

Как выбрать правильные бизнес-термины для экрана?

Начните с существующих существительных: слова из звонков продаж, тикетов поддержки, демо и документации. Если бизнес говорит «purchase request», сохраняйте это имя в UI, коде и маршруте, пока команда не договорится об одном более подходящем термине.

Когда общее имя компонента приемлемо?

Генерик-имена подходят для частей макета, которые отвечают только за размещение, например Sidebar или PageHeader. Как только компонент владеет бизнес-правилами или показывает бизнес-данные, дайте ему доменное имя вроде ApprovalDecisionForm или PurchaseRequestSummary.

Как структурировать состояние, чтобы экран оставался объяснимым?

Держите бизнес-данные отдельно от деталей представления. Храните request, approver и decision отдельно от activeTab или isDialogOpen, чтобы модель оставалась понятной и удобной для отладки.

Что должен делать хороший маршрут?

Маршрут должен быстро отвечать на два вопроса: какая запись открыта и на каком шаге находится пользователь. Пути вроде purchase-requests/:approvalId/review учат больше, чем расплывчатые workspace/item/:id.

Что делать, когда один экран пытается выполнять слишком много задач?

Дайте странице одну понятную задачу и один главный объект. Если комментарии, утверждения, история и админ-инструменты борются за внимание, перенесите побочные задачи на отдельные страницы, прежде чем экран превратится в захламлённое рабочее пространство.

Какой первый шаг при проектировании нового B2B экрана?

Прежде чем строить, напишите одну простую фразу, описывающую страницу. Если вы не можете объяснить её на бытовом языке, наименования и структура быстро разойдутся.

Какие признаки указывают на запутанную модель экрана?

Ищите имена, которые покрывают несколько бизнес-объектов, гигантские объекты состояния вроде formData и маршруты, скрывающие реальную запись. Это означает, что экран больше не следует бизнес-языку.

Как быстро проверить, легко ли объяснить экран?

Попросите кого-то, кто не знаком с экраном, объяснить его, используя только бизнес-термины. Если они возвращаются к фразам вроде «правой вкладке» или «той панели», наименования по-прежнему описывают макет, а не рабочий процесс.

Когда стоит просить внешнюю помощь с архитектурой экранов?

Привлекайте внешнюю помощь, когда команда постоянно спорит о терминах, страница смешивает несколько рабочих потоков или мелкие изменения ломают несвязанные части. Fractional CTO может пересмотреть язык продукта, структуру кода и модель рабочих процессов до того, как путаница разрастётся.