# USER_GUIDE_ARCHITECTURE.md

Статус: **утверждён** (см. §10). Ничего из описанного здесь ещё не реализовано — сам этот
документ был планом, по образцу того, как `CUTOVER_PLAN.md` предшествовал Live Cutover;
реализация (User Guide v1, ограниченный список разделов) начинается отдельным шагом после этого
утверждения.

---

## 0. Главный принцип: два разных типа документации

| | Developer Portal (`docs/site/`) | User Guide (этот документ) |
|---|---|---|
| Роль | **SSOT** — витрина существующих документов | **Learning Portal** — новый, обучающий контент |
| Источник текста | Полностью markdown-файлы проекта, отображаются как есть | Частично код (факты), частично написанный вручную текст (педагогика) |
| Что происходит при изменении кода | Контент обновляется сам (fetch при следующей загрузке) | Автоматическая часть обновляется сама; написанная руками часть — **может устареть**, требует процесса проверки (см. §5) |

Код знает, **что делает** функция (`showAddModal()` открывает модалку с полями `f_word`,
`f_translation`...). Код не знает, **как правильно объяснить** пользователю, зачем это нужно,
в каком порядке действовать, какие есть типичные ошибки. Смешивать эти два источника в одном
непрозрачном алгоритме — то, что явно запрещено этим планом.

**Из этого следует жёсткое ограничение**, которое обязано соблюдаться при реализации: ни один
раздел не имеет права на 100% состоять из автоматически сгенерированного текста, выдаваемого
за инструкцию. Автоматическая часть — только строго фактическая (список кнопок/команд/полей),
явно отделённая визуально и структурно от написанной руками части.

---

## 1. Что реально можно извлечь автоматически — проверено на коде, не предположено

Перед тем как писать этот план, проверил `grep`-ом реальные файлы `src/modules/vocabulary/screens/*.js`.
Вывод: единообразного паттерна кнопок в коде **нет** — используется смесь `id="vocabX"`,
`data-action="x"`, `data-rating="0"`, `data-filter="x"`, `data-delete="${id}"`. Это ограничивает,
что можно честно назвать «автоматически найденным», не выдумывая единую семантику там, где её
в коде не заложено.

| Факт | Извлекаемо автоматически? | Как |
|---|---|---|
| Название экрана, иконка, порядок в меню | ✅ Да | `manifest.js navigation[]` (уже есть паттерн в Developer Portal — Capability API страница) |
| Command ID экрана | ✅ Да | `manifest.js commands{}` |
| Список кнопок на экране + их видимый текст | ✅ Да (с оговоркой) | Regex по `<button[^>]*>(.*?)</button>` в файле экрана — текст извлекается надёжно, семантика (что именно делает кнопка) — нет |
| Какие capability использует экран (PDF, speech, export…) | ✅ Да | Уже есть в Developer Portal (Capability API страница) — переиспользуется, не дублируется |
| Горячие клавиши | ❌ Нет — **их не существует в коде** | Legacy (`legacy-app.js`) имел Space/стрелки/1-4/T; в плагине не перенесены (задокументированный известный пробел, `CHANGELOG.md` → «Известные ограничения»). Раздел, который претендовал бы показать «горячие клавиши» автоматически, показал бы пустоту либо соврал |
| Смысл/назначение кнопки за пределами текста | ❌ Нет | Требует человека |
| Порядок шагов, на что обратить внимание, типичные ошибки | ❌ Нет | Требует человека |

Вывод: автоматическая часть раздела = «сколько кнопок, как называются, какие capability
задействованы» — короткая фактическая справка, не инструкция. Всё остальное — раздел «Написанное
руководство», см. §3.

---

## 2. Структура каталогов (предложение)

```
docs/academy/
├── index.html
├── css/style.css
├── js/
│   ├── app.js            — тот же паттерн роутинга/темы/поиска, что docs/site/
│   ├── content.js         — реестр разделов
│   ├── autoFacts.js        — извлечение фактов из src/modules/vocabulary/** (см. §1)
│   └── markdown.js          — переиспользуется как есть из docs/site/js/ (не дублируется — либо
│                              общий модуль в docs/shared/, либо симлинк; решить при реализации)
└── content/
    ├── study.md            — написанное руководство по экрану Study
    ├── list.md
    ├── batch.md
    ├── pdf-import.md
    ├── test.md
    ├── decks.md
    ├── statistics.md
    ├── settings.md
    ├── getting-started.md   — не привязан к одному экрану
    ├── organization.md      — см. явную оговорку в §4
    └── faq.md
```

Название каталога — `docs/academy/`, не `help/`/`docs/help/`, вслед за вашей формулировкой
«Knowledge Platform Academy». Если предпочитаете `docs/help/` — не принципиально, меняется одной
строкой при реализации.

**Переиспользование, не копирование:** `markdown.js` (рендерер) и паттерн `fetchText`/кэша из
`docs/site/js/utils.js` — тот же код, что уже есть и проверен. Решение при реализации: либо
вынести в `docs/shared/js/` и импортировать из обоих порталов, либо оставить дублирование двух
небольших файлов ради независимости порталов друг от друга (Developer Portal не должен ломаться,
если что-то поменяется в User Guide, и наоборот) — открытый вопрос, отмечаю здесь явно, а не
решаю сам.

---

## 3. Формат раздела — двухчастная схема

Каждый раздел, привязанный к экрану, состоит из двух блоков, визуально разделённых (не слитых
в один текст):

```
┌─────────────────────────────────────────┐
│ Экран: Study                             │
├─────────────────────────────────────────┤
│ 🤖 Автоматически найдено                 │  ← autoFacts.js, живой fetch, как Developer Portal
│                                           │
│ Команда: vocabulary.study                │
│ Кнопки на экране: 5                      │
│  • 🔄 Перевернуть                        │
│  • ◀ Пред. / След. ▶                     │
│  • Снова / Трудно / Хорошо / Легко (SRS) │
│ Capability: speech (озвучка слова)       │
│                                           │
│ ⚠️ Горячие клавиши: не реализованы        │  ← честно показывает пробел, не молчит
├─────────────────────────────────────────┤
│ 📖 Руководство                           │  ← content/study.md, написан человеком
│                                           │
│ Как эффективно пользоваться режимом      │
│ обучения...                              │
│                                           │
│ Шаг 1. ...                               │
│ Шаг 2. ...                               │
│                                           │
│ Советы                                   │
│ ...                                       │
│                                           │
│ Типичные ошибки                          │
│ ...                                       │
└─────────────────────────────────────────┘
```

Технически: `render(screenId)` = `autoFactsHtml(screenId) + sourceBar + mdBlock(content/<screenId>.md)`.
Если `content/<screenId>.md` отсутствует — раздел показывает только автоматический блок и явную
плашку «Руководство ещё не написано» (тот же честный паттерн, что ROADMAP.md в Developer Portal),
**не блокирует** показ автоматической части.

---

## 4. Разделы (сопоставление с реальными 8 экранами + примечания)

| Раздел | Экран/тема | Автоматическая часть готова технически? |
|---|---|---|
| Начало работы | — (не экран) | Нет — целиком написан вручную |
| Study | `study` | Да |
| Добавление слова | `addWord` (модалка, не экран) | Да, но иначе — команда без `.screen`-контейнера |
| Список слов | `list` | Да |
| Массовое добавление | `batch` | Да |
| Импорт PDF | `pdf` | Да |
| Тест | `test` | Да |
| Колоды | `decks` | Да |
| Статистика | `stats` | Да |
| Настройки | `settings` | Да |
| **Организация** | — | ⚠️ **Почти нет UI** — RBAC/Membership/Role существуют в Core (см. Developer Portal → Multi-Tenant), но нет ни одного экрана плагина для управления пользователями/ролями. **Решение (утверждено):** раздел не исключается, а показывает статус-заглушку — см. ниже |
| FAQ | — | Нет — целиком написан вручную |

**Раздел «Организация» — статус-заглушка, не пустота и не полноценная статья.** Автоматическая
часть в этом случае не найдёт ни одного экрана (`screenId` не указан — его физически нет) —
вместо попытки её отрендерить раздел показывает фиксированный текст:

```
Организация
Статус: готовится.

Данная функциональность предусмотрена архитектурой Knowledge Platform (Tenant, Role,
Membership, RBAC — см. Developer Portal → Multi-Tenant), однако пользовательский интерфейс
для управления организациями появится в одном из следующих Milestone.

Этот раздел будет автоматически расширен после появления соответствующих экранов.
```

Технически это раздел без `screenId` и без `content/<id>.md` — реестр разделов (`content.js`)
помечает его `stub: true`, рендер-функция возвращает текст выше вместо обычного двухчастного
формата. Как только у раздела появится реальный `screenId` (Milestone 2+) — `stub: true` снимается
одной правкой реестра, раздел автоматически переходит на обычную двухчастную схему §3, текст
статус-заглушки заменяется на настоящую статью (Черновик → ... по циклу §6).

**Видео/GIF-анимации** (упомянуты в исходном ТЗ на User Guide) — сознательно не включаю в этот
план. Запись/монтаж — не то, что можно сделать автоматизированным способом или ответственно
оценить по времени в рамках этого документа; предлагаю оставить как явный пункт на будущее
(`content/<screen>.md` может ссылаться на видео, когда/если они появятся — формат это не
блокирует), не обещать сейчас.

---

## 5. Поддержание актуальности — честный, не «магический» механизм

Автоматическая часть актуальна всегда — тот же живой `fetch()`, что в Developer Portal, ничего
особенного придумывать не нужно.

Написанная руками часть — **не может** проверяться программно на смысловую точность (это и есть
причина, по которой она написана руками). Предлагаемый процесс, без иллюзии полной автоматизации:

- Каждый `content/<screen>.md` начинается с короткой служебной строки:
  `<!-- проверено против: src/modules/vocabulary/screens/studyScreen.js @ 2026-07-13 -->`
- `check-links.mjs` (уже есть в Developer Portal, расширяется на `docs/academy/`) при каждом
  прогоне сверяет: изменился ли `Last-Modified` экрана (уже умеем читать, см. `utils.getLastModified`
  из Developer Portal) **позже**, чем дата в этой служебной строке — если да, печатает
  предупреждение («study.md не проверялся после последнего изменения studyScreen.js»), не
  блокирует, не переписывает текст сам. Это сигнал человеку, не замена ревью.
- Это единственный честный уровень автоматизации здесь: **обнаружение возможного устаревания**,
  не автоматическое исправление текста.

---

## 6. Жизненный цикл статьи

Формализует и делает видимым в UI то, что §5 уже описывал как механизм обнаружения устаревания —
не отдельная система, а его явное состояние.

```
Черновик
    ↓
Проверка
    ↓
Утверждена
    ↓
Опубликована
    ↓
Требует обновления
```

Статус живёт в той же служебной шапке файла, что и дата проверки из §5 (один механизм, не два):

```
<!--
status: черновик | проверка | утверждена | опубликована | требует-обновления
проверено-против: src/modules/vocabulary/screens/studyScreen.js
дата-проверки: 2026-07-13
-->
```

**Переходы:**
- Черновик → Проверка → Утверждена → Опубликована — вручную, при написании и ревью статьи.
  Черновики (`status: черновик`) не попадают в основную навигацию портала — видны только через
  прямую ссылку, чтобы недописанный текст не выглядел как готовая инструкция.
- Опубликована → **Требует обновления** — **автоматически**, не вручную: `check-links.mjs`
  (и сам портал при показе страницы) сверяет `Last-Modified` файла экрана
  (`utils.getLastModified`, уже есть) с `дата-проверки` в шапке статьи. Если экран менялся
  позже — статус на странице показывается как жёлтая плашка «Содержимое могло устареть — экран
  изменился после последней проверки (DATE)», статья остаётся полностью читаемой и НЕ
  помечается как ошибка (важное отличие от того, как портал обращается с реальными сбоями
  fetch — те как раз показываются как ошибка, см. Developer Portal `app.js`).
- Из «Требует обновления» обратно в «Опубликована» — только вручную, человек подтверждает,
  что текст всё ещё верен (или правит его), обновляет `дата-проверки`.

Автоматическая часть (§1, §3) в статус не входит — она либо есть и актуальна (всегда, живой
fetch), либо технически не найдена (например, для `stub`-разделов вроде «Организация», §4).
Статус жизненного цикла — только про написанную вручную часть.

---

## 7. Как добавить новый раздел

1. Написать `docs/academy/content/<id>.md` (обычный markdown, тот же рендерер, что и везде).
2. Если раздел привязан к экрану плагина — добавить `{ id, screenId, title }` в реестр разделов
   в `content.js` порталa; `autoFacts.js` сам найдёт кнопки/команду/capability по `screenId`.
3. Если раздел не привязан к экрану (FAQ, «Начало работы») — тот же реестр, без `screenId`,
   автоматическая часть просто не рендерится.
4. Прогнать `check-links.mjs` (расширенный, см. §5).

---

## 8. Контекстная справка из самого приложения — решение принято, реализация отложена

Исходное ТЗ хотело кнопку `?`/`📖 Помощь` на каждом экране приложения, ведущую в
`docs/academy/#screen`. Это требует правки `src/modules/vocabulary/**` (новая кнопка в реальном
UI) — то есть **новая функциональность в продукте**, а не в документации. Прямо конфликтует
с зафиксированным feature freeze («никаких новых функций до Milestone 2»,
`ARCHITECTURE.md` §0 статус, `CHANGELOG.md`).

**Решение (утверждено):**
- ❌ Не реализуется сейчас, ни в каком виде.
- ✅ Явно зафиксировано как кандидат на Milestone 2 (не RFC — не меняет границы платформы,
  не подпадает под критерий RFC из `docs/rfcs/README.md`: «идея, которая меняет границы
  платформы… исход обсуждения не очевиден заранее» — здесь всё очевидно, это обычная UI-фича
  внутри уже согласованных границ, откладывается только из-за freeze, не из-за неопределённости).
- ✅ В архитектуре User Guide зарезервирован раздел «Будущая интеграция» (ниже) — не код, а
  запись, чтобы при формализации Milestone 2 не пришлось заново вспоминать это решение.
- ✅ Добавлено пунктом №1 в `MILESTONE_2_CANDIDATES.md` (2026-07-13) — тот же бэклог, куда
  попадают все подобные уже-решённые-но-отложенные пункты, не только этот.

### Будущая интеграция (запись на Milestone 2, не реализация)

Когда Milestone 2 будет формализован и снимет freeze на новую функциональность:
кнопка `?`/`📖 Помощь` на каждом `.screen`-контейнере плагина → `deps.showScreen`-подобный
переход, только во внешний портал (`window.open` или ссылка) на
`docs/academy/index.html#/<screenId раздела User Guide>` — сопоставление `screenId` уже
существует в реестре разделов (§7 «Как добавить новый раздел»), дополнительной работы по
маппингу не потребуется, только сама кнопка в shell/экранах.

---

## 9. Явные не-цели этого этапа

- Раздел «Организация» — не пишется как полноценная статья, пока нет реального UI; показывает
  только статус-заглушку «готовится» (см. §4).
- Видео/GIF — не пишутся, только место в формате под них на будущее.
- Контекстная справка из приложения (кнопка `?`) — не реализуется сейчас, зафиксирована как
  кандидат Milestone 2 (см. §8).
- Автоматическая проверка смысловой точности написанного текста — невозможна в принципе, не
  обещается (см. §5).
- User Guide не заменяет и не дублирует Developer Portal — доменная модель, ADR, архитектура
  остаются только там.

---

## 10. Утверждение

Утверждён 2026-07-13, с тремя правками к исходному черновику:

1. **§4 — «Организация» не исключается.** Показывает статус-заглушку «готовится» вместо полного
   отсутствия раздела — пользователь видит, что возможность архитектурно предусмотрена, просто
   пока без UI.
2. **§8 — контекстная справка перенесена в Milestone 2**, не RFC (не меняет границы платформы).
3. **§6 (новый) — «Жизненный цикл статьи»** добавлен: явный видимый статус
   (черновик/проверка/утверждена/опубликована/требует-обновления), с автоматическим переходом
   в «требует обновления» при рассинхронизации с `Last-Modified` экрана — формализует то, что
   §5 уже описывал как механизм, не вводит новую систему.

**Разрешённый объём User Guide v1** (следующий шаг, отдельно от этого документа):

Писать сейчас: Начало работы, Карточки, Изучение, PDF, Импорт/Экспорт, Статистика, Настройки, FAQ.
Не писать сейчас: Организация (только статус-заглушка §4), контекстная помощь (§8), управление
пользователями, RBAC-интерфейс.
