24 KiB
BRIEF: Анализ и рекомендации по документации Nubes Terraform Provider
Для: Claude Sonnet Дата: 2026-08-10 Задача: Изучить ВЕСЬ пайплайн генерации документации, проанализировать фронтенд и UX, выдать подробные рекомендации по улучшению.
1. ЧТО ЭТО ТАКОЕ
Nubes Terraform Provider — это внутренний провайдер для Terraform, который управляет облачными сервисами (~43 сервиса: PostgreSQL, Redis, Kafka, S3, VMware и т.д.) через API платформы Nubes.
Документация — автосгенерированный статический сайт на mkdocs-material, который хостится в S3 и доступен юзерам провайдера.
Юзер документации — DevOps-инженер, который пишет Terraform-манифесты. Ему нужно:
- Быстро найти нужный ресурс (сервис)
- Понять какие параметры обязательные, какие опциональные, какие значения допустимы
- Скопировать готовый HCL-пример и подставить свои значения
- Узнать какие outputs можно использовать для связки ресурсов
- Понять что делает каждая операция (create/modify/suspend/resume/...)
2. ПОЛНЫЙ ПАЙПЛАЙН ГЕНЕРАЦИИ
┌─────────────────────────────────────────────────────────────────┐
│ Шаг 1: YAML-спеки │
│ generated/{stand}/resources_yaml/{service}.yml │
│ ~43 YAML-файла: параметры, типы, defaults, constraints, MAN │
└──────────────────────────┬──────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────┐
│ Шаг 2: docs-generator (Go) │
│ TOOLS/docs-generator/main.go │
│ │
│ Вход: YAML + --version + --api-endpoint + --provider-source │
│ Выход: плоские .md файлы в generated/{stand}/docs_llm/ │
│ │
│ На каждый сервис генерирует: │
│ {name}.md — MAN (руководство пользователя) │
│ {name}_example.md — HCL-примеры (minimal + full) │
│ {name}_params_create.md — таблица create-параметров │
│ {name}_params_modify.md — таблица modify-параметров │
│ {name}_outputs.md — выходные параметры + cloud snapshot │
│ {name}_ops.md — список всех операций │
│ {name}_params.md — лендинг со ссылками │
│ index.md — общий индекс всех ресурсов │
│ _nav_fragment.yml — фрагмент для mkdocs sidebar │
│ │
│ Ключевые функции в writers/writers.go: │
│ ResourceDocs() — вызывает все build* функции │
│ buildCreateParamsPage() — таблицы обязательных/опциональных │
│ buildExamplePage() — minimal + full HCL примеры │
│ buildManualPage() — MAN: HTML → Markdown конвертация │
│ buildOutputsPage() — output params + cloud snapshot │
│ buildOpsPage() — список операций │
│ renderParamTable() — Markdown-таблица параметров │
│ renderNestedParams() — вложенные sub_params (map-fixed) │
│ IndexMD() — индекс всех ресурсов │
│ WriteNavFragment() — sidebar навигация │
│ │
│ Таблицы: Markdown (| Code | Type | ... |), НЕ HTML. │
│ Навигация: inline-строка в header каждой страницы: │
│ **Manual** · [Create params] · [Modify params] · ... │
│ (активная страница выделена жирным) │
└──────────────────────────┬──────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────┐
│ Шаг 3: LLM-обогащение (Python) │
│ TOOLS/scripts/05_generate_docs_llm.py │
│ │
│ LLM: gpt-oss-120b (через api.aillm.ru) │
│ На вход: все .md файлы сервиса + YAML + MAN │
│ На выход: переписанные .md (те же имена файлов) │
│ │
│ Что LLM делает: │
│ A. Переносит value_list из Constraints в Description │
│ "value_list=1,3,5" → "Допустимые значения: **1, 3, 5**" │
│ B. Преобразует regex в читаемый текст │
│ "regex=^[a-f0-9-]+$" → "Формат: UUID" │
│ C. Заполняет пустые Description (из MAN, имени параметра) │
│ D. Описывает map-fixed группы (из sub-params имён + MAN) │
│ E. Описывает операции без описания (suspend, resume, ...) │
│ F. Переводит HTML MAN в читаемый Markdown │
│ G. Заменяет TODO в примерах на реальные значения │
│ │
│ ЖЁСТКИЕ ЗАПРЕТЫ: │
│ - НЕ менять имена параметров │
│ - НЕ трогать HCL-блоки │
│ - НЕ трогать навигационные строки │
│ - НЕ менять структуру таблиц │
│ - НЕ выдумывать типы/defaults/constraints │
└──────────────────────────┬──────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────┐
│ Шаг 4: mkdocs-material (Python) │
│ mkdocs.yml + mkdocs build │
│ │
│ Тема: material, синяя схема │
│ Фичи: navigation.path, navigation.footer, navigation.indexes │
│ Markdown-расширения: md_in_html, admonition, superfences, ... │
│ CSS: extra.css — компактные шрифты, скрыты боковые панели │
│ JS: fix-slash.js — авто-добавление / в конец URL │
│ Выход: site/ — статический HTML │
└──────────────────────────┬──────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────┐
│ Шаг 5: S3 (s3cmd sync) │
│ s3://nubes-terraform-registry/docs/{stand}/{provider}/{ver}/ │
│ Доступ: https://tf-registry.containerk8s.services.ngcloud.ru/ │
│ docs/nubes-test/nubes/5.0.5/ │
└─────────────────────────────────────────────────────────────────┘
3. ТЕКУЩАЯ СТРУКТУРА ФРОНТЕНДА
3.1 Макет страницы ресурса
Каждая страница ресурса (например, PostgreSQL) имеет:
┌─────────────────────────────────────────────────────────┐
│ # Resource nubes_postgres · Service ID: 90 · PostgreSQL│
│ │
│ **Manual** · [Create params] · [Modify params] │
│ · [Output params] · [Operations] · [Example] │ ← inline nav
│ │
│ ## MAN │
│ (текст руководства — переведён из HTML в Markdown) │
│ ... │
└─────────────────────────────────────────────────────────┘
3.2 Что скрыто
CSS скрывает обе боковые панели mkdocs:
.md-sidebar--primary { display: none !important; }
.md-sidebar--secondary { display: none !important; }
Это значит:
- НЕТ sidebar-меню — юзер не видит оглавление других ресурсов
- НЕТ table of contents — юзер не видит структуру текущей страницы
- Единственная навигация — inline-строка в header
3.3 CSS-особенности
font-size: 0.82rem— компактный шрифтmax-width: 61rem— умеренная ширина контента- MAN-контент:
font-size: 0.62rem— очень мелкий - НЕТ стилей для Markdown-таблиц (были для HTML-таблиц
.resource-table, теперь не применяются)
3.4 Индексная страница
Генерируется IndexMD() — простая таблица:
| ID | Ресурс | Описание |
|----|--------|----------|
| 1 | nubes_dummy | Болванка |
| 2 | nubes_template | Темплейт k8s |
...
Ссылки ведут на {name}.md.
4. ТЕКУЩИЕ ПРОБЛЕМЫ (ЧТО УЖЕ ИЗВЕСТНО)
4.1 Навигация — СЛАБОЕ МЕСТО №1
- Боковые панели скрыты → юзер теряется между страницами
- Inline-nav работает, но это неудобно: чтобы перейти к другому ресурсу, нужно вернуться на index
- Нет breadcrumbs между ресурсами (хотя mkdocs умеет
navigation.path) - Нет поиска по параметрам внутри ресурса
4.2 Таблицы параметров — СТАЛО ЛУЧШЕ
- Были HTML-таблицы, mkdocs их не рендерил → юзер видел голый текст
map-fixedmap-fixed - Исправлено: переведены на Markdown-таблицы → рендерятся корректно
- НО: стили
.resource-tableбольше не применяются (они были для HTML) - Описания параметров заполняются LLM, но не для всех (зависит от качества MAN)
4.3 Примеры (HCL) — работает
- Minimal example (только required) + Full example (с defaults) в раскрывашке
<details> - Юзер может скопировать и использовать
4.4 MAN-секция — перегружена
font-size: 0.62rem— очень мелко, трудно читать- HTML→Markdown конвертация в
htmlToMarkdown()— regex-костыль, может глючить - MAN содержит HTML из админки, его качество зависит от того, кто и как заполнял
4.5 Нет версионирования в интерфейсе
- Юзер не видит в UI какую версию провайдера он смотрит
- Хотя URL содержит версию (
/5.0.5/), в самой странице это не отображается
5. ЧТО ХОРОШО (НЕ ЛОМАТЬ)
- Автоматическая генерация из YAML — параметры всегда актуальны, не отстают от API
- Inline-навигация между страницами ресурса — понятно где ты находишься
- Markdown-таблицы — рендерятся везде, не зависят от HTML-санитайзеров
- LLM-обогащение — описания становятся читаемыми (value_list, regex, пустые ячейки)
- Cloud snapshot в outputs — реальные ключи
state_out_flatиvault_secretsиз облака - Dual example — minimal + full, юзер выбирает что нужно
6. ВОПРОСЫ К СОННЕТУ
Блок A: Навигация и структура сайта
A1. Как организовать навигацию между ресурсами (43 сервиса)?
- Варианты: sidebar mkdocs, отдельная страница-индекс с поиском, grouped by category
- Плюсы/минусы каждого подхода для DevOps-юзера
A2. Нужно ли вернуть боковую панель mkdocs (sidebar)?
- Если да — что в ней должно быть: дерево ресурсов? категории? поиск?
- Если нет — как улучшить inline-nav + index page?
A3. Как юзер должен быстро найти нужный ресурс?
- Группировка: Базы данных, Очереди, Хранилище, K8s, VMware, Приложения, Сеть
- Поиск по имени/описанию?
Блок B: Дизайн страницы ресурса
B1. MAN-секция сейчас font-size: 0.62rem. Как сделать читаемым?
- Оставить компактным но разборчивым?
- Сделать раскрывающимся (collapsed by default)?
- Вынести ключевую информацию выше?
B2. Как лучше структурировать страницу ресурса?
- Текущий порядок: Заголовок → Inline nav → MAN → ...
- Может: Заголовок → Краткое описание → Пример (сразу!) → Параметры → MAN (внизу)?
B3. Нужна ли версия провайдера в UI?
- Где показывать: в header? в title? в breadcrumb?
Блок C: Таблицы параметров
C1. Как улучшить читаемость таблиц параметров?
- Сейчас: Code | Type | Description | Constraints
- Нужны ли: Required (yes/no), Default, категории параметров?
- Группировка связанных параметров (например, все cluster_configuration вместе)?
C2. Как показывать вложенные параметры (map-fixed)?
- Сейчас: ### clusterConfiguration → отдельная таблица sub_params
- Лучше: раскрывающийся блок? инлайн в той же таблице?
Блок D: Примеры и HCL
D1. Как улучшить страницу Example?
- Сейчас: Minimal example сверху, Full example в
<details> - Добавить: описание каждого блока? комментарии в коде?
- Показывать реальные значения из облака?
Блок E: Общие рекомендации
E1. Какие ещё элементы не хватает?
- Changelog между версиями?
- Ссылки на связанные ресурсы (PostgreSQL → как связать с Lucee/NodeJS)?
- Предупреждения/важные заметки (lifecycle behaviour)?
E2. Приоритизация: что сделать в первую очередь для максимального UX-эффекта?
7. КОНТЕКСТ ДЛЯ ИЗУЧЕНИЯ
Файлы для чтения (в порядке важности):
- mkdocs.yml — конфигурация сайта, тема, фичи, CSS
- TOOLS/docs-generator/internal/writers/writers.go — ВСЯ генерация .md (~1000 строк, ключевой файл)
- TOOLS/docs-generator/main.go — CLI, флаги, оркестрация
- TOOLS/scripts/05_generate_docs_llm.py — LLM-обогащение, SYSTEM_PROMPT
- docs/LLM_DOCS_GENERATION.md — архитектурная документация
- docs/30_registry/assets/extra.css — CSS-стили
- docs/30_registry/javascripts/fix-slash.js — JS (trailing slash fix)
Посмотреть живьём (если есть доступ):
- https://tf-registry.containerk8s.services.ngcloud.ru/docs/nubes-test/nubes/5.0.5/ — индекс ресурсов
- https://tf-registry.containerk8s.services.ngcloud.ru/docs/nubes-test/nubes/5.0.5/postgres_params_create/ — пример страницы параметров PostgreSQL
- https://tf-registry.containerk8s.services.ngcloud.ru/docs/nubes-test/nubes/5.0.5/postgres_example/ — пример HCL
8. ОГРАНИЧЕНИЯ
- YAML = истина. Параметры, типы, defaults, constraints берутся ТОЛЬКО из YAML. Не выдумывать.
- mkdocs-material — выбранный фреймворк. Менять можно в рамках его возможностей.
- 43 сервиса — масштаб. Решения должны работать для всех, не только для PostgreSQL.
- Русский язык — вся документация на русском.
- Целевая аудитория — DevOps-инженеры, знают Terraform, не знают внутренностей Nubes.
9. ФОРМАТ ОТВЕТА
Жду от тебя структурированный анализ:
- Общая оценка текущего состояния документации (что хорошо, что плохо)
- Детальные рекомендации по каждому блоку вопросов (A1-E2)
- Приоритизированный план действий (Quick wins → Среднесрок → Долгосрок)
- Конкретные предложения по коду/CSS/структуре где применимо
- Антипаттерны — что НЕ стоит делать и почему
Не спеши. Изучи все файлы. Подумай как ДЕВОПС который впервые видит этот провайдер и пытается написать манифест для PostgreSQL.
10. УТОЧНЯЮЩИЙ ВОПРОС: Как смержить nav
Ты рекомендуешь вернуть sidebar с категориями. Но в mkdocs.yml секция nav: — статическая (руководства, глоссарий), а ресурсы генерируются динамически через WriteNavFragment() в _nav_fragment.yml.
Как правильно смержить статический nav: (руководства) и динамический (43 ресурса по категориям) в mkdocs?
Ответ Соннета
Нет встроенного !include в mkdocs. mkdocs-material не имеет нативного механизма подключения внешних YAML-фрагментов в nav:.
Вариант 1 — Рекомендован: расширить существующий Python pre-build шаг
В 04_build_and_publish_docs.sh уже есть Python-блок, который пишет .mkdocs.tmp.yml. Добавить туда чтение _nav_fragment.yml и инъекцию в nav::
import yaml
nav_fragment_path = Path(docs_dir) / "_nav_fragment.yml"
if nav_fragment_path.exists():
fragment = yaml.safe_load(nav_fragment_path.read_text(encoding="utf-8"))
resources_nav = fragment.get("resources_nav", [])
config = yaml.safe_load(text)
for item in config.get("nav", []):
if isinstance(item, dict) and "Ресурсы" in item:
item["Ресурсы"] = resources_nav
break
text = yaml.dump(config, allow_unicode=True, default_flow_style=False, sort_keys=False)
Плюсы: ноль новых зависимостей, PyYAML уже в окружении, merge в одном месте.
Вариант 2: docs-generator пишет полный mkdocs.yml (сложнее поддерживать).
Вариант 3: mkdocs-awesome-pages (не решает проблему merge).
Дополнительно: когда docs_dir переключается на generated/{stand}/docs_llm, пути 30_registry/guides/*.md ломаются. Решение: копировать 30_registry в docs_dir перед сборкой.
Итого: Вариант 1 — минимальные изменения, всё уже на месте.