Раздел «Документация» в админ-панели — контракт интеграции¶
Handoff команде админ-панели. Готовность со стороны Wiki по трём пунктам, которые вы запрашивали: (1) манифесты, (2) wiki за авторизацией + чистый
mkdocs.ymlбез CDN, (3)service_connect.data.docs. Спецификация структуры — ../projects/_STRUCTURE.md.
Статус готовности (со стороны Wiki)¶
| # | Что требовалось | Статус | Где |
|---|---|---|---|
| 1 | Манифесты сгенерированы | ✅ генерируются на сборке | hook material/overrides/hooks/manifests.py |
| 2 | Из mkdocs.yml убраны Google Analytics / внешние шрифты | ✅ сделано | mkdocs.yml (font: false, блок analytics удалён) |
| 2 | Wiki за авторизацией | ⛔ инфра-задача (reverse-proxy/forward-auth) — вне репозитория, нужно поднять перед публикацией | см. «Приватность и CSP» |
| 3 | service_connect.data.docs заполнен | 🟡 SQL готов (ниже) — применить на admin_api_test | этот документ |
После этого со стороны админки: раздел «Документация» (per-project, по манифесту, гейт projectDocsView).
1. Манифесты¶
На каждой сборке сайта hook генерирует:
/projects/<slug>/manifest.json— дерево документации проекта;/projects/manifest.index.json— реестр проектов.
path в дереве = реальный served-URL MkDocs (use_directory_urls), напр. projects/teslapay/scenarios/payment/topup/. Узлы-каталоги без своего index.md имеют path: null — это нелистаемые заголовки групп (рендерить как раскрывающийся узел без ссылки).
Схема manifest.json (на проект)¶
{
"slug": "teslapay",
"title": "TeslaPay",
"path": "projects/teslapay/",
"category": null,
"children": [
{
"category": "scenarios",
"title": "Бизнес-сценарии",
"path": "projects/teslapay/scenarios/",
"children": [
{
"title": "Пополнение счёта",
"path": "projects/teslapay/scenarios/payment/topup/",
"children": []
}
]
}
]
}
business-analytics, system-analytics, tech-info, scenarios. Узел: { title: string, path: string|null, children: Node[] }; у категорийного узла дополнительно category: string. Схема manifest.index.json¶
{
"schema": 1,
"projects": [
{ "slug": "teslapay", "title": "TeslaPay", "manifest_path": "/projects/teslapay/manifest.json" },
{ "slug": "trientes", "title": "Trientes", "manifest_path": "/projects/trientes/manifest.json" }
]
}
Путь манифеста —
/projects/<slug>/manifest.json(рядом с контентом проекта), а не/<slug>/.... Это уточнение к раннему черновику спеки; именно этот путь кладите вservice_connect.data.docs.manifest_path.
Как получить тело документа¶
GET {base_url}{path} отдаёт готовую HTML-страницу MkDocs. Два варианта встраивания (на ваш выбор):
- iframe с приватного wiki-origin + origin-проверка (как у
DrawioEditor), узкийframe-src; - прокси через admin-api (admin-api ходит на wiki по внутреннему адресу, отдаёт HTML фронту) — не расширяет CSP фронта.
2. Приватность и CSP (инфра, до публикации)¶
- Wiki закрыть авторизацией (reverse-proxy / forward-auth) — публиковать для встраивания только за аутентификацией.
- CSP: узкий
frame-srcна один доверенный wiki-origin (при iframe), либо проксирование HTML через admin-api без расширения CSP фронта. mkdocs.ymlочищен от внешних CDN:font: false(системные шрифты, безfonts.gstatic.com), убран Google Analytics. Emoji/иконки рендерятся инлайн на сборке (Twemoji-SVG), рантайм-запросов наружу нет.- ⚠️ Раздел
tech-infoсодержит креды к TEST-БД и карту портов (по решению владельца — это допустимо для wiki, т.к. доступ к разделам ограничен и креды нужны допущенным для получения доступа к БД). Следствие для админки: доступ кtech-infoдолжен быть под тем же (или более строгим) гейтом, что и весь раздел документации —projectDocsView. Не отдаватьtech-infoпользователям без права.
2.1 Маскирование секретов в документах (требуется от команды Wiki)¶
Двухуровневая модель доступа:
projectDocsView— видеть раздел «Документация» и читать документы (включаяtech-info).projectDocsSecrets— дополнительно видеть секреты (пароли/креды) в открытом виде. У кого права нет — секреты заменяются маской••••••на стороне admin-api до отдачи фронту (оператор без права физически не получает значение секрета — маскирование серверное, не CSS).
Что нужно сделать в документах: обернуть каждое секретное значение маркером, который попадёт в итоговый HTML как элемент с классом secret или атрибутом data-secret. admin-api при отсутствии права заменяет всё содержимое такого элемента маской.
Примеры в Markdown (инлайн-HTML работает в MkDocs):
Пароль БД: <span class="secret">lt6eTQiB6EhWOqwe</span>
DSN: postgres://admin_api:<span class="secret">lt6eTQiB6EhWOqwe</span>@10.8.0.11:15405/admin_api_test
В таблице кредов — оборачивать значение в ячейке:
| Сервис | Пользователь | Пароль |
|--------|--------------|--------|
| users | users_test | <span class="secret">kvPfwLp3MkAbqWrK</span> |
Рекомендации: - Маркировать только само значение, не подпись («Пароль:» оставлять видимым). - Можно добавить в extra.css темы стиль .secret { … } (например моноширинный фон) — для операторов с правом значение видно как обычно; маскирование значения не зависит от CSS. - Вложенная разметка внутри .secret допустима — маскируется весь элемент целиком. - Если значение не обёрнуто маркером — оно не маскируется (виден всем с projectDocsView). Поэтому для tech-info важно покрыть маркером все креды.
3. service_connect.data.docs¶
Платформенное правило: базовый URL/слаг/путь манифеста — не env и не хардкод, а в service_connect.data per-project. Ключ docs добавляется к существующему data (не перезаписывая service_hosts / flat-адреса).
Таблица service_connect(id UUID PK, project_name TEXT, data JSONB, project_id UUID FK), БД admin_api_test (10.8.0.11:15405). Существующие строки: TeslaPay 0e1c7f6b-9439-4cc0-b2a9-c10330efd09d, Trientes 8557fd43-07da-41c1-aa1d-c37bb0e3515a.
-- TeslaPay: добавить ключ docs к существующему data
UPDATE service_connect
SET data = (data::jsonb || '{
"docs": {
"base_url": "https://wiki.gsmsoft.eu",
"project_slug": "teslapay",
"manifest_path": "/projects/teslapay/manifest.json"
}
}'::jsonb)::json,
update_date = NOW()
WHERE id = '0e1c7f6b-9439-4cc0-b2a9-c10330efd09d';
-- Trientes: то же (flat-адреса в data сохраняются)
UPDATE service_connect
SET data = (data::jsonb || '{
"docs": {
"base_url": "https://wiki.gsmsoft.eu",
"project_slug": "trientes",
"manifest_path": "/projects/trientes/manifest.json"
}
}'::jsonb)::json,
update_date = NOW()
WHERE id = '8557fd43-07da-41c1-aa1d-c37bb0e3515a';
-- Проверка:
-- SELECT project_name, data->'docs' FROM service_connect ORDER BY project_name;
Автоматизация «новый проект → docs»¶
- Админка при
POST /project/v1дополняетservice_connect.data.docs(project_slug,manifest_path = /projects/<slug>/manifest.json) — обязательный шаг создания проекта. - Скелет папки в
common_docs: CI-джобаscaffoldкопирует_TEMPLATE→<slug>/, добавляет проект в реестр и открывает MR (запуск вручную командой Wiki или pipeline-trigger из admin-api). Рантайм-запись сервиса в git не делаем.
Чек-лист включения раздела¶
- Wiki закрыта авторизацией (forward-auth).
- Применён SQL
service_connect.data.docs(teslapay, trientes). - Право
projectDocsViewдобавлено и навешено на раздел (включаяtech-info). - Секреты в документах обёрнуты маркером
class="secret"/data-secret(маскируются для операторов безprojectDocsSecrets) — см. §2.1. - Выбран способ встраивания (iframe+origin-check / прокси admin-api) и настроен CSP.
- Админка читает
manifest.index.json→ per-projectmanifest.json→ строит дерево → грузит тело поpath.