Сотня форков и вопрос «в каком из них?»
Наш продукт — виджет 3D-тура, который застройщики, классифайды и агентства встраивают к себе через iframe. Почти каждому B2B-клиенту нужна своя подача: цвета, логотип, набор кнопок, язык, положение миникарты. Первое решение было разумным: ядро в npm-пакете и тонкая обёртка с конфигом, которую форкали под клиента.
На пяти клиентах это работало, к сотому — развалилось. Форк замораживал версию ядра, за четыре года вышло около 450 версий пакета, и багфикс превращался в кампанию по обновлению десятков репозиториев. Подключение партнёра занимало до двух недель, а разработчики тратили время на сдвиг плашек и замену цветов. Хуже всего, что никто не знал, какие параметры доступны в конкретной версии: описание жило в коде, устаревшей документации и памяти автора. Настоящей проблемой было отсутствие контракта конфигурации.
Тип как исходник, схема как исполняемый контракт
Контракт у нас уже существовал — в TypeScript-типе конфигурации с перечислениями, флагами и TSDoc-комментариями. Его нужно было не придумать, а донести до людей, которые настраивают клиентов. В CI по тегу релиза из типа генерируется JSON Schema: комментарии становятся описаниями, union-типы — перечислениями.
Схемы лежат в S3 с раскладкой по версиям и паспортом релиза со ссылкой на коммит и пайплайн. База данных не понадобилась: опубликованные версии не меняются. Одна деталь без присмотра ломала бы всё тихо — latest обновляется, только если тег совпадает с актуальной версией в npm, иначе хотфикс в старую ветку перезаписал бы схему.
В админке схема подключается к Monaco Editor — редактору, на котором построен VS Code. Он сам даёт автодополнение, подсказки по параметрам и подсветку ошибок, а невалидный конфиг нельзя сохранить. Рядом — выбор версии схемы и iframe с живым виджетом: цикл правки сократился с дней до пары секунд. Сам виджет при загрузке запрашивает брендинг по домену, поэтому новый клиент — это строка в базе, а не сборка: сотни поддоменов обслуживают один wildcard-конфиг и четыре сертификата.
800+ брендированных релизов без разработчика
Система три года работает в продакшене и обслужила больше восьмисот брендингов, по 20–45 новых в месяц. Около сотни репозиториев свелись к одному, подключение партнёра — с двух недель до пары дней, ошибки из-за опечаток в конфигах исчезли, а примерно треть времени разработки вернулась к продукту. Кастомный JavaScript понадобился меньше чем одному проценту клиентов.
Статистика использования удивила. Примерно две трети брендингов вообще не трогают параметры, а три самых популярных ключа покрывают 95% настроек у остальных. Первое место заняло переопределение текстов интерфейса, а не цвета, как мы ожидали.
Что забрать с собой
Форки — симптом, болезнь — отсутствие контракта. Исходник контракта почти всегда уже есть в типах, и задача в том, чтобы протащить его до интерфейса, не создав новой рутины: документацию к параметрам мы перестали вести отдельно, потому что TSDoc доезжает до подсказок в редакторе сам.
И второе: мы бы не угадали, какие настройки важнее. Показать всю схему и строить форму из неё оказалось надёжнее, чем проектировать удобный экран под десяток параметров, которые кажутся главными.