Skip to content

Latest commit

 

History

History
150 lines (129 loc) · 11.5 KB

File metadata and controls

150 lines (129 loc) · 11.5 KB

Конвенции и подводные камни в документации

Правила для редактирования apps/docs (MDX-контент + компоненты), которые не видны из кода и уже не раз нас кусали.

Новый MDX-компонент — регистрировать в ТРЁХ местах

У сайта два пути рендеринга: Next.js рендерит MDX через React, и scripts/generate-llms.ts уплощает MDX в Markdown для /llms-full.txt и постраничных .md. Компонент, добавленный для сайта, о котором flattener не знает, утекает сырым тегом <Component> в AI-facing Markdown.

Добавляя компонент, регистрируй его во всех трёх:

  1. apps/docs/components/mdx/mdx-components.tsx — определение + добавить в customMdxComponents.
  2. apps/docs/components/api/markdown-content.tsx — импорт + добавить в объект components, который передаётся в MDXRemote (без этого — runtime-ошибка «component is not defined»).
  3. apps/docs/lib/mdx-expander.ts — обработчик в expandMdxComponents(), который превращает JSX в обычный Markdown (или раскрывает внутренний контент для layout-обёрток вроде <CardRow> / <ParamsTable>). Без этого сырые теги утекают в public/**/*.md и public/llms-full.txt.

Проверка: после npx turbo build команда grep -n "ComponentName" apps/docs/public/llms-full.txt apps/docs/public/api/*.md должна ничего не вернуть. То же правило для HTML-entity типографики (&nbsp;, &shy;, …) — заменяй/убирай в expander'е, в AI-facing Markdown они попадать не должны.

Импорт MDX-компонентов — НЕ через re-export

Не делай export { X } from '...' в mdx-components.tsx — Turbopack может не зарезолвить компонент в runtime. Вместо этого: в mdx-components.tsximport для customMdxComponents, в markdown-content.tsx — импорт напрямую из файла-источника (@/components/mdx/steps и т.п.).

Turbopack / dev-сервер

  • turbo check ловит ошибки типов, но не проблемы резолва модулей Turbopack — всегда тестируй в runtime (bun turbo dev) после добавления / регистрации компонента.
  • После изменения регистраций компонентов или добавления TS/TSX-файлов — перезапусти dev-сервер (pkill -f "next dev", rm -rf apps/docs/.next, потом bun turbo dev). Turbopack HMR часто их пропускает.
  • Next.js: оставаться на 16.0.x (16.0.10). 16.1.x ломает next dev --turbopack (server-external-packages.json переименован в .jsonc, Turbopack всё ещё ждёт .json). Build работает, ломается только dev. Перепроверять перед апгрейдом.
  • Middleware Next 16 живёт в apps/docs/proxy.ts (Next переименовал middleware.tsproxy.ts). Если оба файла присутствуют — build падает.

Заголовки — без декоративных символов

В MDX-заголовках (##, ###) и в <Step title="..."> нельзя использовать: em dash , стрелки → ← ⇒, плюс +, латинизм vs и inline-код / backticks (`guest`, `chat_ids`). Заголовки попадают в боковой TOC и там смотрятся как шум; backticks в заголовке не рендерятся как код — отображаются сырые символы. Называй сущность словами («гостевая роль», «чаты»), а идентификатор раскрывай в тексте под заголовком. Скобки (...) и дефис в составных словах (webhook-слот) — нормально.

Переписывай в чистую фразу:

Плохо Хорошо
### Execute Step — запуск одного узла ### Запуск одного узла через Execute Step
<Step title="Деактивировать → протестировать → активировать"> <Step title="Временная деактивация продакшен-workflow">
## Роль "guest" и "chat_ids" при создании (backticks в заголовке) ## Гостевая роль и чаты при создании сотрудника

Проверка перед коммитом: grep -En '^#{2,3}.*( — | → | \+ |)' apps/docs/content/**/*.mdx`

Дизайн-система — минимальный размер шрифта

text-[11px] допустим только с uppercase / capitalize (мелкие ярлыки). Для обычного текста минимум — text-[12px]. Не «чини» 12-пиксельные подсказки до 11 — 11px нормальным начертанием слишком мелко.

TypeSpec — подводные камни

  • @opExample не работает с HttpPart<T> (multipart) — строковые значения нельзя присвоить HttpPart<string>. Multipart-примеры обрабатывай в генераторах.
  • @encodedName("multipart/form-data", ...) не генерирует OpenAPI- секцию encoding — имена свойств схемы остаются camelCase; мэппинг wire-имён надо делать отдельно.
  • Schema.properties — это Record<string, Schema> | undefined, перед Object.entries() нужно сузить тип.
  • После правки typespec.tsp обязательно пересобирать: npx turbo build --filter=@pachca/spec --force — иначе openapi.yaml останется устаревшим и доки не отразят изменение.
  • @doc полей моделей: коротко, без markdown bold. Таблица параметров рендерит описание поля как текст: inline `code` превращается в чип, а **bold** показывается как литерал **. Одно- два коротких предложения, самодостаточно, без cross-ref'ов типа «см. описание метода». Не выдумывай уточнения — используй ровно те термины, которые уже есть в доках. Подробные правила / списки ошибок / edge-case'ы — в @doc("""...""") операции (рендерится как полный markdown над таблицей; там много абзацев — ок). Эталон длины: User.skip_email_notify (2 коротких предложения).
  • Используй уже существующую в spec лексику — не выдумывай синонимы. Перед тем как добавить новое слово в @doc, grep его в packages/spec/typespec.tsp и apps/docs/content/api/**/*.mdx. Ноль попаданий — значит ты придумываешь термин. Найди слово, которым другие эндпоинты уже описывают ту же сущность, и используй его. Одна и та же идея, выраженная двумя разными словами в разных местах API, читается как две разные идеи у того, кто открыл доки впервые.
  • @doc методов — нейтральный голос, без перечисления аудитории. Описывай что метод делает, а не кто его вызывает. Пользовательские и ботовые токены ходят в одни и те же эндпоинты с одинаковой семантикой доступа — формулировка «доступных пользователю или боту» расщепляет одну идею на два клауса без причины. Используй второе лицо («у которых вы состоите») или безличную конструкцию («список доступных тредов»).
  • Без per-method исключений в @doc shared-моделей. Поля общих моделей (PaginationMeta, Message, Chat, User, …) рендерятся на каждом эндпоинте, который их использует. Если в описании есть «хвост» про то, как один конкретный эндпоинт ведёт себя иначе, этот хвост вылезает в таблице параметров у всех остальных эндпоинтов как шум. Особенности конкретного метода живут в (а) его собственном @doc("""..."""), и (б) в гайде, где эта особенность уже описана. В @doc поля shared-модели — никогда.
  • Терминальная точка в @doc — по числу предложений. Сложившаяся конвенция (≈863 однострочных @doc: ≈825 без точки, ≈38 с ней): одна фраза / одно предложение (label вроде @doc("Тип файла")) — без терминальной точки; многопредложное описание (два и больше предложений) — с точкой в каждом, включая последнее (живые примеры: User.email, User.phone_number). Та же логика, что и в пунктуации changelog'ов — updates-format §3. Когда разбиваешь точкой с запятой на два предложения, результат — многопредложный, последнее тоже должно заканчиваться точкой.
  • Синхронность EN overlay с описаниями операций. $.paths[...].<method>.update.description в packages/spec/overlay.en.yaml — это полная замена описания. Если добавил абзац в @doc русской операции, но не добавил в её overlay- таргет, английская версия молча теряет абзац (overlay:apply не падает — кириллицы не осталось). Редактируешь русское описание операции — одновременно правь и её EN overlay-таргет.

См. также: CONTRIBUTING · формат обновлений · API-аудит