AdminStudent

Геймификация и рейтинг

Система баллов и рейтинг (лидерборд). Студенты и кураторы видят рейтинг с проекцией по роли; админы настраивают правила начисления баллов (значения по умолчанию и переопределения для конкретных объектов) и могут вручную корректировать баллы. Баллы передаются строкой (NUMERIC(10,2)) во избежание потери точности.

GET/api/v1/t/rating

Рейтинг (лидерборд)

TenantStudent JWT

Возвращает таблицу лидеров с проекцией по роли вызывающего: студент видит свой ранг и баллы, имена других студентов анонимизируются (имя + инициал фамилии); куратор без права manage_groups видит только своих студентов и без полей caller_*; админ/суперадмин видят полную таблицу с полными именами.

Параметр limit по умолчанию 10 и жёстко ограничен сверху значением 100. source_types — список через запятую из значений lesson, module, course, quiz, assignment, exam, manual. Поля caller_rank/caller_points отсутствуют для куратора; time_window присутствует только при заданных from/to.

Query-параметры

ПараметрТипОписание
group_idопц.uuidФильтр рейтинга по группе (когорте).
source_typesопц.stringСписок типов источников баллов через запятую: lesson, module, course, quiz, assignment, exam, manual.Пример: quiz,exam
fromопц.stringНачало временного окна (включительно).Пример: 2026-05-01T00:00:00Z
toопц.stringКонец временного окна.Пример: 2026-05-28T00:00:00Z
limitопц.integerРазмер выборки (по умолчанию 10, максимум 100).Пример: 10

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

cURL
curl "https://api.edumentor.kz/api/v1/t/rating?limit=10&source_types=quiz,exam" \
  -H "Authorization: Bearer <token>" \
  -H "X-Tenant-Subdomain: acme"

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

200 OK · application/json
{
  "success": true,
  "data": {
    "entries": [
      { "rank": 1, "student_id": "1a2b3c4d-...", "display_name": "Айгерим Н.", "points": "420.00" },
      { "rank": 2, "student_id": "2b3c4d5e-...", "display_name": "Данияр К.", "points": "390.50" }
    ],
    "total_students": 84,
    "caller_rank": 7,
    "caller_points": "215.00",
    "time_window": null
  }
}

Ошибки

КодerrorКогда
400invalid group_idПараметр group_id не является валидным UUID.
401unauthorizedТокен отсутствует, истёк или недействителен.
403PAYMENT_REQUIREDБиллинг школы приостановлен или истёк.
404group_not_foundУказанная группа не найдена в текущей школе.
GET/api/v1/t/admin/gamification/rules

Список правил начисления

Admin JWT

Возвращает все активные правила школы — значения по умолчанию и переопределения — в плоском виде, сгруппированные по типу источника. Доступно только админу/суперадмину.

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

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

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

200 OK · application/json
{
  "success": true,
  "data": {
    "rules": [
      {
        "default_id": "8f3b1c2a-...",
        "tenant_id": "0a1b2c3d-...",
        "source_type": "quiz",
        "enabled": true,
        "points": "10.00",
        "calc_mode": "fixed",
        "threshold_source": null,
        "threshold_value": null,
        "award_only_if_passed": true,
        "repeat_behavior": "overwrite_if_higher"
      }
    ]
  }
}

Ошибки

КодerrorКогда
401unauthorizedТокен отсутствует, истёк или недействителен.
403forbiddenДоступно только для роли admin/superadmin.
PUT/api/v1/t/admin/gamification/rules/defaults/:source_type

Правило по умолчанию для типа источника

Admin JWT

Создаёт или обновляет правило по умолчанию для типа источника баллов. Поля частичные: null/отсутствие поля означает «не менять». Доступно только админу/суперадмину.

Для source_type = assignment действуют ограничения: при calc_mode = above_threshold обязателен threshold_value, а threshold_source = passing_score для задания недопустим.

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

ПараметрТипОписание
source_typeобяз.stringТип источника баллов. Один из: lesson, module, course, quiz, assignment, exam, manual.Пример: quiz

Тело запроса

ПараметрТипОписание
enabledопц.booleanВключено ли начисление.
pointsопц.stringКоличество баллов (строка-десятичная дробь NUMERIC(10,2)).Пример: 10.00
calc_modeопц.stringРежим расчёта: fixed, raw или above_threshold.Пример: fixed
threshold_sourceопц.stringИсточник порога: passing_score или rule_specified.
threshold_valueопц.stringЗначение порога (строка-десятичная дробь).
award_only_if_passedопц.booleanНачислять баллы только при успешной сдаче.
repeat_behaviorопц.stringПоведение при повторе: ignore, award_each, overwrite, overwrite_if_higher.

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

cURL
curl -X PUT https://api.edumentor.kz/api/v1/t/admin/gamification/rules/defaults/quiz \
  -H "Authorization: Bearer <token>" \
  -H "X-Tenant-Subdomain: acme" \
  -H "Content-Type: application/json" \
  -d '{
    "enabled": true,
    "points": "10.00",
    "calc_mode": "fixed",
    "award_only_if_passed": true,
    "repeat_behavior": "overwrite_if_higher"
  }'

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

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

Ошибки

КодerrorКогда
400invalid_request_bodyТело запроса не прошло валидацию (например, недопустимый calc_mode).
400invalid_calc_modeНедопустимый режим расчёта баллов.
400assignment_no_passing_scoreДля задания нельзя использовать threshold_source = passing_score.
400assignment_passed_requires_thresholdДля задания при above_threshold обязателен threshold_value.
401unauthorizedТокен отсутствует, истёк или недействителен.
403forbiddenДоступно только для роли admin/superadmin.
PUT/api/v1/t/admin/gamification/rules/overrides/:source_type/:target_id

Переопределение правила для объекта

Admin JWT

Создаёт или обновляет переопределение правила для конкретного объекта (например, конкретного теста или курса). Незаданные поля наследуются от правила по умолчанию. Доступно только админу/суперадмину.

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

ПараметрТипОписание
source_typeобяз.stringТип источника: lesson, module, course, quiz, assignment, exam, manual.Пример: quiz
target_idобяз.uuidИдентификатор объекта, для которого задаётся переопределение.

Тело запроса

ПараметрТипОписание
enabledопц.booleanВключено ли начисление.
pointsопц.stringКоличество баллов (строка-десятичная дробь).Пример: 25.00
calc_modeопц.stringРежим расчёта: fixed, raw или above_threshold.
threshold_sourceопц.stringИсточник порога: passing_score или rule_specified.
threshold_valueопц.stringЗначение порога (строка-десятичная дробь).
award_only_if_passedопц.booleanНачислять баллы только при успешной сдаче.
repeat_behaviorопц.stringПоведение при повторе: ignore, award_each, overwrite, overwrite_if_higher.

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

cURL
curl -X PUT https://api.edumentor.kz/api/v1/t/admin/gamification/rules/overrides/quiz/8f3b1c2a-1d2e-4a5b-9c6d-7e8f9a0b1c2d \
  -H "Authorization: Bearer <token>" \
  -H "X-Tenant-Subdomain: acme" \
  -H "Content-Type: application/json" \
  -d '{ "enabled": true, "points": "25.00" }'

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

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

Ошибки

КодerrorКогда
400invalid_target_idtarget_id не является валидным UUID.
400invalid_request_bodyТело запроса не прошло валидацию.
400invalid_calc_modeНедопустимый режим расчёта баллов.
400assignment_no_passing_scoreДля задания нельзя использовать threshold_source = passing_score.
400assignment_passed_requires_thresholdДля задания при above_threshold обязателен threshold_value.
401unauthorizedТокен отсутствует, истёк или недействителен.
403forbiddenДоступно только для роли admin/superadmin.
DELETE/api/v1/t/admin/gamification/rules/overrides/:source_type/:target_id

Удалить переопределение правила

Admin JWT

Мягко удаляет переопределение для конкретного объекта, возвращая объект к правилу по умолчанию школы. Доступно только админу/суперадмину.

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

ПараметрТипОписание
source_typeобяз.stringТип источника: lesson, module, course, quiz, assignment, exam, manual.Пример: quiz
target_idобяз.uuidИдентификатор объекта переопределения.

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

cURL
curl -X DELETE https://api.edumentor.kz/api/v1/t/admin/gamification/rules/overrides/quiz/8f3b1c2a-1d2e-4a5b-9c6d-7e8f9a0b1c2d \
  -H "Authorization: Bearer <token>" \
  -H "X-Tenant-Subdomain: acme"

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

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

Ошибки

КодerrorКогда
400invalid_target_idtarget_id не является валидным UUID.
401unauthorizedТокен отсутствует, истёк или недействителен.
403forbiddenДоступно только для роли admin/superadmin.
404rule_not_foundПереопределение для данного объекта не найдено.
POST/api/v1/t/admin/rating/adjustments

Ручная корректировка баллов

Admin JWT

Вручную начисляет или списывает баллы студенту. points — знаковая числовая строка (отрицательное значение = списание). reason обязателен для аудита. Опциональный idempotency_key предотвращает двойную запись при повторе. Доступно только админу/суперадмину; записывается событие аудита.

Тело запроса

ПараметрТипОписание
student_idобяз.uuidИдентификатор студента.
pointsобяз.stringЗнаковая величина в баллах; отрицательное значение — списание.Пример: -15.00
reasonобяз.stringПричина корректировки (1–2000 символов) — попадает в журнал аудита.
idempotency_keyопц.stringКлюч идемпотентности для защиты от двойной записи при повторе.

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

cURL
curl -X POST https://api.edumentor.kz/api/v1/t/admin/rating/adjustments \
  -H "Authorization: Bearer <token>" \
  -H "X-Tenant-Subdomain: acme" \
  -H "Content-Type: application/json" \
  -d '{
    "student_id": "1a2b3c4d-1d2e-4a5b-9c6d-7e8f9a0b1c2d",
    "points": "25.00",
    "reason": "Активность на вебинаре"
  }'

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

200 OK · application/json
{
  "success": true,
  "data": { "event_id": "9f8e7d6c-1d2e-4a5b-9c6d-7e8f9a0b1c2d" }
}

Ошибки

КодerrorКогда
400invalid_request_bodyТело запроса не прошло валидацию (например, пустой reason).
401unauthorizedТокен отсутствует, истёк или недействителен.
403forbiddenДоступно только для роли admin/superadmin.
404student_not_foundСтудент не найден в текущей школе.
GET/api/v1/t/admin/rating/students/:id/summary

Сводка рейтинга студента

AdminCuratorStudent JWT

Возвращает сводку по баллам студента: ранг и сумму баллов в школе, общее число студентов и ранги по группам. Несмотря на префикс /admin/, эндпоинт доступен также куратору (в рамках его студентов) и студенту (только свои данные). Любой запрос вне области видимости, к чужому студенту, к другой школе или к несуществующему студенту даёт одинаковый ответ 404 student_not_found (защита от утечки фактом существования).

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

ПараметрТипОписание
idобяз.uuidИдентификатор студента.

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

cURL
curl https://api.edumentor.kz/api/v1/t/admin/rating/students/1a2b3c4d-1d2e-4a5b-9c6d-7e8f9a0b1c2d/summary \
  -H "Authorization: Bearer <token>" \
  -H "X-Tenant-Subdomain: acme"

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

200 OK · application/json
{
  "success": true,
  "data": {
    "school_rank": 7,
    "school_total": "215.00",
    "school_total_students": 84,
    "group_ranks": [
      {
        "group_id": "3c4d5e6f-...",
        "group_name": "Поток-2026",
        "rank": 3,
        "total_points": "215.00",
        "total_students": 24
      }
    ]
  }
}

Ошибки

КодerrorКогда
400invalid_idИдентификатор студента не является валидным UUID.
401unauthorizedТокен отсутствует, истёк или недействителен.
403PAYMENT_REQUIREDБиллинг школы приостановлен или истёк.
404student_not_foundСтудент не найден либо недоступен текущему пользователю (единый отпечаток ответа).
GET/api/v1/t/admin/rating/students/:id/events

История начислений студента

AdminCuratorStudent JWT

Возвращает ленту событий начисления/списания баллов студента с пагинацией и фильтрами. Те же правила видимости и тот же отпечаток 404, что и у сводки. Поддерживает фильтры по типу источника, временному окну, знаку и поиску по причине.

sign — один из positive, negative, all. limit по умолчанию 50 и ограничен сверху 100; offset по умолчанию 0. from/to — RFC3339, полуоткрытый интервал.

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

ПараметрТипОписание
idобяз.uuidИдентификатор студента.

Query-параметры

ПараметрТипОписание
source_typeопц.stringСписок типов источников через запятую: lesson, module, course, quiz, assignment, exam, manual.Пример: quiz,manual
fromопц.stringНачало временного окна (RFC3339, включительно).Пример: 2026-05-01T00:00:00Z
toопц.stringКонец временного окна (RFC3339, исключительно).
signопц.stringФильтр по знаку баллов: positive, negative или all.Пример: all
reason_searchопц.stringПоиск по подстроке в причине (ILIKE).
limitопц.integerРазмер страницы (по умолчанию 50, максимум 100).Пример: 50
offsetопц.integerСмещение для пагинации (по умолчанию 0).Пример: 0

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

cURL
curl "https://api.edumentor.kz/api/v1/t/admin/rating/students/1a2b3c4d-1d2e-4a5b-9c6d-7e8f9a0b1c2d/events?sign=all&limit=50" \
  -H "Authorization: Bearer <token>" \
  -H "X-Tenant-Subdomain: acme"

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

200 OK · application/json
{
  "success": true,
  "data": {
    "events": [
      {
        "id": "9f8e7d6c-...",
        "awarded_at": "2026-05-20T14:00:00Z",
        "source_type": "quiz",
        "target_id": "8f3b1c2a-...",
        "target_label": "Тест: Основы Go",
        "points": "10.00",
        "rule_id": "0a1b2c3d-...",
        "reason": null,
        "actor_user_id": null,
        "actor_display_name": null
      }
    ],
    "total": 23,
    "limit": 50,
    "offset": 0
  }
}

Ошибки

КодerrorКогда
400invalid_idИдентификатор студента не является валидным UUID.
400invalid_timeПараметр from/to не соответствует формату RFC3339.
400invalid_signЗначение sign не входит в набор positive/negative/all.
401unauthorizedТокен отсутствует, истёк или недействителен.
403PAYMENT_REQUIREDБиллинг школы приостановлен или истёк.
404student_not_foundСтудент не найден либо недоступен текущему пользователю (единый отпечаток ответа).