# Доступы

Самая частая причина обращения в поддержку у любой школы — «заплатил, а урок
не открылся». Эта страница про то, как устроено открытие уроков, чтобы такие
случаи разбирались за минуту, а не за день.

## Доступ — это запись, а не флажок

У человека либо есть запись о доступе к курсу, либо её нет. У записи есть
состояние, срок и **дата старта**, и от неё считается всё расписание курса.

Три вещи, которые легко перепутать:

| Что | Что это |
|---|---|
| **Заказ** | Намерение и деньги. Заказ может быть оплачен, а доступ выдан позже |
| **Покупка** | Факт выдачи доступа: что именно и на какой срок |
| **Доступ** | Запись о том, что человек учится на этом курсе, с датой старта и состоянием |

Заказ может быть оплачен, а доступ отозван. Доступ может быть выдан руками
без всякого заказа — при переносе учеников из другой платформы это обычный путь.
Это разные вещи, и в API это разные ресурсы.

## Дата старта — не дата оплаты

**Всё расписание курса считается от даты старта доступа.** Не от даты покупки,
не от даты выдачи.

Зачем так: ученик, купивший курс в отпуске, начинает учиться через две недели,
и открытие уроков должно считаться от его начала, а не от момента списания денег.
А в потоке дата старта общая — она берётся из потока, и своя дата при этом
не принимается.

Это первое, что стоит проверить, когда «у одного открылось, у другого нет».

## Четыре правила открытия урока

У каждого урока своё правило. Их четыре, и они не смешиваются.

**Сразу.** Урок доступен, как только у человека появился доступ к курсу.

**К моменту.** Указывается дата и время. Урок откроется у всех одновременно —
это правило потока.

**Через N дней от старта.** У каждого ученика **своя дата**: отсчёт идёт от его
собственного старта. Двадцать человек, начавших в разные дни, получат урок
в разные дни.

**По условию.** Урок откроется, когда выполнятся условия. **Даты при этом нет
вообще**, и ученику мы так и говорим — без обещания срока, которого не знаем.

Дата и смещение взаимоисключающи: либо дата потока, либо «через N дней от старта».
Задать оба нельзя.

### Перед сохранением видно, у кого во сколько это откроется

Правило «к моменту» задаётся в одном часовом поясе, а ученики живут в разных.
Поэтому до сохранения показывается, **кто увидит открытие в какое время** — по
зонам живых учеников этого курса, а не по списку зон мира. Отдельной строкой
сказано, сколько человек попадёт на ночь, и отдельной — сколько учеников не указали
пояс и считаются живущими по часам школы.

Для правила «через N дней» показывается разброс: у нынешних учеников это
с такого-то по такое-то число.

## Условия соединяются только через «и»

Условий может быть до двадцати, и соединяются они **только через «и»**. Ни «или»,
ни вложенности, ни отрицания.

Это сознательное ограничение, а не недоделка. Автор настраивает правило один раз
и через год не помнит, что настроил; ошибка означает, что заплативший ученик
не попал в урок, а узнаём мы об этом из письма в поддержку. Правило, которое
читается однозначно, здесь дороже гибкости.

В **сегментах** «или» есть — там другая цена ошибки: неверная рассылка вместо
потерянного доступа, и число попавших видно до отправки.

Типы условий: завершён конкретный урок, завершён модуль целиком. Условие «завершён
модуль» существует отдельно именно затем, чтобы последовательное прохождение
не приходилось выражать перечислением двадцати уроков.

## Скрытый или видимый замок

У правила есть настройка: показывать закрытый урок в программе или нет.

**Показывать** — ученик видит название урока, замок, причину и, если срок известен,
таймер. Это правильное поведение по умолчанию: человек видит, что курс продолжается.

**Не показывать** — урока в программе нет вовсе, пока он не откроется.

## Продление, заморозка, отзыв

**Продление** сдвигает дату окончания. Прогресс, ответы и сертификаты не трогаются.

**Заморозка** останавливает и доступ, и отсчёт: доступ на месяц, замороженный
на две недели, после разморозки доживёт свой месяц. Нужна для отпусков и болезней.

**Отзыв** закрывает доступ к урокам. И здесь есть правило, которое стоит знать
заранее:

> **Отзыв останавливает создание нового, а не работу созданного.**

Уже выданный сертификат не аннулируется. Уже принятые ответы остаются на месте
и остаются видны куратору. Прогресс сохраняется — если доступ выдадут снова,
ученик продолжит с того места, где остановился, а не с нуля.

Причина та же, что и в других местах продукта: тихая автоматическая отмена создаёт
ложное чувство порядка, а на деле люди откатывают её не разбираясь.

## Почему урок закрыт

Ответ на этот вопрос даёт **тот же движок**, который показывает причину ученику.
Не вторая реализация «для админки» — одна логика, а не две. Иначе в двух местах
она однажды разойдётся, и разбирать придётся не доступ ученика, а расхождение
между экранами.

Причины, которые он различает:

| Причина | Что означает |
|---|---|
| Урок не опубликован | Автор его ещё не выпустил; правила доступа тут ни при чём |
| Нет доступа к курсу | Записи о доступе не существует |
| Доступ отозван | Запись есть, доступ закрыт |
| Доступ заморожен | Приостановлен, отсчёт срока остановлен |
| Срок доступа истёк | Дата окончания прошла |
| Откроется по дате | Правило «к моменту», дата известна и показывается |
| Откроется через N дней | Правило «через N дней от старта», дата считается от старта этого ученика |
| Условие не выполнено | Показывается, **какое именно** условие и что нужно сделать |

Последняя строка — самая полезная: ответ не «закрыто», а «нужно сдать урок такой-то».

## Индивидуальное исключение

Одному человеку можно открыть урок в обход правила. Это отдельное действие,
и оно **записывается**: кто открыл, когда, кому и какой урок.

Метода «показать урок, минуя правило» без следа не существует — ни в интерфейсе,
ни в API. Любое расширение доступа оставляет запись, и это принципиально:
без неё через месяц никто не помнит, почему у одного ученика курс шёл иначе.
