Перейти к содержанию

Дода: тесты

Тесты для игры. Методы доступны ролям teacher и school_admin (ведущим): без токена - 401, с другой ролью - 403. Ведущий видит только свои тесты; хозяин теста - profile_id из токена.

Тексты prompt, explanation, content - объект {язык: текст} с ключом ru: {"ru": "2+2?"}.

Объект «Вопрос»

Вопрос в запросе (QuestionCreate):

Параметр Тип Описание
kind string single (по умолчанию), true_false, multi, type_answer, ordering, numeric
prompt* object Текст вопроса
options array Варианты ответа
options[].label* string Метка: A, B, ...
options[].content* object Текст варианта
options[].is_correct boolean Верный ли вариант
options[].order integer Позиция; у ordering верный порядок - это order
accepted_answers array Только type_answer: верные ответы строками, без учёта регистра
numeric object Только numeric: {"value", "tolerance", "min", "max", "step"}
numeric.value* number Верный ответ
numeric.tolerance number Допустимое отклонение, по умолчанию 0
numeric.min, numeric.max, numeric.step number Границы и шаг слайдера
why object Дополнительный вопрос «Почему?»: {"prompt", "options"}, 2-6 вариантов, ровно 1 верный
explanation object Пояснение, показывается после ответа
order integer Позиция в тесте; при создании без неё - в конец, при изменении без неё - не меняется
reading_seconds integer Пауза до появления вариантов; по умолчанию 0
time_limit_seconds integer Время на вопрос; без него - question_seconds игры
image_url string Картинка вопроса, публичный адрес
kind Варианты Верный ответ
single 2-6 Ровно 1 is_correct
true_false Ровно 2 Ровно 1 is_correct
multi 2-6 Хотя бы 1 is_correct
ordering 2-6 Порядок по order
type_answer [] Хотя бы 1 строка в accepted_answers
numeric [] numeric.value с numeric.tolerance
{
  "kind": "single",
  "prompt": {"ru": "1/2 = ?"},
  "options": [
    {"label": "A", "content": {"ru": "2/4"}, "is_correct": true},
    {"label": "B", "content": {"ru": "2/3"}, "is_correct": false}
  ],
  "explanation": {"ru": "2/4 сокращается до 1/2"},
  "time_limit_seconds": 20
}

Вопрос в ответе (Question) - те же поля с серверными id у вопроса, вариантов и вариантов why:

{
  "id": "4f1d...", "order": 0, "kind": "single", "reading_seconds": 0, "time_limit_seconds": 20,
  "image_url": null, "prompt": {"ru": "1/2 = ?"}, "explanation": {"ru": "..."},
  "accepted_answers": null, "numeric": null, "why": null,
  "options": [{"id": "9a2c...", "label": "A", "content": {"ru": "2/4"}, "is_correct": true, "order": 0}]
}

Объект «Тест»

Тест в запросе (TestCreate):

Параметр Тип Описание
title* string Название
subject string Предмет
language_codes array Языки теста; по умолчанию ["ru"]
status string draft (по умолчанию) или published; опубликовать тест без вопросов нельзя
shuffle_options boolean Перемешивать варианты; по умолчанию true
sound_enabled boolean Звук; по умолчанию true
questions array Вопросы (QuestionCreate), сохраняются вместе с тестом

Тест в ответе (Test):

Параметр Тип Описание
id* uuid id теста
title* string Название
subject string Предмет
language_codes* array Языки
status* string draft или published
owner_id uuid Хозяин теста
shuffle_options* boolean Перемешивать варианты
sound_enabled* boolean Звук
created_at* datetime Когда создан
questions* array Вопросы (Question)
{
  "id": "7c3e...", "title": "Дроби", "subject": "Математика", "language_codes": ["ru"], "status": "draft",
  "owner_id": "0b6f...", "shuffle_options": true, "sound_enabled": true, "created_at": "2026-11-10T10:00:00Z",
  "questions": []
}

Создание теста

Создаёт тест, с вопросами или без.

Запрос: POST {DODA_URL}/v1/tests, авторизация - токен ведущего, тело - TestCreate.

{"title": "Дроби", "subject": "Математика", "questions": [{"kind": "true_false", "prompt": {"ru": "3/3 = 1"}, "options": [{"label": "A", "content": {"ru": "Да"}, "is_correct": true}, {"label": "B", "content": {"ru": "Нет"}, "is_correct": false}]}]}

Ответ 201: объект «Тест».

Код ошибки Когда
422 Неверный тест или вопрос

Список тестов

Возвращает тесты ведущего без вопросов, с их числом.

Запрос: GET {DODA_URL}/v1/tests, авторизация - токен ведущего.

Параметр Тип Описание
page, page_size integer В строке запроса: пагинация

Ответ 200: страница с items - тестами без questions, с полями updated_at и question_count.

{"items": [{"id": "7c3e...", "title": "Дроби", "subject": "Математика", "language_codes": ["ru"], "status": "draft", "owner_id": "0b6f...", "shuffle_options": true, "sound_enabled": true, "created_at": "2026-11-10T10:00:00Z", "updated_at": "2026-11-10T10:05:00Z", "question_count": 5}], "page": 1, "page_size": 20, "total": 1}

Тест

Возвращает тест с вопросами.

Запрос: GET {DODA_URL}/v1/tests/{id}, авторизация - токен ведущего.

Ответ 200: объект «Тест».

Код ошибки Когда
404 Теста нет или он чужой

Изменение теста

Заменяет данные теста. С полем questions (в том числе []) заменяются все вопросы; без него меняются только данные теста.

Запрос: PUT {DODA_URL}/v1/tests/{id}, авторизация - токен ведущего, тело - TestCreate.

Ответ 200: объект «Тест».

Код ошибки Когда
404 Теста нет или он чужой
422 Неверный тест или вопрос

Удаление теста

Удаляет тест; история прошлых игр по нему сохраняется.

Запрос: DELETE {DODA_URL}/v1/tests/{id}, авторизация - токен ведущего.

Ответ 204 без тела.

Код ошибки Когда
404 Теста нет или он чужой
409 По тесту сейчас идёт игра

Добавление вопроса

Добавляет вопрос в тест.

Запрос: POST {DODA_URL}/v1/tests/{id}/questions, авторизация - токен ведущего, тело - QuestionCreate.

Ответ 201: вопрос (Question).

Код ошибки Когда
404 Теста нет или он чужой
422 Неверный вопрос

Изменение вопроса

Заменяет вопрос; его id не меняется, варианты создаются заново.

Запрос: PUT {DODA_URL}/v1/tests/{id}/questions/{qid}, авторизация - токен ведущего, тело - QuestionCreate.

Ответ 200: вопрос (Question).

Код ошибки Когда
404 Теста или вопроса нет
422 Неверный вопрос

Удаление вопроса

Удаляет вопрос из теста.

Запрос: DELETE {DODA_URL}/v1/tests/{id}/questions/{qid}, авторизация - токен ведущего.

Ответ 204 без тела.

Код ошибки Когда
404 Теста или вопроса нет

Порядок вопросов

Меняет порядок вопросов одним запросом.

Запрос: POST {DODA_URL}/v1/tests/{id}/questions/reorder, авторизация - токен ведущего.

Параметр Тип Описание
[].id* uuid id вопроса
[].order* integer Новая позиция
[{"id": "4f1d...", "order": 0}, {"id": "8b2e...", "order": 1}]

Ответ 200: объект «Тест» с новым порядком.

Код ошибки Когда
404 Чужой или неизвестный id вопроса

Шаблон Word

Отдаёт пустой шаблон .docx, по которому учитель пишет тест в Word.

Запрос: GET {DODA_URL}/v1/tests/template?lang=ru, авторизация - токен ведущего.

Ответ 200: файл .docx как вложение.

Код ошибки Когда
422 Неподдерживаемый lang

Импорт из Word

Создаёт черновик теста из заполненного шаблона.

Запрос: POST {DODA_URL}/v1/tests/import-document, авторизация - токен ведущего, тело - multipart/form-data.

Параметр Тип Описание
file* file Заполненный шаблон .docx, до 25 МБ
lang string ru; перебивает строку «Язык:» в файле

Ответ 201: объект «Тест» со status: "draft".

Код ошибки Когда
413 Файл больше 25 МБ
422 Документ не разобран; в detail номер вопроса и что исправить
503 В документе есть картинка: картинки из Word выключены

ИИ-генерация теста

Создаёт тест по предмету, классу и теме с помощью ИИ. Пустой черновик теста появляется сразу, ИИ его заполняет; картинок ИИ не добавляет. Генерация асинхронная: статус - методом «Статус генерации» (раздел «ИИ-генерации»).

Запрос: POST {API_URL}/v1/doda-tests, авторизация - токен.

Параметр Тип Описание
subject* string Предмет, 1-128 символов
grade* integer Класс, 1-12
topic* string Тема и название теста, 1-255 символов
question_count integer Сколько вопросов: 1-15, по умолчанию 10
instruction string Пожелания, до 1000 символов
{"subject": "Математика", "grade": 5, "topic": "Дроби", "question_count": 10}

Ответ 202: объект «Генерация», kind: "doda_test", в result.test_id - id черновика теста. Когда генерация completed, тест заполнен: его вернёт метод «Тест». При failed черновик остаётся пустым.