Документация

Впервые в системе? Начните с гайда С чего начать.

Встроенная документация приложения. Читается двумя способами:

  • с GitHub - как обычные Markdown-файлы этого каталога;
  • из приложения - контроллер docs рендерит эти же файлы (оглавление: /docs/index), дополняя их подсказками из кода.

Конвенция: три слоя документации

Слой 1 - микроописания (живут в коде)

  • attributeData()['<attr>']['hint'] - короткая подсказка атрибута (1–3 предложения, до ~300 символов). Показывается тултипом у поля. Обязательна для каждого пользовательского атрибута - контролируется сторожевым тестом. Минимальная HTML-разметка допустима (<br>, <b>, <i>, muted); структура документа (заголовки, разделы) - признак, что тексту место в слое 2.
  • Типовые подсказки - “толстые” типы (typeClass) дают свою часть подсказки методами inputHint() (как заполнять) и searchHint() (как искать). Итоговый тултип атрибута = специфичная часть + типовая (типовая выводится приглушённо).
  • modelDescription() - короткое описание сущности (что это, зачем). Показывается popover’ом на страницах списка/карточки.

Стандарт формулировок (чтобы конкатенация частей читалась естественно):

Текст Отвечает на вопрос Пример
hint атрибута что здесь хранится и зачем “MAC адреса сетевых интерфейсов оборудования”
inputHint() типа как вводить: формат, множественность “В каждой строке - один адрес или диапазон…”
searchHint() типа как искать: только отличия от общего синтаксиса “Поиск по диапазону - только полным MAC…”

Hint атрибута не описывает формат (это даст тип); типовые подсказки не упоминают конкретные модели.

Правило актуальности: изменил семантику поля или модели - обнови hint/описание в том же коммите.

Слой 2 - подробные описания (этот каталог)

Длинные тексты в коде не живут. Для каждой модели/атрибута/типа может существовать MD-файл, который приложение подтягивает вторым слоем. Из тултипа атрибута ведут раздельные подписанные ссылки - на страницу атрибута (“подробнее: Оборудование → MAC адреса”) и на страницу типа (“подробнее о типе: MAC-адреса”); каждая показывается только если её страница существует:

docs/help/
  README.md                  оглавление и эта конвенция
  models/<class-id>.md       подробное описание модели/сущности
  models/<class-id>/<attr>.md подробное описание атрибута (опционально)
  types/<type-id>.md         описание типа данных (одно на все модели)
  guides/*.md                сквозные сценарии работы
  admin/*.md                 установка, обновление, интеграции
  img/*                      изображения (минимум - тяжело поддерживать)
  • <class-id> - kebab-case идентификатор модели, как у контроллера (comps, tech-models); <attr> - имя атрибута модели.
  • Привязка к коду - именем файла; переименования полей/моделей ловит сторожевой тест на “осиротевшие” файлы.
  • MD-файл опционален: он нужен только там, где есть что рассказать сверх короткого hint.
  • Секции страницы модели привязаны к страницам UI. Панель документации доносит до страниц приложения только канонические H2-секции: преамбула и «Список» - на списке, «Просмотр» - на карточке, «Добавление» и «Редактирование» - на формах. H2-секция вне этого набора в приложении видна только на полной странице /docs - поэтому инструкции по элементам UI живут внутри секции той страницы, где эти элементы находятся. Отдельной «страницы удаления» не существует: удаление делается кнопкой на карточке, и его описание - подсекция ### Удаление в конце «Просмотра» (так же «Копирование» и прочие действия карточки). H2 вне канона оставляем только концепциям (жизненный цикл, связи, архивность), не привязанным к конкретной странице.
  • Описания атрибутов НЕ ведутся разделами страницы модели: короткое - в hint (слой 1), длинное - в models/<class-id>/<attr>.md. Страница сущности в приложении (/docs/model) собирается без дублей: заголовок странице даёт код (H1 документа отбрасывается), концепцию - MD-страница (modelDescription показывается только фолбэком, когда MD нет), ниже - генерируемый справочник атрибутов, из которого атрибутные страницы открываются ссылками “подробнее” модалкой - “ссылка вместо пересказа”, вторым сборником они не разворачиваются. Тултип поля ведёт на то же фокусное описание атрибута. Страница модели - только концепция: что это, жизненный цикл, связи, сценарии.

Слой 3 - доставка в UI

Контроллер docs: оглавление, рендер страниц, отдача картинок. Заказчик может переопределять и дополнять страницы: каталог с той же структурой указывается в params['docsOverridePath'] и просматривается первым.

Интеграция в UI: описания доставляются элементами интерфейса

Слой 1 не “лежит в коде” - он выводится самим интерфейсом: описание атрибута или элемента живёт НА нём (иконка “?” у подписи, тултип объекта), а не пересказывается текстом страницы-описания (принцип element-locality - справка по странице описывает лишь композицию странице не перечисляя атрибуты/поля).

Единая точка вывода - ModelFieldWidget + сборщик тултипов AttributeTooltip. Инструменты: - подпись с “?” (renderFieldTitle) - значение со скрытой до help-mode “?” (renderFieldValueHinted) - заголовок составного блока с агрегированными hint’ами нескольких атрибутов (renderCompositeTitle) - цепочка положения (ChainWidget) - режим help-mode (подсветка всех “?”).

Механизмы описаны в ui-sources.md (§0.1 и §3) - здесь не дублируются.

Правило: составной/нестандартный рендер в карточке делай самодокументируемым этими инструментами, а не текстом-пересказом (или заведи MD слоя 2 и сошлись на него).

Метка TODO-REVIEW

Текст, сгенерированный ИИ по коду без вычитки человеком, помечается меткой TODO-REVIEW (в PHP - комментарием рядом с hint/modelDescription, в MD - строкой > ⚠ TODO-REVIEW: ...). Найти всё непроверенное: grep -rn "TODO-REVIEW" models modules docs. После вычитки и правки метка удаляется.

Правила оформления страниц

  • Первая строка файла - # Заголовок (используется как title страницы в приложении и в оглавлении).
  • Ссылки на другие страницы документации - относительные (../guides/page.md): работают и на GitHub, и в приложении (приложение переписывает их на свои маршруты).
  • Картинки - относительными путями в img/; допустимые форматы: png, jpg, jpeg, gif, svg, webp. Но их избегаем: не версионируются осмысленно, устаревают, требуют актуализации после каждого изменения UI.
  • Схемы - блоками “`mermaid, а не картинками. Диаграмма как код версионируется с текстом, GitHub рендерит её нативно, в приложении - mermaid.js (MermaidAsset на страницах docs и в инфоблоках). Так вопрос “картинки-схемы устаревают” снимается.
  • Абсолютные URL (внешние ресурсы) не переписываются - использовать только для действительно внешних ссылок.
  • Ссылка на секцию - якорем по её заголовку (setup.md#авторизация): приложение проставляет заголовкам те же id, что GitHub (нижний регистр, пунктуация выброшена, пробелы -> дефисы), поэтому одна ссылка работает в обоих местах чтения. Свой якорь заголовка задаётся в MD как ## Заголовок {#свой-id}.
  • Ссылка на атрибут сущности - якорем по латинскому имени атрибута: [Основной документ](models/contracts.md#attr-parent_id). Якоря #attr-<имя> не пишутся в MD руками - приложение проставляет их само на строках справочника атрибутов страницы сущности (/docs/model), а такие ссылки переписывает на неё же (а не на голый MD, где справочника нет). Так ссылаться можно на любой атрибут - и на тот, у которого нет своей страницы models/<class-id>/<attr>.md. Латинское имя атрибута в справочнике - само себе ссылка: адрес якоря видно и можно скопировать. На GitHub такая ссылка ведёт на страницу модели (якоря там нет - открывается её начало), поэтому для атрибутов со своей страницей предпочтительна прямая ссылка на неё.
  • Переход по якорю внутрь документации приложение подсвечивает: цель (заголовок секции или строка атрибута) на пару секунд загорается тем же маркером, что и элемент интерфейса по ссылке #doc-anchor: (см. ниже). Ничего дополнительно в MD для этого писать не надо.

Подсветка элемента интерфейса по ссылке

Когда описание должно указать на конкретный элемент на странице (а перенос текста в тултип элемента неестественен - элемент далеко или описание якорное), свяжите строку описания с элементом по ключу:

  • в тексте страницы/секции - обычной markdown-ссылкой [текст](#doc-anchor:КЛЮЧ) (её якорный href переживает рендер - приложение переписывает только ссылки на соседние .md/картинки);
  • в hint-тултипе атрибута - той же ссылкой raw-HTML: <a href="#doc-anchor:КЛЮЧ">текст</a> (обработчик делегирован на весь документ и срабатывает и из всплывающего тултипа) - так подсказка одного элемента может подсветить связанный элемент;
  • на самом элементе интерфейса (во вьюхе) - атрибутом data-doc-anchor="КЛЮЧ".

Клик по такой ссылке в инфоблоке документации проскроллит к элементу и на пару секунд подсветит его. Если элемента на текущей странице нет - ссылка ничего не делает (ведёт себя как обычный якорь). КЛЮЧ - короткий kebab-slug, уникальный в пределах страницы. Так подсказка по странице ссылается на элемент, а не пересказывает его текстом.

В приложении ссылки-подсветки автоматически маркируются (пунктирное подчёркивание + значок-прицел, site.css по префиксу href) - читатель заранее видит, что клик подсветит элемент на этой же странице, а не уведёт с неё. В MD для этого ничего дополнительно писать не надо; на GitHub такие ссылки выглядят обычными и просто ничего не делают.

Подсветка селектором (#doc-select:)

Когда целей много и размечать каждую атрибутом расточительно (заголовки сортировки, строка фильтров таблицы), элементы ищутся CSS-селектором - подсвечиваются все совпадения, скролл к первому:

[заголовку](<#doc-select:.grid-view th a[data-sort]>)
[полями фильтров](<#doc-select:.grid-view .filters input>)
  • Destination в <угловых скобках> - из-за пробелов в селекторе (это штатный markdown, GitHub и приложение понимают одинаково); без пробелов скобки не нужны. Символ > внутри селектора кодируется как %3E.
  • Селектор - только по стабильным библиотечным классам/атрибутам (a[data-sort] у Yii-сортировки, .filters у строки фильтров GridView, Bootstrap-классы), а не по нашей вёрстке: селектор в MD молча умирает при переименовании класса, и сторожевым тестом это не ловится. Всё специфичное для одной страницы/формы - по-прежнему #doc-anchor: с меткой на элементе.
  • Работает и в hint-тултипах raw-HTML ссылкой: <a href="#doc-select:СЕЛЕКТОР">текст</a> (пробелы в HTML-атрибуте легальны).

Разделы

  • models/ - сущности: заполняется по мере миграции контента из wiki.
  • types/ - типы данных.
  • guides/ - сценарии: “как завести рабочее место”, “как оформить закупку”…
  • admin/ - установка, обновление (в т.ч. Docker), интеграции, бэкапы.