Траектории обучения
Последовательные траектории курсов: CRUD, публикация/снятие с публикации, набор и порядок курсов, роестр студентов траектории и студенческий просмотр своих траекторий с разблокировкой. Все эндпоинты живут под /api/v1/t/* и требуют JWT + заголовок X-Tenant-Subdomain.
- GET
/api/v1/t/learning-pathsСписок траекторий - GET
/api/v1/t/learning-paths/:idПолучить траекторию - GET
/api/v1/t/learning-paths/:id/studentsСтуденты траектории - POST
/api/v1/t/learning-pathsСоздать траекторию - PATCH
/api/v1/t/learning-paths/:idИзменить траекторию - DELETE
/api/v1/t/learning-paths/:idУдалить траекторию - POST
/api/v1/t/learning-paths/:id/publishОпубликовать траекторию - POST
/api/v1/t/learning-paths/:id/unpublishСнять с публикации - PATCH
/api/v1/t/learning-paths/:id/coursesЗаменить набор курсов - PATCH
/api/v1/t/learning-paths/:id/reorder-coursesИзменить порядок курсов - GET
/api/v1/t/students/me/pathsМои траектории
/api/v1/t/learning-pathsСписок траекторий
Постраничный список траекторий обучения школы. Доступен любому авторизованному пользователю школы. Конверт: { paths, total, limit, offset }.
limit 1..200 (по умолчанию 50), offset >= 0. status фильтруется по перечислению draft | published; иное значение даёт 400.
Query-параметры
| Параметр | Тип | Описание |
|---|---|---|
qопц. | string | Поиск по названию (подстрока). |
statusопц. | string | Фильтр по статусу: draft | published. |
limitопц. | integer | Размер страницы (1..200). По умолчанию 50.Пример: 50 |
offsetопц. | integer | Смещение (>=0). По умолчанию 0.Пример: 0 |
Пример запроса
curl "https://api.edumentor.kz/api/v1/t/learning-paths?status=published&limit=50&offset=0" \
-H "Authorization: Bearer <token>" \
-H "X-Tenant-Subdomain: acme"Пример ответа
{
"success": true,
"data": {
"paths": [
{
"id": "p1p1...",
"title": "Путь Go-разработчика",
"description": "От основ до продакшена",
"status": "published",
"created_by": "c1c1...",
"course_count": 4,
"created_at": "2026-05-28T09:00:00Z",
"updated_at": "2026-05-28T09:00:00Z"
}
],
"total": 1,
"limit": 50,
"offset": 0
}
}Ошибки
| Код | error | Когда |
|---|---|---|
| 400 | invalid_params | Некорректные limit/offset. |
| 400 | invalid_status_filter | Недопустимое значение status (не draft/published). |
| 401 | unauthorized | Школа не определена или токен недействителен. |
/api/v1/t/learning-paths/:idПолучить траекторию
Возвращает траекторию с упорядоченным списком курсов (позиция + ID + название). Кросс-тенантный ID отдаётся как 404.
Параметры пути
| Параметр | Тип | Описание |
|---|---|---|
idобяз. | uuid | ID траектории. |
Пример запроса
curl https://api.edumentor.kz/api/v1/t/learning-paths/p1p1... \
-H "Authorization: Bearer <token>" \
-H "X-Tenant-Subdomain: acme"Пример ответа
{
"success": true,
"data": {
"id": "p1p1...",
"title": "Путь Go-разработчика",
"description": "От основ до продакшена",
"status": "published",
"created_by": "c1c1...",
"course_count": 2,
"created_at": "2026-05-28T09:00:00Z",
"updated_at": "2026-05-28T09:00:00Z",
"courses": [
{ "course_id": "2b1a...", "position": 0, "title": "Основы Go" },
{ "course_id": "3c1a...", "position": 1, "title": "Go в продакшене" }
]
}
}Ошибки
| Код | error | Когда |
|---|---|---|
| 400 | invalid_id_format | ID в пути не является UUID. |
| 401 | unauthorized | Школа не определена или токен недействителен. |
| 404 | path_not_found | Траектория отсутствует или принадлежит другой школе. |
/api/v1/t/learning-paths/:id/studentsСтуденты траектории
Кураторско-административный реестр студентов, проходящих траекторию, с агрегатами прогресса. Непривилегированный куратор видит только своих студентов. Конверт: { students, total, limit, offset }.
limit 1..200 (по умолчанию 50), offset >= 0.
Параметры пути
| Параметр | Тип | Описание |
|---|---|---|
idобяз. | uuid | ID траектории. |
Query-параметры
| Параметр | Тип | Описание |
|---|---|---|
limitопц. | integer | Размер страницы (1..200). По умолчанию 50.Пример: 50 |
offsetопц. | integer | Смещение (>=0). По умолчанию 0.Пример: 0 |
Пример запроса
curl "https://api.edumentor.kz/api/v1/t/learning-paths/p1p1.../students?limit=50&offset=0" \
-H "Authorization: Bearer <token>" \
-H "X-Tenant-Subdomain: acme"Пример ответа
{
"success": true,
"data": {
"students": [
{
"student_id": "8f3b...",
"email": "student@acme.kz",
"first_name": "Айгерим",
"last_name": "Нурлан",
"is_active": true,
"courses_unlocked": 2,
"courses_completed": 1,
"first_unlocked_at": "2026-05-28T10:00:00Z",
"last_activity_at": "2026-05-28T11:00:00Z"
}
],
"total": 1,
"limit": 50,
"offset": 0
}
}Ошибки
| Код | error | Когда |
|---|---|---|
| 400 | invalid_id_format | ID в пути не является UUID. |
| 400 | invalid_params | Некорректные limit/offset. |
| 401 | unauthorized | Школа не определена или токен недействителен. |
| 403 | permission_denied | Нет права manage_courses. |
| 404 | path_not_found | Траектория отсутствует или принадлежит другой школе. |
/api/v1/t/learning-pathsСоздать траекторию
Создаёт новую траекторию обучения. Статус всегда стартует как draft; публикация — отдельный переход. 201 Created.
Тело запроса
| Параметр | Тип | Описание |
|---|---|---|
titleобяз. | string | Название траектории (1..255). |
descriptionопц. | string | Описание (до 4000 символов). |
Пример запроса
curl -X POST https://api.edumentor.kz/api/v1/t/learning-paths \
-H "Authorization: Bearer <token>" \
-H "X-Tenant-Subdomain: acme" \
-H "Content-Type: application/json" \
-d '{ "title": "Путь Go-разработчика", "description": "От основ до продакшена" }'Пример ответа
{
"success": true,
"data": {
"id": "p1p1...",
"title": "Путь Go-разработчика",
"description": "От основ до продакшена",
"status": "draft",
"created_by": "c1c1...",
"course_count": 0,
"created_at": "2026-05-28T09:00:00Z",
"updated_at": "2026-05-28T09:00:00Z"
}
}Ошибки
| Код | error | Когда |
|---|---|---|
| 400 | invalid_request_body | Некорректное тело запроса (нарушены binding-правила). |
| 401 | unauthorized | Школа не определена или токен недействителен. |
| 403 | permission_denied | Нет права manage_courses. |
/api/v1/t/learning-paths/:idИзменить траекторию
Частичное обновление названия/описания. Статус через этот эндпоинт не меняется — для публикации используйте отдельные переходы.
Параметры пути
| Параметр | Тип | Описание |
|---|---|---|
idобяз. | uuid | ID траектории. |
Тело запроса
| Параметр | Тип | Описание |
|---|---|---|
titleопц. | string | Новое название (1..255). |
descriptionопц. | string | Новое описание (до 4000). |
Пример запроса
curl -X PATCH https://api.edumentor.kz/api/v1/t/learning-paths/p1p1... \
-H "Authorization: Bearer <token>" \
-H "X-Tenant-Subdomain: acme" \
-H "Content-Type: application/json" \
-d '{ "title": "Путь Go-разработчика (v2)" }'Пример ответа
{
"success": true,
"data": {
"id": "p1p1...",
"title": "Путь Go-разработчика (v2)",
"description": "От основ до продакшена",
"status": "draft",
"created_by": "c1c1...",
"course_count": 0,
"created_at": "2026-05-28T09:00:00Z",
"updated_at": "2026-05-28T12:00:00Z"
}
}Ошибки
| Код | error | Когда |
|---|---|---|
| 400 | invalid_id_format | ID в пути не является UUID. |
| 400 | invalid_request_body | Некорректное тело запроса. |
| 401 | unauthorized | Школа не определена или токен недействителен. |
| 403 | permission_denied | Нет права manage_courses. |
| 404 | path_not_found | Траектория отсутствует или принадлежит другой школе. |
/api/v1/t/learning-paths/:idУдалить траекторию
Мягко удаляет траекторию обучения. Возвращает { deleted: true }.
Параметры пути
| Параметр | Тип | Описание |
|---|---|---|
idобяз. | uuid | ID траектории. |
Пример запроса
curl -X DELETE https://api.edumentor.kz/api/v1/t/learning-paths/p1p1... \
-H "Authorization: Bearer <token>" \
-H "X-Tenant-Subdomain: acme"Пример ответа
{
"success": true,
"data": { "deleted": true }
}Ошибки
| Код | error | Когда |
|---|---|---|
| 400 | invalid_id_format | ID в пути не является UUID. |
| 401 | unauthorized | Школа не определена или токен недействителен. |
| 403 | permission_denied | Нет права manage_courses. |
| 404 | path_not_found | Траектория отсутствует или принадлежит другой школе. |
/api/v1/t/learning-paths/:id/publishОпубликовать траекторию
Переводит траекторию в статус published. Идемпотентно для уже опубликованной. Пустая траектория (без курсов) отклоняется с 409 path_publish_empty.
Параметры пути
| Параметр | Тип | Описание |
|---|---|---|
idобяз. | uuid | ID траектории. |
Пример запроса
curl -X POST https://api.edumentor.kz/api/v1/t/learning-paths/p1p1.../publish \
-H "Authorization: Bearer <token>" \
-H "X-Tenant-Subdomain: acme"Пример ответа
{
"success": true,
"data": { "published": true }
}Ошибки
| Код | error | Когда |
|---|---|---|
| 400 | invalid_id_format | ID в пути не является UUID. |
| 401 | unauthorized | Школа не определена или токен недействителен. |
| 403 | permission_denied | Нет права manage_courses. |
| 404 | path_not_found | Траектория отсутствует или принадлежит другой школе. |
| 409 | path_publish_empty | Нельзя опубликовать траекторию без курсов. |
/api/v1/t/learning-paths/:id/unpublishСнять с публикации
Возвращает траекторию в статус draft. Идемпотентно для уже черновой траектории.
Параметры пути
| Параметр | Тип | Описание |
|---|---|---|
idобяз. | uuid | ID траектории. |
Пример запроса
curl -X POST https://api.edumentor.kz/api/v1/t/learning-paths/p1p1.../unpublish \
-H "Authorization: Bearer <token>" \
-H "X-Tenant-Subdomain: acme"Пример ответа
{
"success": true,
"data": { "unpublished": true }
}Ошибки
| Код | error | Когда |
|---|---|---|
| 400 | invalid_id_format | ID в пути не является UUID. |
| 401 | unauthorized | Школа не определена или токен недействителен. |
| 403 | permission_denied | Нет права manage_courses. |
| 404 | path_not_found | Траектория отсутствует или принадлежит другой школе. |
/api/v1/t/learning-paths/:id/coursesЗаменить набор курсов
REPLACE-семантика: переданный массив course_ids полностью заменяет текущий набор курсов траектории. Пустой массив очищает траекторию. Кросс-тенантный course_id даёт 400 course_not_in_tenant.
Параметры пути
| Параметр | Тип | Описание |
|---|---|---|
idобяз. | uuid | ID траектории. |
Тело запроса
| Параметр | Тип | Описание |
|---|---|---|
course_idsобяз. | string[] | Массив UUID курсов (до 200; допускается пустой). |
Пример запроса
curl -X PATCH https://api.edumentor.kz/api/v1/t/learning-paths/p1p1.../courses \
-H "Authorization: Bearer <token>" \
-H "X-Tenant-Subdomain: acme" \
-H "Content-Type: application/json" \
-d '{ "course_ids": ["2b1a...", "3c1a..."] }'Пример ответа
{
"success": true,
"data": { "replaced": true, "count": 2 }
}Ошибки
| Код | error | Когда |
|---|---|---|
| 400 | invalid_id_format | ID в пути не является UUID. |
| 400 | invalid_request_body | Некорректное тело запроса. |
| 400 | course_not_in_tenant | Один из курсов принадлежит другой школе. |
| 401 | unauthorized | Школа не определена или токен недействителен. |
| 403 | permission_denied | Нет права manage_courses. |
| 404 | path_not_found | Траектория отсутствует или принадлежит другой школе. |
| 409 | course_already_in_path | Курс уже присутствует в траектории (дубликат в наборе). |
/api/v1/t/learning-paths/:id/reorder-coursesИзменить порядок курсов
Переупорядочивает курсы траектории. Переданный набор course_ids должен в точности совпадать с текущим набором курсов траектории (полная перестановка).
Параметры пути
| Параметр | Тип | Описание |
|---|---|---|
idобяз. | uuid | ID траектории. |
Тело запроса
| Параметр | Тип | Описание |
|---|---|---|
course_idsобяз. | string[] | Полный упорядоченный список UUID курсов (1..200). |
Пример запроса
curl -X PATCH https://api.edumentor.kz/api/v1/t/learning-paths/p1p1.../reorder-courses \
-H "Authorization: Bearer <token>" \
-H "X-Tenant-Subdomain: acme" \
-H "Content-Type: application/json" \
-d '{ "course_ids": ["3c1a...", "2b1a..."] }'Пример ответа
{
"success": true,
"data": { "reordered": true }
}Ошибки
| Код | error | Когда |
|---|---|---|
| 400 | invalid_id_format | ID в пути не является UUID. |
| 400 | invalid_request_body | Некорректное тело запроса. |
| 401 | unauthorized | Школа не определена или токен недействителен. |
| 403 | permission_denied | Нет права manage_courses. |
| 404 | path_not_found | Траектория отсутствует или принадлежит другой школе. |
| 409 | reorder_duplicate | В переданном наборе есть дублирующиеся ID курсов. |
| 409 | reorder_incomplete | Переданный набор не совпадает с текущим набором курсов траектории. |
/api/v1/t/students/me/pathsМои траектории
Студенческий просмотр своих траекторий с упорядоченным списком курсов и аннотациями locked | unlocked | completed. Студент берётся из JWT — параметр не передаётся. Заблокированные курсы показывают только название.
Пример запроса
curl https://api.edumentor.kz/api/v1/t/students/me/paths \
-H "Authorization: Bearer <token>" \
-H "X-Tenant-Subdomain: acme"Пример ответа
{
"success": true,
"data": {
"paths": [
{
"path_id": "p1p1...",
"title": "Путь Go-разработчика",
"description": "От основ до продакшена",
"courses": [
{
"course_id": "2b1a...",
"position": 0,
"title": "Основы Go",
"status": "completed",
"unlocked_at": "2026-05-28T10:00:00Z",
"completed_at": "2026-05-28T11:00:00Z"
},
{
"course_id": "3c1a...",
"position": 1,
"title": "Go в продакшене",
"status": "unlocked",
"unlocked_at": "2026-05-28T11:00:00Z"
}
]
}
]
}
}Ошибки
| Код | error | Когда |
|---|---|---|
| 401 | unauthorized | Школа не определена или токен недействителен. |