Жизненный цикл работ по заданиям

Состояния работы студента (черновик → отправлено → принято/не принято), попытки и пересдачи, продвижение по курсу при отправке и модель проверки «Принят/Не принят».

Задание (assignment) — самостоятельная сущность уровня тенанта; урок ссылается на него блоком контента типа assignment_ref. Работа студента (submission) проходит через простой конечный автомат, а проверка преподавателя — это бинарное решение «Принят» / «Не принят».

Состояния работы

СтатусЗначениеКто переводит
draftЧерновик — студент прикрепляет файлыстудент
submittedОтправлено на проверкустудент (Отправить)
acceptedПринято — успешная попыткапреподаватель (Принят)
rejectedНе принято — нужна пересдача (с комментарием)преподаватель (Не принят)
Статус graded выведен из оборота
Раньше существовал статус graded (оценено баллом). Сейчас проверка бинарная: accepted / rejected. Балл (score) опционален и сопровождает решение. Старые строки graded читаются как accepted.

Попытки (attempts)

Каждая пересдача — это отдельная строка submission со своим 1-based номером attempt. Текущая попытка — с наибольшим номером. Одновременно может существовать только одна незавершённая (draft или submitted) попытка. Полная история (включая прошлые попытки с их комментариями, баллами и файлами) доступна на GET /api/v1/t/assignments/:id/submissions/history (newest-first).

Пересдача

После решения «Не принят» студент нажимает «Пересдать»: POST /api/v1/t/assignments/:id/submissions создаёт НОВУЮ попытку-черновик (attempt += 1). Отклонённая попытка сохраняется как история — она не удаляется и не перезаписывается.

Продвижение по курсу — при отправке

Блок завершается на submit, а не на проверке
Блок assignment_ref считается завершённым, как только студент ОТПРАВИЛ работу (submitted). Проверка преподавателя асинхронна и не блокирует прохождение курса. Решение «Не принят» НЕ откатывает завершение блока — оно лишь открывает пересдачу и показывает комментарий.

Модель проверки (review)

Преподаватель/куратор (право manage_students) выносит решение одним запросом. Поле decision обязательно; score и feedback — опциональны. На каждое решение (и accepted, и rejected) студенту отправляется уведомление.

POST /api/v1/t/submissions/:id/review
curl -X POST https://api.edumentor.kz/api/v1/t/submissions/<id>/review \
  -H "Authorization: Bearer <token>" \
  -H "X-Tenant-Subdomain: acme" \
  -H "Content-Type: application/json" \
  -d '{ "decision": "accepted", "score": "85", "feedback": "<p>Отличная работа</p>" }'

Возврат на доработку: POST /api/v1/t/submissions/:id/reopen переводит accepted | rejected → submitted для повторной проверки, сохраняя балл и комментарий; завершение блока при этом не меняется.