← Files WeStudyARCHIVED FILE

skills/westudy/references/course-materials.md

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

↓ Download file

# Структура й базові матеріали курсу

## Команди та межі

| Команда | Призначення |
| --- | --- |
| get_course_structure | Усі матеріали курсу: type, name, parentUuid, sortOrder, isPublished, editable; revision структури. Без студентських даних. |
| get_course_element | Точна мовна чернетка page, опублікований publishedPage, settings, поточний курсовий generalConfig, revision і structureRevision. |
| create_course_element | Створити неопублікований module, lesson або task. |
| update_course_element | Змінити лише передані settings та/або зберегти native page у чернетку. |
| move_course_element | Перемістити матеріал разом із вкладеністю в module/корінь і визначити порядок. |
| publish_course_element | Опублікувати один матеріал вибраною мовою, обробити його форми. |
| unpublish_course_element | Зняти один матеріал із публікації для всіх мов, зберегти дизайн і файли. |
| prepare_course_element_file | Додати приватному готовому файлу COURSE_ELEMENT scope; для відео отримати об'єкт Video. |

Працюй лише з курсами нової версії. Створення/редагування test, certificate, webinar,
scorm та інших типів — наступні етапи.
Розклад наявних матеріалів усіх типів змінюй окремими командами за
[course-schedules.md](course-schedules.md): дні після реєстрації або дати одного плану,
без зміни типу, дизайну чи публікації.
Тарифні прив’язки наявних матеріалів усіх типів змінюй окремими командами за
[course-tariffs.md](course-tariffs.md), без перезапису їхнього контенту.
Такі матеріали можуть бути у прочитаній структурі: зберігай їх і не перетворюй на lesson.
Студенти, їхній прогрес і зарахування не належать до цих команд. Видалення матеріалів
або файлів недоступне. Підготовка файлового scope ще не додає документ у дизайн.

## Робочий порядок

1. Визнач школу й курс за правилами courses.md; прочитай get_course_structure.
2. Для редагування прочитай get_course_element потрібною lang. Без lang береться
   мова курсу; відсутній переклад не підміняється іншою мовою. Уточни ціль, якщо
   за назвою або змістом підходить кілька матеріалів.
3. Для native дизайну прочитай get_design_reference для course-materials, page,
   потрібних блоків/елементів і профілю fine-editor. Бери generalConfig із матеріалу;
   не застосовуй тему сайта і не генеруй нову тему для уроку.
4. Змінюй тільки запитаний зміст. Збережи невідомі поля, інші блоки, UUID та структуру
   документа. validate_design/preview_design викликай із context="course".
5. Запиши чернетку. Публікуй тільки коли це входить у пряме доручення користувача.
   Чіткий запит створити/редагувати вже дозволяє відповідну дію; не перепитуй його.

Чинну тему можна отримати до створення матеріалу через `get_course_design_config`
з `parent=course` і його courseUuid. Новий порожній матеріал також повертає generalConfig.
Для зміни спільної чи індивідуальної теми прочитай [course-design.md](course-design.md);
створення/редагування матеріалу саме по собі тему не змінює.
Не використовуй довільний вигаданий конфіг лише щоб пройти перевірку.

## Ієрархія та версії

create_course_element: requestId, courseUuid, expectedStructureRevision із останнього
читання структури, type та settings.name. parentUuid — UUID модуля або null/пропуск
для кореня. beforeUuid — наступний матеріал у тій самій папці; null/пропуск додає в кінець.

move_course_element вимагає parentUuid явно (null означає корінь), elementUuid і
expectedStructureRevision. Вкладеність дозволена лише в module. Не можна переносити
в інший курс, у самого себе або свого нащадка. Команда не публікує і не змінює дизайн.
Кожна наступна зміна структури використовує нову revision/structureRevision із результату.
Не надсилай паралельно кілька перестановок на одну стару revision.

update/publish/unpublish/prepare_file вимагають expectedRevision поточного матеріалу.
Ревізія враховує також інші переклади й публікацію. При CONFLICT перечитай і застосуй
намір до нових даних, а не лише заміни revision у старому повному дизайні.
Не застосовуй старе погодження публікації до суттєво зміненого сторонніми людьми змісту.

## Параметри й чернетки

settings: name, description, imageUrl, icon, isRequired, isCalculatedTotal,
evaluationType, evaluationRule, passingScore, maxPoints, xpPoints.
Назва непорожня. Пропущені поля зберігаються; null очищає лише nullable поля.
Назва/параметри діють одразу, у тому числі в опублікованому матеріалі; чернеткою є дизайн.
Не передавай назад увесь прочитаний settings/config як команду оновлення.

page — повний native документ чернетки {blocks, config}, без спрощення. При передачі
page потрібний generalConfig для перевірки; він не зберігається цією командою.
Тип матеріалу, тарифи, розклад, isPublished і студенти через settings не змінюються.

Нові lesson/module мають auto/auto оцінювання; task — teacher/bool. Для teacher
доступні bool, percent, points. Для points потрібний додатний maxPoints, passingScore
не більший за максимум; для percent passingScore не більший за 100.
Не змінюй систему оцінювання існуючого матеріалу, якщо про це не просили.

## Форми завдань

Дивись каталог course-materials. Потрібний form.config.form.isTaskReply=true
(тобто config.form.isTaskReply всередині блока). Типи: text_field, text_area, file_input.
Сам блок має UUID; нові сутності form/question — без uuid та id. Публікація створює
сутності та прив'язку TASK_REPLY. Порожнє ім'я форми доповнюється назвою матеріалу.
Після публікації використовуй повернуту чернетку з виданими ID; при правках зберігай їх.
Не підставляй UUID форми іншого матеріалу і не змінюй тип існуючого питання/форми.
Звичайна form без isTaskReply не є завданням із відповіддю студента.

## Приватне відео

Спочатку створи material UUID. Завантаж/імпортуй відео як visibility="private" і
дочекайся READY; або знайди готовий приватний файл у сховищі цієї школи.
Виклич prepare_course_element_file з kind="video", fileUuid та поточною revision.
Повернутий video встав у config.video елемента конструктора video. Збережи весь
об'єкт, включно з url:null і file.uuid. Потім update_course_element запише чернетку.
Команда додає scope COURSE_ELEMENT=elementUuid, не прибирає попередні scopes і не
змінює видимість файла. Публічний файл автоматично приватним не стає.

Не вставляй приватне відео у rich-text video_block: там поки немає студентського
getFileFunction. kind="file" лише готує scope; приватні документи як окремі файлові
матеріали/вкладення цим етапом ще не реалізовано. Не вигадуй вузол для їх відображення.
Ілюстрації можуть використовувати звичайні публічні картинки. Не роби відео публічним
і не зберігай тимчасовий підписаний URL, щоб обійти доступ.

У загальному viewer можна перевірити дизайн, але не студентські права на приватне
відео і не відправлення відповіді на завдання. Не заповнюй/не відправляй навчальні
форми при візуальній перевірці й не заявляй про перевірений доступ студента без неї.

## Публікація й результат

publish_course_element публікує рівно один матеріал; вкладені уроки модуля самі не
публікуються. Якщо доручено опублікувати розділ із матеріалами, спочатку визнач його
склад і виконай окремі команди для нього та потрібних нащадків. Публікація матеріалу
не активує курс, не публікує лендінг і не розсилає повідомлення. Неопублікований
батьківський модуль може приховувати опублікований урок — врахуй це у звіті.

Права: courses:read для читання, courses:write для створення/редагування/переміщення,
courses:publish для публікації/зняття. Підготовка файла додатково потребує files:read.
При нестачі прав дотримуйся загальних правил підключення; не обходь їх браузером.

Кожна команда — одна операція, один requestId. QUEUED/RUNNING → get_execution.
UNKNOWN/таймаут не означає, що запис не відбувся: збережи requestId/executionId,
не повторюй запис із новим requestId. SUCCEEDED підтверджує тільки виконану дію.
Завжди розрізняй «чернетку збережено», «параметри змінено» й «матеріал опубліковано».

SHA-256: a31e82d4a2d0facbb032ebc641c9e0ce8e88902890723dff2c7c1379095a32e1