TenantAdminCuratorStudent

Траектории обучения

Последовательные траектории курсов: CRUD, публикация/снятие с публикации, набор и порядок курсов, роестр студентов траектории и студенческий просмотр своих траекторий с разблокировкой. Все эндпоинты живут под /api/v1/t/* и требуют JWT + заголовок X-Tenant-Subdomain.

GET/api/v1/t/learning-paths

Список траекторий

Tenant JWT

Постраничный список траекторий обучения школы. Доступен любому авторизованному пользователю школы. Конверт: { 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
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"

Пример ответа

200 OK · application/json
{
  "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Когда
400invalid_paramsНекорректные limit/offset.
400invalid_status_filterНедопустимое значение status (не draft/published).
401unauthorizedШкола не определена или токен недействителен.
GET/api/v1/t/learning-paths/:id

Получить траекторию

Tenant JWT

Возвращает траекторию с упорядоченным списком курсов (позиция + ID + название). Кросс-тенантный ID отдаётся как 404.

Параметры пути

ПараметрТипОписание
idобяз.uuidID траектории.

Пример запроса

cURL
curl https://api.edumentor.kz/api/v1/t/learning-paths/p1p1... \
  -H "Authorization: Bearer <token>" \
  -H "X-Tenant-Subdomain: acme"

Пример ответа

200 OK · application/json
{
  "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Когда
400invalid_id_formatID в пути не является UUID.
401unauthorizedШкола не определена или токен недействителен.
404path_not_foundТраектория отсутствует или принадлежит другой школе.
GET/api/v1/t/learning-paths/:id/students

Студенты траектории

AdminCurator JWT право: manage_courses

Кураторско-административный реестр студентов, проходящих траекторию, с агрегатами прогресса. Непривилегированный куратор видит только своих студентов. Конверт: { students, total, limit, offset }.

limit 1..200 (по умолчанию 50), offset >= 0.

Параметры пути

ПараметрТипОписание
idобяз.uuidID траектории.

Query-параметры

ПараметрТипОписание
limitопц.integerРазмер страницы (1..200). По умолчанию 50.Пример: 50
offsetопц.integerСмещение (>=0). По умолчанию 0.Пример: 0

Пример запроса

cURL
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"

Пример ответа

200 OK · application/json
{
  "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Когда
400invalid_id_formatID в пути не является UUID.
400invalid_paramsНекорректные limit/offset.
401unauthorizedШкола не определена или токен недействителен.
403permission_deniedНет права manage_courses.
404path_not_foundТраектория отсутствует или принадлежит другой школе.
POST/api/v1/t/learning-paths

Создать траекторию

AdminCurator JWT право: manage_courses

Создаёт новую траекторию обучения. Статус всегда стартует как draft; публикация — отдельный переход. 201 Created.

Тело запроса

ПараметрТипОписание
titleобяз.stringНазвание траектории (1..255).
descriptionопц.stringОписание (до 4000 символов).

Пример запроса

cURL
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": "От основ до продакшена" }'

Пример ответа

200 OK · application/json
{
  "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Когда
400invalid_request_bodyНекорректное тело запроса (нарушены binding-правила).
401unauthorizedШкола не определена или токен недействителен.
403permission_deniedНет права manage_courses.
PATCH/api/v1/t/learning-paths/:id

Изменить траекторию

AdminCurator JWT право: manage_courses

Частичное обновление названия/описания. Статус через этот эндпоинт не меняется — для публикации используйте отдельные переходы.

Параметры пути

ПараметрТипОписание
idобяз.uuidID траектории.

Тело запроса

ПараметрТипОписание
titleопц.stringНовое название (1..255).
descriptionопц.stringНовое описание (до 4000).

Пример запроса

cURL
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)" }'

Пример ответа

200 OK · application/json
{
  "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Когда
400invalid_id_formatID в пути не является UUID.
400invalid_request_bodyНекорректное тело запроса.
401unauthorizedШкола не определена или токен недействителен.
403permission_deniedНет права manage_courses.
404path_not_foundТраектория отсутствует или принадлежит другой школе.
DELETE/api/v1/t/learning-paths/:id

Удалить траекторию

AdminCurator JWT право: manage_courses

Мягко удаляет траекторию обучения. Возвращает { deleted: true }.

Параметры пути

ПараметрТипОписание
idобяз.uuidID траектории.

Пример запроса

cURL
curl -X DELETE https://api.edumentor.kz/api/v1/t/learning-paths/p1p1... \
  -H "Authorization: Bearer <token>" \
  -H "X-Tenant-Subdomain: acme"

Пример ответа

200 OK · application/json
{
  "success": true,
  "data": { "deleted": true }
}

Ошибки

КодerrorКогда
400invalid_id_formatID в пути не является UUID.
401unauthorizedШкола не определена или токен недействителен.
403permission_deniedНет права manage_courses.
404path_not_foundТраектория отсутствует или принадлежит другой школе.
POST/api/v1/t/learning-paths/:id/publish

Опубликовать траекторию

AdminCurator JWT право: manage_courses

Переводит траекторию в статус published. Идемпотентно для уже опубликованной. Пустая траектория (без курсов) отклоняется с 409 path_publish_empty.

Параметры пути

ПараметрТипОписание
idобяз.uuidID траектории.

Пример запроса

cURL
curl -X POST https://api.edumentor.kz/api/v1/t/learning-paths/p1p1.../publish \
  -H "Authorization: Bearer <token>" \
  -H "X-Tenant-Subdomain: acme"

Пример ответа

200 OK · application/json
{
  "success": true,
  "data": { "published": true }
}

Ошибки

КодerrorКогда
400invalid_id_formatID в пути не является UUID.
401unauthorizedШкола не определена или токен недействителен.
403permission_deniedНет права manage_courses.
404path_not_foundТраектория отсутствует или принадлежит другой школе.
409path_publish_emptyНельзя опубликовать траекторию без курсов.
POST/api/v1/t/learning-paths/:id/unpublish

Снять с публикации

AdminCurator JWT право: manage_courses

Возвращает траекторию в статус draft. Идемпотентно для уже черновой траектории.

Параметры пути

ПараметрТипОписание
idобяз.uuidID траектории.

Пример запроса

cURL
curl -X POST https://api.edumentor.kz/api/v1/t/learning-paths/p1p1.../unpublish \
  -H "Authorization: Bearer <token>" \
  -H "X-Tenant-Subdomain: acme"

Пример ответа

200 OK · application/json
{
  "success": true,
  "data": { "unpublished": true }
}

Ошибки

КодerrorКогда
400invalid_id_formatID в пути не является UUID.
401unauthorizedШкола не определена или токен недействителен.
403permission_deniedНет права manage_courses.
404path_not_foundТраектория отсутствует или принадлежит другой школе.
PATCH/api/v1/t/learning-paths/:id/courses

Заменить набор курсов

AdminCurator JWT право: manage_courses

REPLACE-семантика: переданный массив course_ids полностью заменяет текущий набор курсов траектории. Пустой массив очищает траекторию. Кросс-тенантный course_id даёт 400 course_not_in_tenant.

Параметры пути

ПараметрТипОписание
idобяз.uuidID траектории.

Тело запроса

ПараметрТипОписание
course_idsобяз.string[]Массив UUID курсов (до 200; допускается пустой).

Пример запроса

cURL
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..."] }'

Пример ответа

200 OK · application/json
{
  "success": true,
  "data": { "replaced": true, "count": 2 }
}

Ошибки

КодerrorКогда
400invalid_id_formatID в пути не является UUID.
400invalid_request_bodyНекорректное тело запроса.
400course_not_in_tenantОдин из курсов принадлежит другой школе.
401unauthorizedШкола не определена или токен недействителен.
403permission_deniedНет права manage_courses.
404path_not_foundТраектория отсутствует или принадлежит другой школе.
409course_already_in_pathКурс уже присутствует в траектории (дубликат в наборе).
PATCH/api/v1/t/learning-paths/:id/reorder-courses

Изменить порядок курсов

AdminCurator JWT право: manage_courses

Переупорядочивает курсы траектории. Переданный набор course_ids должен в точности совпадать с текущим набором курсов траектории (полная перестановка).

Параметры пути

ПараметрТипОписание
idобяз.uuidID траектории.

Тело запроса

ПараметрТипОписание
course_idsобяз.string[]Полный упорядоченный список UUID курсов (1..200).

Пример запроса

cURL
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..."] }'

Пример ответа

200 OK · application/json
{
  "success": true,
  "data": { "reordered": true }
}

Ошибки

КодerrorКогда
400invalid_id_formatID в пути не является UUID.
400invalid_request_bodyНекорректное тело запроса.
401unauthorizedШкола не определена или токен недействителен.
403permission_deniedНет права manage_courses.
404path_not_foundТраектория отсутствует или принадлежит другой школе.
409reorder_duplicateВ переданном наборе есть дублирующиеся ID курсов.
409reorder_incompleteПереданный набор не совпадает с текущим набором курсов траектории.
GET/api/v1/t/students/me/paths

Мои траектории

Student JWT

Студенческий просмотр своих траекторий с упорядоченным списком курсов и аннотациями locked | unlocked | completed. Студент берётся из JWT — параметр не передаётся. Заблокированные курсы показывают только название.

Пример запроса

cURL
curl https://api.edumentor.kz/api/v1/t/students/me/paths \
  -H "Authorization: Bearer <token>" \
  -H "X-Tenant-Subdomain: acme"

Пример ответа

200 OK · application/json
{
  "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Когда
401unauthorizedШкола не определена или токен недействителен.