Привет, Хабр! Меня зовут Паша Абдюшев, я занимаюсь развитием продуктов в HFLabs. А где продукты, там и документация. С одной стороны, её ведение — вопрос явно не первостепенный. А с другой — неактуальная информация не только бесит печалит, но и влечёт за собой дополнительные траты.
Не спешите кидаться тапками, если тема кажется слишком очевидной. Иногда чужой пример — лучший стимул взять и наконец сделать это у себя.
Наш путь по приведению в порядок накопившейся документации можно разделить на две части. Сначала мы прошлись по ней в ручном режиме, потом запустили автодокументацию. Сначала я расскажу, что и зачем мы делали вручную, поскольку без этой части работы автоматизацию запускать смысла нет. Во второй части статьи будет непосредственно про автодоку.
Сразу оговорюсь, что применение автодоки в b2c вряд ли настолько актуально, так как общая документация у всех одна. А вот в b2b без неё сложно.
У нас продукт класса CDI (Customer Data Integration) — «Единый клиент». Основная документация по нему живет в Confluence. Каждый заказчик видит два разных пространства:
- общую документацию, где описаны типовые настройки, правила и т.п.
- документацию с правилами конкретного заказчика.
Проблема в том, что страницы в этих пространствах называются одинаково. Более того, страницы в пространстве заказчика содержат сведения из общей документации (через механизм включения текста с одной страницы в другую).
Чем это было неудобно?
Заказчики не понимали, где чьи настройки. Часто бывало так, что они сначала смотрели свою документацию, потом общую, а затем приходили к нам с вопросами: «А где это у нас? Почему у нас не так написано?».
Иногда на внедрениях, когда нужно сделать документацию быстро, ребята просто брали доки одного заказчика и делали копипаст, так как в Confluence нет шаблона пространства целиком, есть только шаблон конкретной страницы. Это всё порождало страницы с неактуальной документацией, так как у нового заказчика что-то могло быть сделано иначе. На мой субъективный взгляд, полное отсутствие документации куда лучше, чем бессмысленное копирование.
30+ пространств заказчиков в Confluence имели разную структуру (хотя и описывали один и тот же продукт, который внедрялся по типовому процессу внедрения). Их создавали разные люди в разное время и делали так, как им удобно. Пока компания была маленькая и с каждым клиентом работали отдельные команды, проблем не было. Когда заказчиков и спейсов стало больше, хаос начал множиться.
Те самые 30+ пространств приносили всем веселье, когда что-то менялось в самом продукте. Например, появлялось новое поле. Да, Confluence позволяет делать включения одних страниц в другие. Но у каждого заказчика своя модель данных, а значит, нельзя красиво в одной таблице объединить как общую модель, так и 50 кастомных полей клиента. При добавлении нового поля нужно идти в каждое пространство и добавлять его туда.
В общем, основная засада состояла в том, что вроде документация есть, но непонятно, насколько она актуальна. Мы старались всё описывать, тратили время, но основной вопрос к документации — можно ли ей верить? — оставался.
При всём этом наша документация считалась заказчиками одной из лучших. Потому что пишем мы её человеческим языком, с примерами. Но актуализация откровенно хромала посыпает голову пеплом.
Визуальный стиль
Еще раз поясню, почему без этапа ручной работы не обойтись. Без унификации структуры мы ничего не сделаем с автодокументацией. Нам нужно понимать, в каком формате должны быть разделы в этой автодоке, чтобы было удобно. А как их сравнивать с текущими, если текущие все по-разному называются?.. Плюс разная вложенность: у одного заказчика описание модуля в папке «Модули», а у другого ещё дальше запрятано. Мы даже сравнить не сможем и разобраться, если мы что-то неправильно, например, в автодоке сделали. Так что прежде чем начать автоматизировать, сначала нужно ручками навести порядок.
Начали мы с того, что спросили у поддержки, где больше всего болит? Получили ответ: заказчик часто путается, где его документация, а где общая. Вложенные страницы и кросс-ссылки в Confluence сыграли дурную службу: заказчик мог кликнуть по ссылке и оказаться в спейсе с общей документацией по продукту, которую в идеальном сценарии он вообще не должен видеть.
Решили сделать плашку-пояснение для общей документации. Почти сразу столкнулись с проблемой баннерной слепоты: люди не замечают баннеры, на автомате их отсекают из зоны внимания.
Попробовали поменять фон и шрифты — не зашло. Дело в том, что человеку удобно работать в сине-серой цветовой гамме. И чтобы была заметна разница, нужен явно отличающийся стиль (то есть замена тёмно-синего на чёрный, например, не катит — люди не замечают разницы). С другой стороны, если изменить на что-то яркое, то работать уже сложно: насыщенные цвета перетягивают внимание на себя, хочется сразу из документации сбежать.
Методом проб и ошибок пришли к тому, что достаточно цвет меню изменить, чтобы всё остальное читалось нормально, но при этом человек сразу бы понимал, что он попал в другое место. Да и заказчику удобно отвечать: если цвет меню жёлтый, это общий спейс.
Вот как это выглядит:
Но даже с этим жёлтым цветом по факту оказалось всё не так просто. Когда я эту штуку предложил, то неожиданно столкнулся с сопротивлением ребят — ну камон, раньше жили и было нормально, что за дурацкий цвет… У нас были настоящие внутренние батлы и серия переделок, кто кого перередактирует.
Шаблоны
Что дальше? Часто заказчикам и интеграторам нужна сводная информация об установке и о серверах — IP и DNS-name, ОС и ее версия, CPU, память и диск, порты для подключения, интерфейс приложения, админка, папка установки… Тут нам помогла такая штука как шаблоны в Confluence. Очень рекомендую ими пользоваться. Они подходят, например, для описания подключения о серверах, потому что IP и DNS-name там могут встречаться десятки раз. Плюс в шаблоне можно расставить плашки, чтобы человек не делал бездумный копипаст, а видел, где и что ему надо поменять.
В чем ещё прелесть шаблона? Единая структура страницы, подстановочные переменные, подсказки для заполнения (текст подсказок не выводится на итоговую страницу и не виден заказчику), метки для напоминаний, понятная инструкция.
Как это выглядит, показываю ниже на скринах.
Есть, правда, с шаблонами своя сложность: мы их сделали в спейсе одного заказчика, но нам было нужно, чтобы все 30+ клиентов на них переехали. Мы поставили задачу в Jira и начали отмечать, по каким заказчикам это уже сделано. Завели правило: поставляем клиенту релиз — актуализируем его страницу по новому шаблону.
Это, с одной стороны, позволило нам провести активность не в виде субботника и не в приказном порядке, а вписать её в рабочий цикл. Почему об этом рассказываю? На мой взгляд, инициировать перемены легко, а довести до конца — сложно. Особенно, когда речь идет о монотонной работе. И всегда есть риск забить, остановиться посередине, когда часть заказчиков на новые шаблоны перевели, а другие так и остались на старых.
При этом у нас есть заказчики, которым мы редко ставим релизы или которые мало взаимодействуют с документацией. С их спейсами работали уже методом добивающих субботников: каждые пару недель отслеживали в Jira, страницы каких заказчиков у нас ещё не переведены на новую структуру, и брали их в работу.
Рестрикты
Следующая наша проблема: ограничений доступа для заказчиков по документации оказалось довольно много. Но когда человек создаёт страницу в другом спейсе, он может забыть поставить замочек там, где информация только для внутреннего использования. Уследить за тем, что заказчику доступно, а что нет, сложно. Тут нашлось простое решение: оставляем всё в одном спейсе, а то, что заказчик не должен видеть, выносим в отдельный блок.
Выглядит это вот так:
При наведении порядка в ограничениях в очередной раз упёрлись в разнородную структуру страниц заказчика.
Нужно было всё пространство прошерстить, прежде чем найдёшь то, что нужно вынести в рестрикт. Решили, что дальше так жить нельзя. Для начала подключили метрики, чтобы понять, кто какими страницами пользуется. Для этого у нас есть прекрасный бот, который может сказать, кто и сколько раз ту или иную страницу просмотрел. По сути, сделали Яндекс Метрику на весь Confluence. Когда получили отчёт, сильно удивились: оказалось, что классные документы, которые заказчики должны бы читать, почти никто не открывает!
Решение: клонировали пространство заказчика и создали новую структуру на основе метрик. На первый и второй уровень иерархии вынесли то, что нужно чаще всего. Да, обнаружили тонну страниц, с которыми непонятно, что делать. На них повесили метки, что они нуждаются в актуализации. Так последовательно на новую структуру перевели все пространства заказчиков «Единого клиента».
По ходу перевода возник еще один момент: а что делать с неактуальной информацией? Тут мы решили так:
удалять, если она перенесена в другие разделы или же полностью устарела и точно не пригодится в будущем;
архивировать, если информация устарела. Но важно помнить, почему сделано именно так.
И немного автоматизации напоследок
Как только начали перевод заказчиков на новую структуру страницы, снова сюрприз. Пришло осознание, что модель данных остается весьма посредственной. Где самая актуальная информация о ней? В коде и в БД! Пошли к программистам и убедили их автоматизировать выгрузку полей из кода и базы данных в документацию. Реальность нас огорошила — было 20 полей, а стало 40! Посыпались вопросы: а что это за поля, а где вот те поля?
Оказалось, что часть системных полей не была описана в документации, так как они относятся к внутренним, и заказчику про них знать не нужно. А есть еще виртуальные поля в коде, которых нет в БД. Эти поля для заказчика, напротив, важны, а в автодокументацию они изначально не попали. В итоге промаркировали в коде, что выводить в доку, а что нет.
Когда прикрутили автодокументацию, у нас 60-100 страниц в каждом заказчике стало обновляться каждый день. Проблема? Да. Во-первых, это сильно замусоривало ленту обновлений. Во-вторых, было неясно, когда в реальности что-то поменялось в документации. Новая версия страницы создавалась каждый день с нуля, даже если информация на ней ничем не отличалась от предыдущей версии.
Нюанс в том, что после отправки запроса на обновление страницы, Confluence форматирует html по своим правилам. Это значит, что если строково сравнить html до и после отправки на Confluence, то можем получить несовпадение из-за переформатирования. В итоге стабильность проверки, нужно ли обновление, достигли за счёт использование хеш-кодов. При генерации документации мы в любом случае создаем html для всех страниц. Если входные данные не менялись, то мы каждый раз будем получать один и тот же html. От этого html можно расчитать хеш-код (мы используем md5) и сохранить его на этой же странице в скрытом блоке. Получается, что, перед тем как обновлять страницу, мы можем запросить текущую версию и вытащить из неё хеш-код. Далее сравниваем хеш-код нового html и текущего html. Если они не совпадают — обновляем страницу. Если совпадают — едем дальше.
В сухом остатке: мы всегда знаем, какие страницы сгенерированы автоматически. Заказчики этого не видят, так как эта информация хранится в скрытом блоке. Она позволяет нам мгновенно отличать «автоматические» страницы от «ручной» документации и не исправлять их вручную. Как это выглядит, показывают на скриншоте:
Одна из плюшек, которую мы получили, — автоматическое проставление кросс-ссылок между справочниками и полями, которые заполняются этими справочными значениями. Эта информация (о том, что конкретное поле, например, «тип адреса» — это классификатор с пятью значениями: домашний, рабочий, адрес родственника, для корреспонденции, иной) есть непосредственно в коде продукта и теперь автоматически выгружается в документацию. А раньше все ссылки с поля на справочник ставились вручную. Это приводило к тому, что часть ссылок вела не на те справочники по ошибке, а часть справочных полей вообще не имела ссылки на перечень возможных значений в этом поле. Так мы по ходу дела ещё и улучшили кросс-ссылочность в документации.
Краткие итоги
Итак, что у нас в результате?
Четко разделили общую документацию и пространства заказчиков.
У каждого клиента появились чётко разделённые открытые и закрытые части спейса. Унифицировали структуру всех пространств заказчика. Описание всех стендов теперь в одном стиле. Это упростило онбординг новых сотрудников, поддержку заказчиков и переход людей от одного клиента к другому. Теперь всегда ясно, где посмотреть конкретную информацию в спейсе любого заказчика
без гадания, а как оно там называется и где лежит.Появилось актуальное описание модели данных, которое выгружается из кода. Нет никакого смысла править страницу быстро руками, потому что впоследствии автоматически это будет затёрто.
И тем не менее, сказанное в предыдущем абзаце — не панацея. Со временем мы поняли, что хотелки заказчиков не всегда ложатся на тот код, который есть. Поэтому мы в автодоке сделали отсечки, где можно добавлять ручные пометки, которые не затираются автоматическим обновлением документации. Да, это ручное решение проблемы, и за этим приходится следить, чтобы при необходимости пометки были сделаны.
И, что самое приятное, от заказчиков стало меньше жалоб и вопросов;)
И пара рекомендаций для тех, кто начинает работу с автодокой. Обычно автоматически описаны API, но когда начинаешь формировать доку из кода, все будет зависеть от языка программирования и того, как написан код. Для начала рекомендую поискать Open Source решения — например, Swagger. Для Java тоже можно найти варианты, но мы из-за размера проекта используем самописный инструмент.
Будьте готовы и к тому, что иногда коллеги из-за автоматической натуры доки могут ей не до конца верить. У нас, бывает, приходят жаловаться: мол, в автодоке ошибка. А на деле оказывается, что ошибка в коде, а автодока это просто отражает. Бездушной машине точно можно верить, мы проверяли;)