# Модули

# Пользователи



# Тренинги

# Функциональные требования: Модуль «Тренинги»

**Версия:** 1.1
**Статус:** Draft
**Аудитория:** Команда разработки (backend, frontend, QA, PM)
**Референс:** GetCourse (getcourse.ru)

---

## 1. Назначение документа

Документ описывает функциональные требования к модулю «Тренинги» — ядру обучающей платформы. Модуль отвечает за:

- создание и управление учебным контентом (тренинги, подтренинги, уроки);
- выдачу и разграничение доступов к контенту;
- управление порядком прохождения (последовательное открытие и расписание).

Документ не описывает технический стек, архитектуру и схему БД — только бизнес-логику и поведение системы.

---

## 2. Глоссарий

| Термин | Определение |
|---|---|
| **Тренинг** | Корневой образовательный контейнер (курс). Содержит уроки и/или подтренинги. |
| **Подтренинг** | Тренинг, вложенный в другой тренинг или подтренинг. Используется для разбиения курса на модули/темы. По функционалу идентичен тренингу. |
| **Урок** | Атомарная единица обучения с контентом (текст, видео, задания и т.д.). |
| **Ученик** | Пользователь, получивший доступ к тренингу и проходящий обучение. |
| **Группа** | Сегмент пользователей, используемый для группового управления доступами. |
| **Расписание** | Правила открытия уроков во времени (по датам или с задержками). |
| **Стоп-урок** | Урок, блокирующий переход к следующим урокам до его выполнения. |

---

## 3. Роли пользователей

На текущем этапе в модуле «Тренинги» определена одна роль:

**Ученик** — пользователь, имеющий доступ к тренингам согласно членству в группах. Может просматривать уроки (с учётом правил открытия) и отправлять ответы на задания.

Остальные роли (администратор, преподаватель и т.д.) будут определены отдельно в последующих версиях документа.

---

## 4. Иерархия контента

### 4.1. Модель

Поддерживается неограниченная вложенность подтренингов:

```
Тренинг
├── Урок 1
├── Урок 2
├── Подтренинг A
│   ├── Урок A.1
│   ├── Подтренинг A.1
│   │   ├── Урок A.1.1
│   │   └── Подтренинг A.1.1
│   │       └── Урок A.1.1.1
│   └── Урок A.2
├── Подтренинг B
│   ├── Урок B.1
│   └── Урок B.2
└── Урок 3
```

### 4.2. Правила

- Тренинг и подтренинг могут содержать уроки и/или подтренинги в любом сочетании.
- Глубина вложенности подтренингов не ограничена.
- Порядок элементов внутри контейнера задаётся вручную и сохраняется.
- Урок принадлежит ровно одному родителю (тренинг или подтренинг).
- Подтренинг принадлежит ровно одному родительскому контейнеру (тренингу или подтренингу).
- Циклические зависимости запрещены: подтренинг не может быть вложен в самого себя (прямо или транзитивно).

### 4.3. Терминология: тренинг vs подтренинг

С точки зрения модели данных и поведения системы «тренинг» и «подтренинг» — это одна и та же сущность. Разница только в положении в иерархии:

- **Тренинг** — корневой элемент, не имеет родителя.
- **Подтренинг** — элемент, у которого есть родитель (тренинг или другой подтренинг).

Один и тот же элемент может быть тренингом или подтренингом в зависимости от того, где он расположен. При переносе корневого тренинга внутрь другого тренинга он становится подтренингом, и наоборот.

---

## 5. Сущность «Тренинг / Подтренинг»

### 5.1. Основные атрибуты

- **Название** — отображается в списках и заголовках.
- **Описание** — краткое описание курса, видно ученикам.
- **Обложка** — изображение для карточки тренинга.
- **Статус** — черновик / опубликован / архивный.
- **Родитель** — ссылка на родительский тренинг/подтренинг (отсутствует для корневого тренинга).
- **Дата создания**, **дата публикации**.

### 5.2. Статусы

- **Черновик** — тренинг создан, но недоступен ученикам.
- **Опубликован** — тренинг активен и может выдаваться ученикам согласно правилам доступа.
- **Архивный** — тренинг скрыт из активных списков, но доступы сохраняются для исторических данных (опционально — с возможностью полного отзыва доступов).

### 5.3. Действия над тренингом

- Создание / редактирование / удаление.
- Дублирование (копирование структуры с уроками или без).
- Архивация / восстановление из архива.
- Управление составом уроков и подтренингов (добавление, удаление, изменение порядка).
- Перенос в другой родительский контейнер (становится подтренингом) или вынос в корень (становится тренингом).
- Настройка доступов (см. раздел 7).
- Настройка расписания (см. раздел 8).

---

## 6. Сущность «Урок»

### 6.1. Основные атрибуты

- **Название**.
- **Контент** — основное наполнение урока (текст, видео, изображения, файлы).
- **Порядковый номер** внутри родителя.
- **Родитель** — тренинг или подтренинг.
- **Флаг «Скрыт»** — урок не отображается ученикам (используется для черновиков).
- **Флаг «Стоп-урок»** — см. раздел 8.3.
- **Дата открытия по расписанию** — см. раздел 8.

### 6.2. Типы уроков

Для MVP достаточно одного универсального типа урока с составным контентом (текст + медиа + файлы). В дальнейшем могут быть добавлены специализированные типы (вебинар, тест и т.д.), но это за рамками данного документа.

### 6.3. Задания в уроке

Урок может содержать задание, требующее ответа от ученика. В рамках MVP:

- ученик может отправить ответ на задание (текст, файл или комбинацию);
- ответ сохраняется в системе и привязан к паре «ученик ↔ урок»;
- формальная модель статусов ответа (проверка, принятие, отклонение) в MVP не предусмотрена — ответы просто сохраняются.

Логика работы с проверкой ответов будет определена в последующих версиях документа.

### 6.4. Статусы прохождения урока учеником

Для каждой пары «ученик ↔ урок» система хранит статус:

- **Недоступен** — урок закрыт правилами доступа или расписания.
- **Доступен** — урок можно открыть, но ученик ещё не заходил.
- **Начат** — ученик открыл урок.
- **Выполнен** — урок пройден (критерий выполнения: вход в урок или отправка ответа на задание, если задание есть).

---

## 7. Доступы

### 7.1. Модель доступа: по группам

Доступ к тренингам и подтренингам выдаётся через механизм **групп пользователей**.

- Группа — это именованный сегмент пользователей.
- Пользователь может состоять одновременно в нескольких группах.
- Тренинг/подтренинг привязан к одной или нескольким группам.
- Пользователь имеет доступ к тренингу, если он состоит хотя бы в одной группе, привязанной к тренингу.

### 7.2. Управление членством в группе

Членство в группе может изменяться следующими способами:

- **Ручное добавление/удаление** через интерфейс управления группой.
- **Массовое добавление** (например, импорт списка пользователей).
- **Программное добавление** через внутренние события системы (покупка, регистрация на событие и т.д.) — реализуется за пределами модуля «Тренинги», но модуль должен корректно реагировать на изменение состава группы.

### 7.3. Последствия изменения членства

- При **добавлении** пользователя в группу — он немедленно получает доступ ко всем тренингам, привязанным к этой группе.
- При **удалении** пользователя из группы — доступ к тренингу сохраняется, если пользователь остаётся в хотя бы одной другой группе, привязанной к тренингу. Иначе — доступ отзывается.
- Прогресс ученика (статусы прохождения уроков, отправленные ответы) **сохраняется** при отзыве доступа. Если доступ будет выдан повторно, ученик продолжит с того места, где остановился.

### 7.4. Доступы к подтренингам

Подтренинг может иметь один из двух режимов доступа:

1. **Наследовать от родителя** — подтренинг доступен всем, у кого есть доступ к родительскому тренингу/подтренингу. Это значение по умолчанию.
2. **Собственные группы** — подтренинг доступен только пользователям из указанных групп (независимо от доступа к родителю).

Второй режим решает типовой кейс: на тренинг куплены два тарифа (обычный и премиум), премиум-тариф открывает дополнительный подтренинг с бонусами. Ученики обоих тарифов состоят в группе «Основная», но только премиум-ученики — в группе «Премиум», привязанной к бонусному подтренингу.

При наследовании доступа режим применяется транзитивно вниз по иерархии: если подтренинг A наследует доступ от родителя, а подтренинг A.1 (вложенный в A) — тоже наследует, то A.1 будет доступен всем, у кого есть доступ к корневому тренингу.

### 7.5. Видимость тренинга без доступа

Для тренингов, к которым у пользователя нет доступа, настраивается поведение отображения:

- **Не отображать** — тренинг скрыт полностью.
- **Отображать как заблокированный** — тренинг виден в общем списке с пометкой «нет доступа» (например, для мотивации к покупке доступа).

Настройка задаётся на уровне тренинга.

---

## 8. Управление прохождением уроков

Существует два независимых механизма ограничения доступа к урокам: **расписание** и **стоп-уроки**. Механизмы могут работать одновременно — в этом случае урок доступен ученику только при выполнении обоих условий.

### 8.1. Расписание: общие положения

Расписание определяет, когда урок становится доступным ученику с точки зрения времени. Расписание настраивается на уровне тренинга или подтренинга. Если контейнер содержит вложенные подтренинги, расписание для уроков внутри каждого подтренинга настраивается отдельно.

Система поддерживает два типа расписания:

1. **Общее** — одинаковые даты открытия для всех учеников.
2. **Индивидуальное** — даты рассчитываются для каждого ученика от момента получения доступа.

Тип расписания выбирается на уровне тренинга/подтренинга и распространяется на все его уроки.

### 8.2. Типы расписания

#### 8.2.1. Общее расписание

Для каждого урока задаётся конкретная дата и время открытия (абсолютная метка времени). Все ученики получают доступ к уроку одновременно в указанный момент.

**Кейс:** живой поток курса, стартующий 1 сентября для всех участников.

#### 8.2.2. Индивидуальное расписание

Для каждого урока задаётся задержка в днях (или часах) относительно точки отсчёта. Точкой отсчёта служит момент получения учеником доступа к тренингу.

- Урок 1 — задержка 0 дней (доступен сразу).
- Урок 2 — задержка 2 дня.
- Урок 3 — задержка 5 дней.

Если ученик получил доступ 10 марта, то урок 3 откроется для него 15 марта.

**Кейс:** самостоятельное прохождение курса в индивидуальном темпе.

### 8.3. Стоп-уроки

Стоп-урок — это урок, блокирующий переход к последующим урокам до его выполнения.

#### 8.3.1. Правила блокировки

Для стоп-урока задаётся критерий «выполнения»:

- **Вход в урок** — достаточно открыть урок.
- **Отправка ответа** — ученик должен отправить ответ на задание.

Пока критерий не выполнен, все уроки, расположенные после стоп-урока в порядке следования, недоступны ученику.

#### 8.3.2. Область действия

- Стоп-уроки работают в пределах одного контейнера (тренинга или подтренинга).
- Стоп-урок в подтренинге не блокирует уроки родительского тренинга и наоборот.

### 8.4. Совместное действие расписания и стоп-уроков

Когда одновременно настроены и расписание, и стоп-уроки — урок доступен ученику только если выполнены **оба** условия:

- дата открытия по расписанию наступила **И**
- все предшествующие стоп-уроки выполнены.

Более строгое ограничение имеет приоритет. Например, если по расписанию урок должен открыться, но предыдущий стоп-урок не пройден — урок остаётся закрытым.

### 8.5. Видимость закрытых уроков

Для каждого урока настраивается поведение отображения, когда он ещё недоступен:

- **Скрыт из списка** — ученик не видит урок до момента открытия.
- **Виден, но заблокирован** — ученик видит название урока и дату открытия, но не может в него войти.

Настройка задаётся на уровне урока и работает одинаково для ограничений по расписанию и по стоп-урокам.

---

## 9. Пользовательские сценарии

### 9.1. Прохождение тренинга (ученик)

1. Ученик видит тренинг в своём списке.
2. Открывает первый доступный урок.
3. Изучает контент, отправляет ответ на задание (если есть).
4. Переходит к следующему уроку — либо сразу, либо после открытия по расписанию, либо после прохождения стоп-урока.

### 9.2. Выдача доступа

1. Пользователь добавляется в группу (вручную, массово или программно).
2. Пользователь немедленно получает доступ ко всем тренингам группы.

### 9.3. Отзыв доступа

1. Пользователь удаляется из группы.
2. Если пользователь не состоит в других группах с доступом к тренингу — доступ автоматически отзывается.
3. Прогресс ученика сохраняется в системе.

---

## 10. Требования к логированию

Для аудита и отладки модуль должен логировать следующие события:

- создание, изменение, удаление, архивация тренинга/подтренинга/урока;
- изменение состава группы доступа;
- выдача и отзыв доступа пользователю (с указанием причины: ручная / через группу);
- открытие урока учеником;
- отправка ответа на задание.

Детализация формата логов — за рамками данного документа.

---

## 11. Вне области этой документации

Следующие аспекты намеренно **не включены** в текущую версию:

- роли пользователей, кроме ученика (администратор, преподаватель и т.д.) — будут определены позже;
- условия завершения тренинга — будут определены позже;
- статусы ответов на задания (проверка, принятие, отклонение) — будут определены позже;
- продукты, предложения, оплаты и связка доступов с покупками;
- процессы и автоворонки;
- геймификация (баллы, рейтинги, достижения);
- сертификаты;
- уроки типа «вебинар», «тест», «опрос» (только универсальный урок);
- тест-драйв, промо-уроки;
- сквозные чаты в уроках;
- потоки обучения (когорты со стартом по датам).

Эти возможности могут быть добавлены в следующих итерациях.

---

## 12. Открытые вопросы

Вопросы, требующие обсуждения с продуктовой командой перед началом разработки:

1. Какие именно форматы контента поддерживаются в уроке в MVP (только текст + видео? файлы? встраиваемые блоки?).
2. Какие уведомления отправляются ученику при открытии урока по расписанию?
3. Как ведёт себя система при смещении расписания в тренинге, где уже есть активные ученики?
4. Нужна ли возможность ручной индивидуальной выдачи доступа к отдельному уроку (в обход групп)?
5. Есть ли ограничение на максимальную глубину вложенности подтренингов (для защиты от UI/performance проблем)?

# Доступы

_Страница в разработке._

# Коммуникация

_Страница в разработке._

# Платежи

_Страница в разработке._

# Автоматизации

_Страница в разработке._

# Аналитика

_Страница в разработке._

# Страницы

_Страница в разработке._