## Обновление API Challenge Service Документ для frontend-разработчика. Описывает НОВЫЕ возможности и требования к клиенту. Содержит два блока изменений: - **Управление видимостью цепочек заданий** (поле `isActive` и новый админский эндпоинт). - **Тестовая проверка решения задания админом** (флаг `isTest` и опциональные `hiddenInstructions` в `/submit`). --- ## 1. Управление видимостью цепочек заданий ### 1.1. Новое поле в модели цепочки **Поле `isActive`** - **Тип**: `boolean` - **По умолчанию**: `true` - **Смысл**: определяет, видна ли цепочка обычным пользователям в пользовательском списке. > В базе: поле уже есть в модели `ChallengeChain`, на фронте его нужно учитывать в админских интерфейсах. --- ### 1.2. Пользовательский список цепочек #### `GET /api/challenge/chains` - **Назначение**: список цепочек для студентов/обычных пользователей. - **Фильтрация на бэке**: возвращаются **только цепочки с `isActive: true`**. - **Доступ**: без специальных ролей. **Гарантии для фронтенда:** - Выключенные / черновые цепочки **никогда** не попадут в этот список. - Можно строить каталог цепочек, не фильтруя по `isActive` на клиенте. Упрощённая структура элемента: ```json { "id": "...", "name": "Основы программирования", "tasks": [ { "id": "...", "title": "...", "description": "..." // Для не-преподавателей поля hiddenInstructions и creator отсутствуют } ], "isActive": true } ``` **Требования к фронтенду:** - Для пользовательских экранов достаточно этого эндпоинта, **дополнительную фильтрацию по активности делать не нужно**. --- ### 1.3. Админский список цепочек #### `GET /api/challenge/chains/admin` - **Назначение**: полный список цепочек (и включённых, и выключенных) для админских/преподавательских экранов. - **Фильтрации по активности нет** — возвращаются **все** цепочки. - **Доступ**: только роли `teacher` или `challenge-author`. - Включает все данные по задачам, в т.ч. `hiddenInstructions`, `creator`. Пример ответа (фрагмент): ```json { "error": null, "data": [ { "id": "...", "name": "Основы программирования", "tasks": [ { "id": "...", "title": "...", "description": "...", "hiddenInstructions": "...", "creator": { "sub": "...", "preferred_username": "teacher1" } } ], "isActive": true, "createdAt": "2023-10-29T12:00:00.000Z", "updatedAt": "2023-10-29T12:00:00.000Z" } ] } ``` **Требования к фронтенду (админский UI):** - Использовать этот эндпоинт для экранов управления цепочками. - Показывать состояние активности (`isActive`) каждой цепочки (badge, тумблер и т.п.). - При ошибке 403 (нет роли `teacher` / `challenge-author`) отображать сообщение об отсутствии доступа и, при необходимости, перенаправлять на пользовательский список. --- ### 1.4. Создание и обновление цепочек с учётом активности #### `POST /api/challenge/chain` **Роли**: `teacher` или `challenge-author`. **Тело запроса:** ```json { "name": "Основы программирования", "taskIds": ["...", "..."], "isActive": true // опционально, по умолчанию true } ``` - Если `isActive` не передан, цепочка создаётся **активной**. **Требования к фронтенду:** - На форме создания цепочки можно: - либо не показывать тумблер активности (все новые будут активными), - либо добавить переключатель «Активна» и передавать `isActive: false` для черновиков. #### `PUT /api/challenge/chain/:chainId` **Роли**: `teacher` или `challenge-author`. **Тело запроса (все поля опциональны):** ```json { "name": "Новое имя", "taskIds": ["..."], "isActive": false } ``` - Если `isActive` передан, его значение меняет активность цепочки. - Если `isActive` не передан, активность не меняется. **Сценарии:** - Включить цепочку: `PUT /api/challenge/chain/:id` с `{ "isActive": true }`. - Выключить цепочку (спрятать из пользовательского списка): `{ "isActive": false }`. - Переименовать / поменять задачи без изменения активности: отправлять только `name` / `taskIds` без поля `isActive`. **Требования к UI:** - На экране «управление цепочками» (данные из `/chains/admin`): - показывать `isActive`; - давать возможность включать/выключать цепочку (тумблер → вызов `PUT /chain/:id` с нужным `isActive`). --- ## 2. Тестовая проверка решения задания (без записи прогресса) Добавлен режим тестовой проверки решения, который позволяет **преподавателю/автору** проверить ответ через LLM **без создания попытки и без постановки в очередь**. ### 2.1. Расширение эндпоинта отправки решения #### `POST /api/challenge/submit` К существующему API добавлены новые опциональные поля в теле запроса: ```json { "userId": "...", "taskId": "...", "result": "...", "isTest": true, // НОВОЕ: флаг тестового режима "hiddenInstructions": "..." // НОВОЕ: опциональные инструкции для проверки } ``` ### 2.2. Обычный режим (без `isTest`) - Если `isTest` **не передан** или `false` — поведение **НЕ изменилось**: - проверяется существование пользователя по `userId`; - считается количество попыток; - создаётся `ChallengeSubmission`; - попытка ставится в очередь на проверку через LLM; - в ответе фронтенд получает `queueId` и `submissionId`. ### 2.3. Тестовый режим (`isTest: true`) - Доступен только для ролей `teacher` / `challenge-author` (проверка через `isTeacher(req, true)`). - **Не создаётся** запись `ChallengeSubmission`. - **Не используется** очередь проверки. - Проверяется только существование задания (`taskId`), пользователь по `userId` в этом режиме **не ищется и не нужен** (но поле всё ещё формально обязательно по схеме). - Если переданы `hiddenInstructions`, они используются **вместо** `task.hiddenInstructions` при формировании промпта для LLM. - Никакие изменения инструкций, переданные через `hiddenInstructions`, **не сохраняются** в базу — это чисто временная инструкция для одной тестовой проверки. **Пример запроса (тестовый режим):** ```http POST /api/challenge/submit Content-Type: application/json Authorization: Bearer { "userId": "any-or-dummy-id", "taskId": "507f1f77bcf86cd799439012", "result": "function solve() { ... }", "isTest": true, "hiddenInstructions": "ВРЕМЕННЫЕ инструкции для проверки, не сохраняются" } ``` **Пример ответа (тестовый режим):** ```json { "error": null, "data": { "isTest": true, "status": "accepted", // или "needs_revision" "feedback": "Развёрнутый комментарий от LLM" } } ``` При отсутствии прав (нет роли `teacher` / `challenge-author`) вернётся 403. ### 2.4. Требования к фронтенду - **Где использовать тестовый режим**: - только в админских/преподавательских интерфейсах (например, экран настройки задания или предпросмотр проверки); - использовать флаг `isTest: true`, когда нужно получить мгновенный ответ от LLM без записи в историю; - при наличии UI-редактора скрытых инструкций использовать `hiddenInstructions` для передачи временного варианта, не сохраняя его. - **Где НЕ использовать**: - в пользовательском флоу сдачи заданий студентами — там должен использоваться обычный режим **без** `isTest`. - **UI-ожидания**: - показывать администратору статус (`accepted` / `needs_revision`) и `feedback`; - явно обозначить в интерфейсе, что это «тестовая проверка» и она **не попадает в статистику / попытки**, а переданные `hiddenInstructions` не сохраняются. --- ## 3. Краткое резюме - Для цепочек: - пользовательский список: `GET /api/challenge/chains` → только активные (`isActive: true`); - админский список: `GET /api/challenge/chains/admin` → все цепочки + управление `isActive` через `POST/PUT /chain`. - Для отправки решений: - обычный режим без `isTest` — всё как раньше (очередь, попытки, статистика); - тестовый режим с `isTest: true` + опциональные `hiddenInstructions` — только для `teacher/challenge-author`, без записи прогресса, сразу возвращает результат проверки с учётом временных инструкций.