AdminCurator

Аналитика

Детальная аналитика по отдельному тесту: количество попыток, доля завершения, средний/максимальный/минимальный балл, доля сдавших, разбивка по вопросам и гистограмма распределения баллов. Требует право `view_analytics`.

GET/api/v1/t/analytics/curators

Аналитика работы кураторов

AdminCurator JWT

Возвращает единую месячную норму 80% для тестов, заданий и пробных ЕНТ, детализацию по ученикам и прежние показатели активности для совместимости. Куратор всегда получает только собственную строку, даже если умеет управлять всеми группами; администратор видит сравнение всех кураторов или выбирает одного через curator_id. Доступно всем кураторам без отдельного флага view_analytics.

from и to включительны; веб выбирает полный календарный месяц в часовом поясе устройства и отправляет последнюю микросекунду месяца как to. monthly_students в каждой строке куратора содержит student_id, first_name, last_name, email, all / quiz / assignment / exam и activities. Каждый из четырёх итогов содержит total (работы с дедлайном в периоде), completed (сданы до to), rate_pct и quota_met (≥80%; оба null при total=0). Одна работа имеет вес 1 и учитывается один раз. В activities: activity_id, kind (quiz / assignment / exam), title, deadline, completed_at, completed_by_period_end, status (completed_on_time / completed_late / not_completed / pending). Поздняя сдача внутри месяца учитывается; сдача после to — нет. Достаточно одной успешной попытки теста; пробный ЕНТ требует проходной балл, если он задан, и корректный итоговый результат. Задание учитывается по submitted_at после отправки (submitted / accepted / rejected / legacy graded); черновики не учитываются. Проверка задания не является условием его сдачи. Сдача может быть раньше from; попытки из будущего не учитываются. Материалы без дедлайна исключены. Пробные ЕНТ учитываются через привязку к урокам (exam_ref) и расписание курса/модуля/урока; course_id / module_id / lesson_id применяются ко всем трём типам. В строке куратора и общей summary поле monthly_summary содержит all / quiz / assignment / exam, каждый с met / not_met / no_tests; no_tests означает отсутствие работ соответствующего типа. Общая summary считает учеников без дублей. Карточки и сравнение в вебе показывают met / (met + not_met), а учеников без работ — отдельно. Незавершённый месяц помечается как предварительный. Используются текущие назначения, доступ к курсам и расписание: их изменение может повлиять на прошлые месяцы. При отсутствии новых monthly-полей веб показывает недоступность расчёта. Старые quiz_students, quiz_period_summary, quiz_deadline_summary и поля активности сохранены: quiz_students содержит прежний расчёт по дедлайнам и месячный расчёт только тестов, assignments_on_time отражает отправку хотя бы одного задания до его дедлайна. Legacy exam_applicable=false при фильтре по контенту отключает только прежний показатель объёма ЕНТ; к monthly_students и monthly_summary он не применяется.

Query-параметры

ПараметрТипОписание
fromопц.RFC3339Начало периода. По умолчанию — начало текущего месяца.
toопц.RFC3339Конец периода. По умолчанию — текущий момент.
curator_idопц.uuidОдин куратор; учитывается только для администратора.
group_idопц.uuidОставить закреплённых учеников выбранной группы.
course_idопц.uuidКурс для тестов, заданий и привязанных пробных ЕНТ.
module_idопц.uuidМодуль для тестов, заданий и привязанных пробных ЕНТ.
lesson_idопц.uuidУрок для тестов, заданий и привязанных пробных ЕНТ.

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

cURL
curl "https://api.edumentor.kz/api/v1/t/analytics/curators?from=2026-08-01T00%3A00%3A00Z&to=2026-08-31T23%3A59%3A59Z" \
  -H "Authorization: Bearer <token>" \
  -H "X-Tenant-Subdomain: acme"

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

200 OK · application/json
{
  "success": true,
  "data": {
    "from": "2026-08-01T00:00:00Z",
    "to": "2026-08-31T23:59:59Z",
    "exam_applicable": true,
    "summary": {
      "curators": 4,
      "students": 82,
      "quiz_deadline_summary": { "met": 50, "not_met": 22, "no_tests": 10 },
      "quiz_period_summary": { "met": 60, "not_met": 12, "no_tests": 10 },
      "monthly_summary": {
        "all": { "met": 55, "not_met": 22, "no_tests": 5 },
        "quiz": { "met": 60, "not_met": 12, "no_tests": 10 },
        "assignment": { "met": 58, "not_met": 16, "no_tests": 8 },
        "exam": { "met": 48, "not_met": 22, "no_tests": 12 }
      },
      "active": { "students": 71, "rate_pct": 86.59 },
      "assignments_on_time": { "students": 64, "rate_pct": 78.05 },
      "quizzes_completed": { "students": 68, "rate_pct": 82.93 },
      "exams_completed": { "students": 51, "rate_pct": 62.2 }
    },
    "curators": []
  }
}

Ошибки

КодerrorКогда
400invalid_fromНачало периода не соответствует RFC3339.
400invalid_toКонец периода не соответствует RFC3339.
400invalid_date_rangeНачало периода позже конца.
403forbiddenСтраница недоступна ученику.
GET/api/v1/t/quizzes/:id/analytics

Аналитика по тесту

AdminCurator JWT право: view_analytics

Возвращает агрегаты по одному тесту. Доступ закрыт правом view_analytics: админ и суперадмин проходят неявно, куратору нужен флаг can_view_analytics, студент получает 403. По умолчанию в подсчёт попадают только попытки студентов; флаг include_admin_attempts=true добавляет попытки админов/кураторов (например, для отладки). Кураторы без права manage_groups видят агрегаты только по своим студентам.

Поля avg_score_pct, max_score_pct, min_score_pct и pass_rate могут быть null: первые три — когда нет отправленных попыток, pass_rate — когда у теста не задан проходной балл. Гистограмма score_distribution содержит 10 корзин (0 — диапазон [0%,10%), 9 — диапазон [90%,100%]).

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

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

Query-параметры

ПараметрТипОписание
include_admin_attemptsопц.booleanВключить ли попытки админов/кураторов в агрегаты. По умолчанию false (только студенты).Пример: false

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

cURL
curl "https://api.edumentor.kz/api/v1/t/quizzes/8f3b1c2a-1d2e-4a5b-9c6d-7e8f9a0b1c2d/analytics?include_admin_attempts=false" \
  -H "Authorization: Bearer <token>" \
  -H "X-Tenant-Subdomain: acme"

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

200 OK · application/json
{
  "success": true,
  "data": {
    "quiz_id": "8f3b1c2a-1d2e-4a5b-9c6d-7e8f9a0b1c2d",
    "attempt_count": 42,
    "submitted_count": 38,
    "completion_rate": 90.48,
    "avg_score_pct": 73.5,
    "max_score_pct": 100.0,
    "min_score_pct": 20.0,
    "pass_rate": 81.58,
    "per_question": [
      {
        "question_id": "1a2b3c4d-...",
        "answered": 38,
        "correct": 31,
        "success_rate": 0.8158
      }
    ],
    "score_distribution": [
      { "bucket": 0, "count": 1 },
      { "bucket": 9, "count": 12 }
    ]
  }
}

Ошибки

КодerrorКогда
400invalid_id_formatИдентификатор теста не является валидным UUID.
400invalid_include_admin_attemptsЗначение include_admin_attempts не является булевым.
401unauthorizedТокен отсутствует, истёк или недействителен.
403forbiddenУ пользователя нет права view_analytics (например, студент или куратор без флага).
404quiz_not_foundТест не найден в текущей школе.