← Files WeStudyARCHIVED FILE

skills/westudy/references/course-schedules.md

13.1 KB · Nov 2, 2026 · 13:16 UTC

↓ Download file

# Розклади курсу

## Команди та вибір режиму

| Команда | Призначення |
| --- | --- |
| get_course_schedules | Усі календарні плани курсу, включно з минулими; revision списку та кожного плану. |
| create_course_schedule | Створити календарний план з назвою та датами навчання/реєстрації. |
| update_course_schedule | Змінити лише передані налаштування одного плану. |
| get_course_material_schedule | Прочитати межі доступу всіх матеріалів: дні або один календарний план. |
| update_course_material_schedule | Змінити межі вибраних матеріалів одним пакетом. |

Режим змінюється через `update_course` → `settings.accessType`:

- `all` — розклади матеріалів не обмежують доступ; інші правила доступу залишаються.
- `days_after_register` — дні від реєстрації студента саме на цьому курсі.
- `scheduled` — конкретні дати календарного плану, призначеного студенту.

Тривалість доступу `accessDays` курсу/тарифу — інше правило; не використовуй її замість
дня відкриття чи закриття матеріалу. Платність і тарифи також незалежні від розкладу.
Перемикання режиму зберігає всі плани та розмітку інших режимів. Новий курс можна
створити з `all` або `days_after_register`; календарний режим увімкни після створення
принаймні одного плану. Створення плану саме по собі режим не перемикає.

Працюй з однозначно вибраним курсом за [courses.md](courses.md). UUID курсу, плану
та матеріалів бери з відповідей інструментів. За кількох придатних планів уточни ціль;
не вибирай перший, найближчий або минулий автоматично. Читання не повертає студентів.

## Дні після реєстрації

1. Прочитай `get_course`; якщо потрібно, зміни `accessType` на `days_after_register`
   з актуальною revision курсу. Явний запит такого розкладу дозволяє це перемикання;
   назви його в повідомленні про дію. За неоднозначного наміру уточни режим.
2. Прочитай `get_course_material_schedule` з `mode="days"`, без `scheduleUuid`
   (або з null). Візьми UUID цілей і revision саме цієї відповіді.
3. Передай тільки запитані межі в `items`, наприклад:
   `{elementUuid: "…", dayStart: 7, dayEnd: 30}`.

`dayStart=7` відкриває матеріал через сім днів від часу реєстрації на курсі, а не від
створення облікового запису й не від моменту зміни налаштувань. `dayEnd=30` — закриття
на 30-й день від тієї ж реєстрації, а не 30 днів після відкриття. Не змішуй ці значення
з порядковим номером уроку або календарними датами. Якщо потрібна тривалість після
відкриття, обчисли кінцевий день із цих умов. Межі — цілі числа 0–32767 або null.

`dayStart=0/null` означає відсутність затримки відкриття, `dayEnd=0/null` — відсутність
розкладної межі закриття. Пропущене поле зберігає його попереднє значення. Коли обидві
межі відсутні, очищається лише розмітка розкладу цього матеріалу. Не обіцяй необмеженого
доступу: публікація, тарифи, батьківський розділ та інші правила продовжують діяти.

## Календарні плани

`get_course_schedules {courseUuid}` повертає `items`, `revision`, `accessType`,
`timezone` та `schoolTimezone`. Для створення потрібна revision списку; для редагування
— revision вибраного item. Плани можуть бути ще не активними або вже минулими.

`create_course_schedule` приймає `requestId`, `courseUuid`, `expectedRevision` та settings:

- `name` — непорожня назва плану;
- `educationStart`, `educationEnd` — обов’язкові початок і кінець навчання;
- `enrollmentStart`, `enrollmentEnd` — період реєстрації; пропущені значення при створенні
  дорівнюють відповідним датам навчання;
- `enrollmentOpen` — чи відкрита реєстрація в цей план; типовий false. Не вмикай її,
  якщо користувач цього не доручив або відкриття набору не є частиною його запиту.

Не вигадуй дати навчання: якщо їх бракує, запитай. Уточни час і часовий пояс, якщо вони
не визначені користувачем і налаштуваннями школи. `update_course_schedule` додатково
потребує `scheduleUuid` і передає лише запитані settings. Пропущені реєстраційні дати
зберігаються навіть при зміні дат навчання. Для цих чотирьох дат плану null не допускається;
якщо старий план має відсутню реєстраційну межу, при зміні відповідної дати навчання
треба явно задати цю реєстраційну дату. Не заповнюй її мовчки без наміру користувача.

Після створення/вибору плану ввімкни `settings.accessType="scheduled"`, якщо це входить
у доручення, і перечитай розклад матеріалів із `mode="calendar"` та `scheduleUuid`.
Передай `items`, наприклад `{elementUuid: "…", dateStart: "2026-11-01T09:30:00+02:00"}`.
`dateStart=null`/`dateEnd=null` очищає відповідну межу лише цього плану; пропуск зберігає її.
Дати загального плану не розставляють автоматично дати всіх уроків і не означають, що
матеріал відкриється з початком навчання. За запиту розмітити уроки зроби окремий пакет.

Студент використовує план, призначений йому на платформі. Ці команди не зараховують
студентів і не перепризначають їм плани. При перемиканні діючого курсу поясни це,
якщо користувач очікує автоматичного переведення на новий потік. Після зміни не заявляй,
що кожен студент отримав потрібний доступ: призначення й студентський перегляд
перевіряються в кабінеті WeStudy.

## Час і часові пояси

Дати передавай у ISO 8601 із секундами та явним зсувом: `2026-11-01T09:30:00+02:00`
або `2026-11-01T07:30:00Z`. Дата без часу/зсуву не приймається. Для користувацьких дат
орієнтуйся на `schoolTimezone`; якщо він відсутній/некоректний і користувач не визначив
пояс, уточни його. Враховуй літній/зимовий час на кожну конкретну дату; не застосовуй
сьогоднішній зсув до всього року. `timezone` описує час зберігання платформи. Відповідь
нормалізована до нього й містить зсув; показуй користувачеві дату в погодженому поясі.

Наприклад, повернуті `07:30:00+00:00` та передані `09:30:00+02:00` означають той самий
момент. Не повідомляй про перенесення початку лише через відмінність запису зсуву.
Кінець не може передувати початку; перевірка враховує як нові, так і збережені межі.

## Пакети, розділи та редагування

- До 200 явних матеріалів в `items`. Для більшого набору розбий на пакети та між
  записами використовуй нову revision результату/читання; не запускай паралельно
  кілька змін на стару revision.
- `includeDescendants=false` типово змінює лише передані UUID. True застосовує саме
  передані межі рекурсивно до вкладених матеріалів вибраного module. Пропущені межі
  кожного нащадка зберігаються окремо. Великий модуль може охопити понад 200 нащадків.
- Розмітка підтримує наявні матеріали всіх типів, зокрема test/certificate, хоча їхнє
  створення/редагування контенту ще не реалізоване. Не змінюй тип чи дизайн матеріалу.
- Не додавай батьківські розділи автоматично. Власний розклад батьківського module
  може впливати на доступ до уроку; враховуй його при поясненні результату.
- Не передавай суперечливі зміни одного поля для module та його нащадка в одному
  рекурсивному пакеті. Для різних дат використай явні UUID або окремі послідовні записи.
- Читати можна неактивний режим (`isActive=false`); записувати матеріальні межі можна
  тільки після ввімкнення відповідного accessType. Після перемикання режиму перечитай
  матеріальний розклад і візьми нову revision. Інакше отримаєш помилку або CONFLICT.

Зміни режиму, плану й розкладу діють одразу, також для опублікованих матеріалів.
Це не чернетка дизайну і не вимагає publish_course/publish_course_element. Перед
записом назви курс, план/режим, цілі й запитану зміну; не вимагай повторного погодження
чіткого доручення. Права — courses:read/courses:write, публікація лишається окремою.

При CONFLICT перечитай потрібний стан і застосуй намір до актуальних меж. Не просто
підставляй нову revision під старий повний об’єкт. Школу визначає підключення; чужі
курси, плани, матеріали й шаблони не підтримуються. Видалення планів/матеріалів/файлів
не доступне. Очищення меж не є видаленням матеріалу або призначення студента.

Кожен запис має свій requestId. Для QUEUED/RUNNING читай get_execution; при UNKNOWN
або таймауті збережи requestId/executionId і не повторюй запис автоматично. Після
SUCCEEDED повідом фактичний режим/план і змінені матеріали. Не стверджуй, що змінено
весь курс, коли пакет містив лише вибрані UUID; за потреби перевір читанням.

SHA-256: de8b14656c7fdc099dafc3c16245f0679f666dcd9eae90bb2d3fb0364f741a48