{"openapi":"3.0.1","info":{"title":"QAIRU OS API","version":"1","description":"Read access to the modules of the QAIRU OS and the Alem.Cloud language model bridge. Authorize with an API key issued by the university (apiToken) or on behalf of a student through Sign in with QAIRU (oauth2, authorization code with PKCE). Data modules accept GET requests only; the operations below are those of the university services, at paths relative to the server address."},"servers":[{"url":"https://api.bbx.kz/os/v1"}],"security":[{"apiToken":[]},{"oauth2":[]}],"paths":{"/users/{userId}/teacher-profile":{"get":{"tags":["USERS: Profiles"],"summary":"Получить профиль преподавателя","description":"Возвращает профиль преподавателя по userId (включая ставку). Поля academicTitle (учёное звание — не то же, что учёная степень degree) и office (корпус и кабинет одной строкой) печатаются в паспорте силлабуса. Поле rate — доля ставки: 1.0 = полная ставка, 0.5 = полставки (НЕ оклад). Поля bio / expertise / photoFileId — витрина карточки, которую преподаватель заполняет о себе сам (GET/PUT /users/me/teacher-profile); их же читает карточка преподавателя на экране записи студента.","operationId":"users_getTeacherProfile","parameters":[{"name":"userId","in":"path","description":"UUID пользователя","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Профиль найден","content":{"*/*":{"schema":{"$ref":"#/components/schemas/TeacherProfileDto"}}}},"401":{"description":"Не аутентифицирован","content":{"*/*":{"schema":{"$ref":"#/components/schemas/TeacherProfileDto"}}}},"403":{"content":{"*/*":{"schema":{"$ref":"#/components/schemas/TeacherProfileDto"}}}},"404":{"description":"Профиль не существует","content":{"*/*":{"schema":{"$ref":"#/components/schemas/TeacherProfileDto"}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.users.read"]}]}},"/users/{userId}/student-profile":{"get":{"tags":["USERS: Profiles"],"summary":"Получить профиль студента","description":"Возвращает профиль студента по userId.","operationId":"users_getStudentProfile","parameters":[{"name":"userId","in":"path","description":"UUID пользователя","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Профиль найден","content":{"*/*":{"schema":{"$ref":"#/components/schemas/StudentProfileDto"}}}},"401":{"description":"Не аутентифицирован","content":{"*/*":{"schema":{"$ref":"#/components/schemas/StudentProfileDto"}}}},"403":{"content":{"*/*":{"schema":{"$ref":"#/components/schemas/StudentProfileDto"}}}},"404":{"description":"Профиль не существует","content":{"*/*":{"schema":{"$ref":"#/components/schemas/StudentProfileDto"}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.users.read"]}]}},"/users/{userId}/staff-profile":{"get":{"tags":["USERS: Profiles"],"summary":"Получить профиль сотрудника","description":"Возвращает профиль сотрудника по userId.","operationId":"users_getStaffProfile","parameters":[{"name":"userId","in":"path","description":"UUID пользователя","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Профиль найден","content":{"*/*":{"schema":{"$ref":"#/components/schemas/StaffProfileDto"}}}},"401":{"description":"Не аутентифицирован","content":{"*/*":{"schema":{"$ref":"#/components/schemas/StaffProfileDto"}}}},"403":{"content":{"*/*":{"schema":{"$ref":"#/components/schemas/StaffProfileDto"}}}},"404":{"description":"Профиль не существует","content":{"*/*":{"schema":{"$ref":"#/components/schemas/StaffProfileDto"}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.users.read"]}]}},"/users/me/teacher-profile":{"get":{"tags":["USERS: My teacher profile"],"summary":"Моя карточка преподавателя","description":"Карточка текущего пользователя: должность, степень, учёное звание, кабинет, доля ставки, рассказ о себе, экспертиза, портрет. Учёное звание (academicTitle) и кабинет (office) правит сам преподаватель; звание — не то же самое, что учёная степень (degree), и в паспорте силлабуса печатаются обе строки. Карточку преподаватель заводит себе сам, и отказ «сначала попроси администратора» закрыл бы экран профиля навсегда. Сам запрос ничего в базе не создаёт — строка появляется при первом сохранении.","operationId":"users_getMyTeacherProfile","responses":{"200":{"description":"Карточка (возможно пустая)","content":{"*/*":{"schema":{"$ref":"#/components/schemas/TeacherProfileDto"}}}},"401":{"description":"Не аутентифицирован","content":{"*/*":{"schema":{"$ref":"#/components/schemas/TeacherProfileDto"}}}},"403":{"content":{"*/*":{"schema":{"$ref":"#/components/schemas/TeacherProfileDto"}}}},"404":{"description":"Учётной записи с таким sub нет в сервисе","content":{"*/*":{"schema":{"$ref":"#/components/schemas/TeacherProfileDto"}}}}},"x-badges":[{"position":"after","name":"TEACHER","color":"#2563eb"},{"position":"after","name":"PORTAL_ADMIN","color":"#dc2626"}],"security":[{"apiToken":[]},{"oauth2":["qairu.users.read"]}]}},"/users/me/student-profile":{"get":{"tags":["USERS: My student profile"],"summary":"Мой профиль студента","description":"Профиль текущего пользователя: программа, курс, форма обучения, фото, личная почта, «о себе». Программа и курс приходят также в GET /users/me.","operationId":"users_getMyStudentProfile","responses":{"200":{"description":"Профиль найден","content":{"*/*":{"schema":{"$ref":"#/components/schemas/StudentProfileDto"}}}},"401":{"description":"Не аутентифицирован","content":{"*/*":{"schema":{"$ref":"#/components/schemas/StudentProfileDto"}}}},"404":{"description":"У пользователя нет профиля студента","content":{"*/*":{"schema":{"$ref":"#/components/schemas/StudentProfileDto"}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.users.read"]}]}},"/users/me/interests":{"get":{"tags":["USERS: Interests"],"summary":"Мои интересы","description":"Выбор по ОБОИМ вопросам на выбранном языке: selected — темы для изучения, life — что нравится в жизни. Плюс правила выбора: recommendedMin — сколько тем просим выбрать, maxTags — предел для тем, maxLifeTags — предел для увлечений (он меньше), maxCustom — сколько своих вариантов разрешено в каждом вопросе. completed=true — шаг «Знакомство» пройден (есть хотя бы один интерес в любом из двух списков).","operationId":"users_myInterests","parameters":[{"name":"locale","in":"query","description":"Локаль: ru | kk | en","required":false,"schema":{"type":"string","default":"ru"},"example":"ru"}],"responses":{"200":{"description":"Мои интересы","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MyInterestsDto"}}}},"401":{"description":"Не аутентифицирован","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MyInterestsDto"}}}},"404":{"content":{"*/*":{"schema":{"$ref":"#/components/schemas/MyInterestsDto"}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.users.read"]}]}},"/users/me/mentor":{"get":{"tags":["USERS: Mentors"],"summary":"Мой ментор","description":"Карточка закреплённого ментора с контактами.","operationId":"users_getMyMentor","parameters":[{"name":"locale","in":"query","description":"Локаль названий тегов: ru | kk | en","required":false,"schema":{"type":"string","default":"ru"},"example":"ru"}],"responses":{"200":{"description":"Состояние закрепления","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MyMentorDto"}}}},"401":{"description":"Не аутентифицирован","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MyMentorDto"}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.users.read"]}]}},"/users/me":{"get":{"tags":["USERS: Users"],"summary":"Current user profile","description":"Merged view {username, email, firstName, lastName, phone, realmRoles, preferredLanguage}. keycloakId resolved from JWT (sub claim). preferredLanguage ('ru'|'kk'|'en', may be null) is the language of outbound emails/notifications, stored on the local user. The cabinet shows it in the «что будет в справке» preview — never `program` there. Both are null together (no programme / learning contour unreachable).","operationId":"users_getMyProfile","responses":{"200":{"description":"Profile found","content":{"*/*":{"schema":{"$ref":"#/components/schemas/UserProfileDto"}}}},"401":{"description":"Token missing or invalid","content":{"*/*":{"schema":{"$ref":"#/components/schemas/UserProfileDto"}}}},"404":{"content":{"*/*":{"schema":{"$ref":"#/components/schemas/UserProfileDto"}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.users.read"]}]}},"/users":{"get":{"tags":["USERS: Users"],"summary":"List all users","description":"Paginated list of all users; each row is `{username, roles}` — no contact details. page must be 0 or greater and size 1..1000 — anything else is a 400, not a 500.","operationId":"users_getAllUsers","parameters":[{"name":"page","in":"query","description":"Page number (0-based)","required":false,"schema":{"type":"integer","format":"int32","default":0},"example":0},{"name":"size","in":"query","description":"Page size, 1..1000","required":false,"schema":{"type":"integer","format":"int32","default":10},"example":10}],"responses":{"200":{"description":"Paginated user list","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ListPaginationUserDto"}}}},"400":{"description":"page < 0, or size outside 1..1000","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ListPaginationUserDto"}}}},"401":{"description":"Token missing or invalid","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ListPaginationUserDto"}}}},"403":{"content":{"*/*":{"schema":{"$ref":"#/components/schemas/ListPaginationUserDto"}}}}},"x-badges":[{"position":"after","name":"PORTAL_ADMIN","color":"#dc2626"}],"security":[{"apiToken":[]},{"oauth2":["qairu.users.read"]}]}},"/users/teachers/cards":{"get":{"tags":["USERS: Teacher cards"],"summary":"Карточки преподавателей (витрина для студента)","description":"Все преподаватели, у которых заполнена хотя бы одна видимая часть карточки (рассказ о себе, должность, степень, экспертиза или портрет), отсортированные по имени. Без постраничности: в вузе десятки преподавателей, а экрану записи нужны все сразу.\nЗачем список, а не карточка по идентификатору: каталог расписания, из которого экран записи берёт преподавателя, идентификаторов человека не носит (в каталоге элективов есть только имена), поэтому клиент сводит карточку с потоком ПО ИМЕНИ.\nДоступ: любой вошедший в систему.","operationId":"users_teacherCards","responses":{"200":{"description":"Список карточек (возможно пустой)","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/TeacherPublicCardDto"}}}}},"401":{"description":"Не аутентифицирован","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/TeacherPublicCardDto"}}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.users.read"]}]}},"/users/org/departments/tree":{"get":{"tags":["USERS: Org directory"],"summary":"Дерево подразделений","description":"Корневые подразделения с вложенными детьми. Цикл или чрезмерная глубина в испорченных данных обрывают спуск (пустые children + WARN в логе), а не роняют ответ.","operationId":"users_tree","responses":{"200":{"description":"Дерево подразделений","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/OrgDepartmentTreeResponse"}}}}},"401":{"description":"Не авторизован","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/OrgDepartmentTreeResponse"}}}}},"403":{"description":"Роль вне списка сотрудников вуза","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/OrgDepartmentTreeResponse"}}}}}},"x-badges":[{"position":"after","name":"EMPLOYEE","color":"#6b7280"},{"position":"after","name":"TEACHER","color":"#2563eb"},{"position":"after","name":"PORTAL_ADMIN","color":"#dc2626"},{"position":"after","name":"DOCFLOW_ADMIN","color":"#6b7280"},{"position":"after","name":"RECTOR","color":"#6b7280"},{"position":"after","name":"VICE_RECTOR","color":"#6b7280"},{"position":"after","name":"HR","color":"#6b7280"},{"position":"after","name":"ACCOUNTANT","color":"#6b7280"},{"position":"after","name":"ECONOMIST","color":"#6b7280"},{"position":"after","name":"LAWYER","color":"#6b7280"},{"position":"after","name":"ANALYST","color":"#6b7280"},{"position":"after","name":"ACADEMIC_DIRECTOR","color":"#6b7280"},{"position":"after","name":"ACADEMIC_MANAGER","color":"#6b7280"}],"security":[{"apiToken":[]},{"oauth2":["qairu.users.read"]}]}},"/users/org/departments":{"get":{"tags":["USERS: Org directory"],"summary":"Плоский список подразделений","description":"Все подразделения одним списком, отсортированы по порядку и названию. Дерево строится по parentId.","operationId":"users_list_2","responses":{"200":{"description":"Список подразделений","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/OrgDepartmentResponse"}}}}},"401":{"description":"Не авторизован","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/OrgDepartmentResponse"}}}}},"403":{"description":"Роль вне списка сотрудников вуза","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/OrgDepartmentResponse"}}}}}},"x-badges":[{"position":"after","name":"EMPLOYEE","color":"#6b7280"},{"position":"after","name":"TEACHER","color":"#2563eb"},{"position":"after","name":"PORTAL_ADMIN","color":"#dc2626"},{"position":"after","name":"DOCFLOW_ADMIN","color":"#6b7280"},{"position":"after","name":"RECTOR","color":"#6b7280"},{"position":"after","name":"VICE_RECTOR","color":"#6b7280"},{"position":"after","name":"HR","color":"#6b7280"},{"position":"after","name":"ACCOUNTANT","color":"#6b7280"},{"position":"after","name":"ECONOMIST","color":"#6b7280"},{"position":"after","name":"LAWYER","color":"#6b7280"},{"position":"after","name":"ANALYST","color":"#6b7280"},{"position":"after","name":"ACADEMIC_DIRECTOR","color":"#6b7280"},{"position":"after","name":"ACADEMIC_MANAGER","color":"#6b7280"}],"security":[{"apiToken":[]},{"oauth2":["qairu.users.read"]}]}},"/users/org/departments/":{"get":{"tags":["USERS: Org directory"],"summary":"Плоский список подразделений","description":"Все подразделения одним списком, отсортированы по порядку и названию. Дерево строится по parentId.","operationId":"users_list_3","responses":{"200":{"description":"Список подразделений","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/OrgDepartmentResponse"}}}}},"401":{"description":"Не авторизован","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/OrgDepartmentResponse"}}}}},"403":{"description":"Роль вне списка сотрудников вуза","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/OrgDepartmentResponse"}}}}}},"x-badges":[{"position":"after","name":"EMPLOYEE","color":"#6b7280"},{"position":"after","name":"TEACHER","color":"#2563eb"},{"position":"after","name":"PORTAL_ADMIN","color":"#dc2626"},{"position":"after","name":"DOCFLOW_ADMIN","color":"#6b7280"},{"position":"after","name":"RECTOR","color":"#6b7280"},{"position":"after","name":"VICE_RECTOR","color":"#6b7280"},{"position":"after","name":"HR","color":"#6b7280"},{"position":"after","name":"ACCOUNTANT","color":"#6b7280"},{"position":"after","name":"ECONOMIST","color":"#6b7280"},{"position":"after","name":"LAWYER","color":"#6b7280"},{"position":"after","name":"ANALYST","color":"#6b7280"},{"position":"after","name":"ACADEMIC_DIRECTOR","color":"#6b7280"},{"position":"after","name":"ACADEMIC_MANAGER","color":"#6b7280"}],"security":[{"apiToken":[]},{"oauth2":["qairu.users.read"]}]}},"/users/onboarding/content":{"get":{"tags":["USERS: Onboarding"],"summary":"Контент онбординга (о вузе + ролики)","description":"Возвращает ОПУБЛИКОВАННЫЕ блоки «о вузе» и видеоинструкции выбранной аудитории на выбранном языке; viewed — по вызывающему. Блок несёт eyebrow, facts (value/label), points, chips и scene (встроенная иллюстрация; при заданной сцене картинка блока не показывается). Ролики без загруженного файла не отдаются. Локаль: ru (по умолчанию), kk, en; при пустом переводе поле берётся из ru.","operationId":"users_getContent","parameters":[{"name":"locale","in":"query","description":"Локаль: ru | kk | en","required":false,"schema":{"type":"string","default":"ru"},"example":"ru"},{"name":"audience","in":"query","required":false,"schema":{"type":"string","enum":["STUDENT","TEACHER"]},"example":"TEACHER"}],"responses":{"200":{"description":"Контент (может быть пустым)","content":{"*/*":{"schema":{"$ref":"#/components/schemas/OnboardingContentDto"}}}},"400":{"description":"Неизвестная аудитория","content":{"*/*":{"schema":{"$ref":"#/components/schemas/OnboardingContentDto"}}}},"401":{"description":"Не аутентифицирован","content":{"*/*":{"schema":{"$ref":"#/components/schemas/OnboardingContentDto"}}}},"403":{"content":{"*/*":{"schema":{"$ref":"#/components/schemas/OnboardingContentDto"}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.users.read"]}]}},"/users/mentors":{"get":{"tags":["USERS: Mentors"],"summary":"Список менторов со свободными местами","description":"Активные менторы с счётчиком мест (capacity/taken/free). available=false — мест нет, карточка приглушается и выбрать нельзя. В ответе также myMentorId (если ментор уже выбран), deferred (нажал «выберу позже») и anySlotsAvailable — когда false, экран показывает «Свободных менторов сейчас нет», и шаг всё равно проходится.\nS-16: у каждой карточки есть interestTags (коды справочника интересов), matchedInterests (пересечение с интересами ЭТОГО студента) и matchScore. sort=MATCH (по умолчанию, если студент заполнил интересы) ставит совпавших выше: matchScore, затем свободные места, затем алфавит. Если интересов у студента нет, сортировка молча становится NAME — фактическая подписана в поле sort ответа. interests=CODE1,CODE2 оставляет только тех, у кого есть хотя бы один из этих тегов (hiddenByFilter — сколько карточек скрыл фильтр).","operationId":"users_listMentors_1","parameters":[{"name":"sort","in":"query","description":"Порядок: MATCH (по совпадению интересов) | NAME (алфавит)","required":false,"schema":{"type":"string","enum":["MATCH","NAME"]},"example":"MATCH"},{"name":"interests","in":"query","description":"Фильтр по кодам интересов, через запятую","required":false,"schema":{"type":"array","items":{"type":"string"}}},{"name":"onlyAvailable","in":"query","description":"Показывать только тех, у кого есть свободные места","required":false,"schema":{"type":"boolean","default":false}},{"name":"locale","in":"query","description":"Локаль названий тегов: ru | kk | en","required":false,"schema":{"type":"string","default":"ru"},"example":"ru"}],"responses":{"200":{"description":"Список менторов","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MentorListDto"}}}},"401":{"description":"Не аутентифицирован","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MentorListDto"}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.users.read"]}]}},"/users/me/student-record":{"get":{"tags":["USERS: My student record"],"summary":"Мои данные приёма","description":"Личные данные, удостоверение (реквизиты и скан — fileId для GET /api/files/{id}/download), адреса, законный представитель, образование, ЕНТ/КТ, льготы. Данных нет (студент заведён списком или перенос ещё не прошёл) — пустые секции и пустые списки, а не 404. transferredAt — когда данные пришли из приёма, updatedAt — последняя правка регистратора.","operationId":"users_getMyStudentRecord","responses":{"200":{"description":"Данные (секции могут быть пустыми)","content":{"*/*":{"schema":{"$ref":"#/components/schemas/StudentRecordDto"}}}},"401":{"description":"Не аутентифицирован","content":{"*/*":{"schema":{"$ref":"#/components/schemas/StudentRecordDto"}}}},"403":{"content":{"*/*":{"schema":{"$ref":"#/components/schemas/StudentRecordDto"}}}},"404":{"content":{"*/*":{"schema":{"$ref":"#/components/schemas/StudentRecordDto"}}}}},"x-badges":[{"position":"after","name":"STUDENT","color":"#06b6d4"}],"security":[{"apiToken":[]},{"oauth2":["qairu.users.read"]}]}},"/users/me/student-documents":{"get":{"tags":["USERS: My student record"],"summary":"Мои документы","description":"Раздел «Документы» профиля: все актуальные файлы приёма (включая медицинские справки и документы воинского учёта, П-4) и документы, добавленные регистратором. Порядок — по категории (REQUIRED, FINANCIAL, PRIVILEGE_QUOTA, ACHIEVEMENT, FOREIGN_CITIZEN, INTEGRATION, ISSUED, OTHER), внутри — новые выше. Скачивание — GET /api/files/{fileId}/download. Договоры здесь НЕ отдаются — они живут в ЭДО (GET /api/docflow/my/subject-documents).","operationId":"users_getMyStudentDocuments","responses":{"200":{"description":"Список (может быть пустым)","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/StudentDocumentDto"}}}}},"401":{"description":"Не аутентифицирован","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/StudentDocumentDto"}}}}},"403":{"content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/StudentDocumentDto"}}}}},"404":{"content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/StudentDocumentDto"}}}}}},"x-badges":[{"position":"after","name":"STUDENT","color":"#06b6d4"}],"security":[{"apiToken":[]},{"oauth2":["qairu.users.read"]}]}},"/users/me/onboarding":{"get":{"tags":["USERS: Onboarding"],"summary":"Состояние онбординга текущего пользователя","description":"Честный ответ «не пройден / в процессе / пройден» для ЛЮБОГО студента, а не только для вошедшего по временному паролю: status = NOT_STARTED | IN_PROGRESS | COMPLETED, progressPercent, stepsDone/stepsTotal и полный перечень шагов в steps — по нему рисуется карточка «Закончите знакомство».\nsteps[]: step (ABOUT, VIDEOS, INTRO, MENTOR, DIAGNOSTIC), status (DONE | PENDING | SKIPPED | UNKNOWN), blocking (запирает ли кабинет — ВСЕГДА false), countsToProgress, source (USER_SERVICE | LEARNING_SERVICE), checkPath. Состояние шага DIAGNOSTIC принадлежит учебному контуру и СПРАШИВАЕТСЯ у него при каждом чтении (пройденная диагностика приходит как DONE с датой результата). UNKNOWN = учебный контур не ответил: шаг остаётся в перечне и в знаменателе, но пройден он или нет — неизвестно. SKIPPED = шага у этого студента не существует: нет блоков, роликов или активных менторов; банк вопросов диагностики пуст; учебной карточки ещё нет.\nЕсли профиля студента ещё нет, возвращается пустое состояние (без создания записи).","operationId":"users_getState","responses":{"200":{"description":"Состояние онбординга","content":{"*/*":{"schema":{"$ref":"#/components/schemas/OnboardingStateDto"}}}},"401":{"description":"Не аутентифицирован","content":{"*/*":{"schema":{"$ref":"#/components/schemas/OnboardingStateDto"}}}},"404":{"content":{"*/*":{"schema":{"$ref":"#/components/schemas/OnboardingStateDto"}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.users.read"]}]}},"/users/me/mentees":{"get":{"tags":["USERS: Mentors"],"summary":"Мои подопечные","description":"Список закреплённых студентов текущего ментора: ФИО, корпоративная почта, программа, курс, фото, дата закрепления. Если пользователь не зарегистрирован как ментор — isMentor=false и пустой список.","operationId":"users_getMyMentees","responses":{"200":{"description":"Список подопечных","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MyMenteesDto"}}}},"401":{"description":"Не аутентифицирован","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MyMenteesDto"}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.users.read"]}]}},"/users/interest-tags":{"get":{"tags":["USERS: Interests"],"summary":"Справочник интересов","description":"Активные теги ОДНОГО вопроса анкеты на выбранном языке, в порядке показа. Пустой перевод откатывается на русский.","operationId":"users_catalog","parameters":[{"name":"locale","in":"query","description":"Локаль: ru | kk | en","required":false,"schema":{"type":"string","default":"ru"},"example":"ru"},{"name":"kind","in":"query","description":"Вопрос анкеты: ACADEMIC — что интересно изучать, LIFE — что нравится в жизни. По умолчанию ACADEMIC","required":false,"schema":{"type":"string","default":"ACADEMIC","enum":["ACADEMIC","LIFE"]},"example":"ACADEMIC"}],"responses":{"200":{"description":"Справочник","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/InterestTagDto"}}}}},"401":{"description":"Не аутентифицирован","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/InterestTagDto"}}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.users.read"]}]}},"/users/directory/teachers":{"get":{"tags":["USERS: People directory"],"summary":"Teacher directory (picker)","description":"Not paginated: the university has dozens of teachers and a dropdown needs all of them at once.\nFeeds two pickers.\nThis one is two fields, open to the roles that actually author programmes.\nThose two learn nothing new here: a teacher name is already readable by any logged-in account through GET /users/teachers/cards.","operationId":"users_teachers","responses":{"200":{"description":"DirectoryEntryDto list (possibly empty)","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/DirectoryEntryDto"}}}}},"401":{"description":"Token missing or invalid","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/DirectoryEntryDto"}}}}},"403":{"content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/DirectoryEntryDto"}}}}}},"x-badges":[{"position":"after","name":"PORTAL_ADMIN","color":"#dc2626"},{"position":"after","name":"TEACHER","color":"#2563eb"},{"position":"after","name":"EMPLOYEE","color":"#6b7280"},{"position":"after","name":"RECTOR","color":"#6b7280"},{"position":"after","name":"VICE_RECTOR","color":"#6b7280"},{"position":"after","name":"STUDENT","color":"#06b6d4"},{"position":"after","name":"STUDENT_AFFAIRS","color":"#6b7280"},{"position":"after","name":"ACADEMIC_DIRECTOR","color":"#6b7280"},{"position":"after","name":"ACADEMIC_MANAGER","color":"#6b7280"}],"security":[{"apiToken":[]},{"oauth2":["qairu.users.read"]}]}},"/files/{fileId}":{"get":{"tags":["FILES: Файлы"],"summary":"Получить метаданные файла","description":"Возвращает публичное представление FileRecord по UUID.\nОтказ возвращает 404, а не 403; при app.file-access.enforce = false (режим тени) отказ только логируется.\npurgedAt — момент физического удаления объекта планировщиком ретенции (null = объект ещё на месте). available=false означает, что физический объект удалён по ретенции (метаданные сохранены).","operationId":"files_getFileById","parameters":[{"name":"fileId","in":"path","description":"UUID записи файла","required":true,"schema":{"type":"string","format":"uuid"},"example":"3fa85f64-5717-4562-b3fc-2c963f66afa6"}],"responses":{"200":{"description":"Метаданные успешно возвращены","content":{"*/*":{"schema":{"$ref":"#/components/schemas/FileRecordDto"}}}},"401":{"description":"Требуется авторизация","content":{"*/*":{"schema":{"$ref":"#/components/schemas/FileRecordDto"}}}},"404":{"description":"Файл не найден либо доступ к нему не выдан","content":{"*/*":{"schema":{"$ref":"#/components/schemas/FileRecordDto"}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.files.read"]}]}},"/files/{fileId}/download":{"get":{"tags":["FILES: Файлы"],"summary":"Скачать файл","description":"Передаёт содержимое файла клиенту с оригинальным именем и MIME-типом. Требует UUID записи файла из БД.\nПоддерживает частичную выдачу: ответ всегда несёт Accept-Ranges: bytes, а запрос с заголовком Range вида bytes=НАЧАЛО-КОНЕЦ получает 206 Partial Content с Content-Range. Именно это позволяет смотреть запись наблюдения с перемоткой через ЭТУ дверь (где проверяется право), а не по подписанной ссылке хранилища, которую можно переслать кому угодно. Многодиапазонный запрос (bytes=0-99,200-299) не поддерживается и обрабатывается как обычный: отдаётся файл целиком.","operationId":"files_downloadFile","parameters":[{"name":"fileId","in":"path","description":"UUID записи файла","required":true,"schema":{"type":"string","format":"uuid"},"example":"3fa85f64-5717-4562-b3fc-2c963f66afa6"},{"name":"Range","in":"header","description":"Диапазон байтов (RFC 9110), например bytes=0-1048575. Без него файл отдаётся целиком","required":false,"schema":{"type":"string"},"example":"bytes=0-1048575"}],"responses":{"200":{"description":"Поток файла успешно возвращён","content":{"*/*":{"schema":{"$ref":"#/components/schemas/StreamingResponseBody"}}}},"206":{"description":"Возвращён запрошенный диапазон байтов (заголовок Range)","content":{"*/*":{"schema":{"$ref":"#/components/schemas/StreamingResponseBody"}}}},"400":{"description":"Ошибка получения файла из хранилища","content":{"*/*":{"schema":{"$ref":"#/components/schemas/StreamingResponseBody"}}}},"401":{"description":"Требуется авторизация","content":{"*/*":{"schema":{"$ref":"#/components/schemas/StreamingResponseBody"}}}},"404":{"description":"Файл не найден либо доступ к нему не выдан","content":{"*/*":{"schema":{"$ref":"#/components/schemas/StreamingResponseBody"}}}},"410":{"description":"Файл удалён по ретенции и более недоступен","content":{"*/*":{"schema":{"$ref":"#/components/schemas/StreamingResponseBody"}}}},"416":{"description":"Запрошенный диапазон выходит за пределы файла","content":{"*/*":{"schema":{"$ref":"#/components/schemas/StreamingResponseBody"}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.files.read"]}]}},"/learning/spaces/{spaceId}/sources/{sourceId}/text":{"get":{"tags":["LEARNING: Study notebook sources"],"summary":"A window of the source text","description":"The extracted Markdown cut exactly by UTF-16 indexes (String.substring): offset ≥ 0, 1 ≤ limit ≤ 200 000 (default 100 000). textLength is the full length. No text yet -> textLength 0, text \"\".","operationId":"learning_text","parameters":[{"name":"spaceId","in":"path","description":"Notebook id","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"sourceId","in":"path","description":"Source id","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"offset","in":"query","description":"Start offset in UTF-16 units","required":false,"schema":{"type":"integer","format":"int32"},"example":0},{"name":"limit","in":"query","description":"Window size, 1-200000","required":false,"schema":{"type":"integer","format":"int32"},"example":100000}],"responses":{"200":{"description":"Text window","content":{"*/*":{"schema":{"$ref":"#/components/schemas/SourceTextWindowDto"}}}},"400":{"description":"offset or limit out of range (WINDOW_INVALID)","content":{"*/*":{"schema":{"$ref":"#/components/schemas/SourceTextWindowDto"}}}},"401":{"description":"No/invalid JWT","content":{"*/*":{"schema":{"$ref":"#/components/schemas/SourceTextWindowDto"}}}},"404":{"description":"Notebook or source not found","content":{"*/*":{"schema":{"$ref":"#/components/schemas/SourceTextWindowDto"}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.learning.read"]}]}},"/learning/resume/badges":{"get":{"tags":["LEARNING: Resume achievements (student)"],"summary":"Достижения, которые можно вынести в резюме","description":"Полученные достижения категорий STUDY / SKILLS / PROJECTS с фразой-фактом на трёх языках («25 работ сдано в срок») и отметкой выбранных. Профиль («Цель выбрана», «На связи») и кампус в список не входят.","operationId":"learning_badges","responses":{"200":{"description":"Варианты для резюме","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ResumeBadgesDto"}}}},"401":{"description":"Нет или невалидный JWT","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ResumeBadgesDto"}}}},"403":{"content":{"*/*":{"schema":{"$ref":"#/components/schemas/ResumeBadgesDto"}}}},"404":{"description":"У вызывающего нет учебной карточки","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ResumeBadgesDto"}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.learning.read"]}]}},"/learning/resume/about":{"get":{"tags":["LEARNING: Resume (student)"],"summary":"Блок «О себе»","description":"Статус поиска (INTERNSHIP | JOB | OPEN_TO_OFFERS | null — «не указано»), текст «О себе» (первый раздел ABOUT) и «Контакты» (первый раздел CONTACTS). Без учебной карточки — все три поля null.","operationId":"learning_about","responses":{"200":{"description":"Блок «О себе»","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ResumeAboutDto"}}}},"401":{"description":"Нет или невалидный JWT","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ResumeAboutDto"}}}},"403":{"content":{"*/*":{"schema":{"$ref":"#/components/schemas/ResumeAboutDto"}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.learning.read"]}]}},"/learning/me/semester/reflection":{"get":{"tags":["LEARNING: Semester summary (student)"],"summary":"Моя рефлексия по периоду","description":"Сохранённые ответы студента: что получилось, что было трудно, цели на следующий период и две оценки 1..5. Ничего не написано — пустой ответ (204), а не 404: ненаписанная рефлексия — нормальное состояние, а не отсутствие ресурса.","operationId":"learning_myReflection","parameters":[{"name":"academicYear","in":"query","description":"Учебный год","required":false,"schema":{"type":"string"},"example":"2026-2027"},{"name":"termNo","in":"query","description":"Номер триместра 1..3","required":false,"schema":{"type":"integer","format":"int32"},"example":1}],"responses":{"200":{"description":"Рефлексия","content":{"*/*":{"schema":{"$ref":"#/components/schemas/SemesterReflectionDto"}}}},"204":{"description":"Рефлексии по этому периоду ещё нет","content":{"*/*":{"schema":{"$ref":"#/components/schemas/SemesterReflectionDto"}}}},"400":{"description":"Период не задан, а текущий определить нечем","content":{"*/*":{"schema":{"$ref":"#/components/schemas/SemesterReflectionDto"}}}},"401":{"description":"Нет/невалидный JWT","content":{"*/*":{"schema":{"$ref":"#/components/schemas/SemesterReflectionDto"}}}},"403":{"content":{"*/*":{"schema":{"$ref":"#/components/schemas/SemesterReflectionDto"}}}},"404":{"description":"Названного периода нет в календаре либо у вызывающего нет учебной карточки","content":{"*/*":{"schema":{"$ref":"#/components/schemas/SemesterReflectionDto"}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.learning.read"]}]}},"/learning/spaces":{"get":{"tags":["LEARNING: Study notebooks"],"summary":"List my notebooks","description":"The caller's notebooks sorted by updatedAt DESC, createdAt DESC: title, source count, dates, sourceKinds (distinct displayKind of its sources, first added first, at most 6 — the card glyphs). updatedAt is never null (falls back to createdAt); chat turns do not move it. Legacy archived rows are not listed. Caller without a Learner row gets an empty list.","operationId":"learning_list","responses":{"200":{"description":"Notebooks of the caller","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/NotebookSummaryDto"}}}}},"401":{"description":"No/invalid JWT","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/NotebookSummaryDto"}}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.learning.read"]}]}},"/learning/spaces/{spaceId}/sources":{"get":{"tags":["LEARNING: Study notebook sources"],"summary":"List the sources of a notebook","description":"SourceDto[] by createdAt ASC, without text; each carries sizeBytes (file size from the file service, null without a file) and updatedAt (last text edit or end of extraction, createdAt before that). The cabinet polls it while some source is PENDING / EXTRACTING or its guide is PENDING. displayKind is decided here, not on the client.","operationId":"learning_list_1","parameters":[{"name":"spaceId","in":"path","description":"Notebook id","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Sources","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/StudySourceDto"}}}}},"401":{"description":"No/invalid JWT","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/StudySourceDto"}}}}},"404":{"description":"Notebook not found or owned by someone else","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/StudySourceDto"}}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.learning.read"]}]}},"/learning/spaces/{spaceId}/notes":{"get":{"tags":["LEARNING: Study notebook notes"],"summary":"List notes","description":"Notes of the notebook, updatedAt DESC.","operationId":"learning_list_2","parameters":[{"name":"spaceId","in":"path","description":"Notebook id","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Notes","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/NoteDto"}}}}},"401":{"description":"No/invalid JWT","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/NoteDto"}}}}},"404":{"description":"Notebook not found or owned by someone else","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/NoteDto"}}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.learning.read"]}]}},"/learning/resume/share":{"get":{"tags":["LEARNING: Resume (student)"],"summary":"Состояние моей публичной ссылки","description":"Включена ли ссылка и её токен (только когда включена). Без учебной карточки — выключенное состояние.","operationId":"learning_shareState","responses":{"200":{"description":"Состояние ссылки","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ResumeShareStateDto"}}}},"403":{"content":{"*/*":{"schema":{"$ref":"#/components/schemas/ResumeShareStateDto"}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.learning.read"]}]}},"/learning/resume/certificates":{"get":{"tags":["LEARNING: Resume certificates (student)"],"summary":"Мои сертификаты","description":"Все сертификаты студента в трёх статусах (PENDING, VERIFIED, REJECTED), кроме проверенных, которые он убрал из резюме. 8).","operationId":"learning_list_3","responses":{"200":{"description":"Сертификаты (может быть пусто)","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/MyCertificateDto"}}}}},"401":{"description":"Нет или невалидный JWT","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/MyCertificateDto"}}}}},"403":{"content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/MyCertificateDto"}}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.learning.read"]}]}},"/learning/resume/achievements":{"get":{"tags":["LEARNING: Resume achievements"],"summary":"Мои работы портфолио","description":"Новые сверху, работы без даты — последними. У каждой приходит список файлов: идентификатор в файловой службе и имя. Тот же fileId уходит обратно в fileIds при сохранении работы. Вызывающий без учебной карточки (преподаватель/админ) получает пустой список, не ошибку.","operationId":"learning_list_4","responses":{"200":{"description":"Работы вызывающего, по порядку показа","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/ResumeAchievementDto"}}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.learning.read"]}]}},"/learning/me/attendance/appeals":{"get":{"tags":["LEARNING: My attendance appeals"],"summary":"My attendance appeals","description":"Все мои обращения, свежие сверху, в любом статусе: PENDING · ACCEPTED · REJECTED · WITHDRAWN · CLOSED_UNRESOLVED. Имя того, кто ПОСТАВИЛ отметку, студент видит в деталях занятия (`markedByName`).","operationId":"learning_mine","responses":{"200":{"description":"Мои обращения (возможно, пустой список)","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/MyAttendanceAppealDto"}}}}},"401":{"description":"Нет/неверный JWT","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/MyAttendanceAppealDto"}}}}},"403":{"content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/MyAttendanceAppealDto"}}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.learning.read"]}]}},"/learning/submissions/{id}":{"get":{"tags":["LEARNING: Submissions"],"summary":"Get submission status","description":"Status/version/late flag and content refs of a submission. lateBySeconds: 0 = on time, null = no deadline. The grade block (totalScore/maxScore/feedback) is non-null only when the submission is GRADED (case 1.7). status may be WITHDRAWN: the student took the work back, the assignment reads as not submitted.","operationId":"learning_getSubmission","parameters":[{"name":"id","in":"path","description":"Submission id","required":true,"schema":{"type":"string","format":"uuid"},"example":"3f6f4c1e-2c1a-4c5e-9b1e-1a2b3c4d5e6f"}],"responses":{"200":{"description":"Submission","content":{"*/*":{"schema":{"$ref":"#/components/schemas/SubmissionDto"}}}},"401":{"description":"No/invalid JWT","content":{"*/*":{"schema":{"$ref":"#/components/schemas/SubmissionDto"}}}},"403":{"description":"Submission belongs to another learner and the caller is not the course's teacher/admin","content":{"*/*":{"schema":{"$ref":"#/components/schemas/SubmissionDto"}}}},"404":{"description":"Submission not found","content":{"*/*":{"schema":{"$ref":"#/components/schemas/SubmissionDto"}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.learning.read"]}]}},"/learning/spaces/{spaceId}/sources/{sourceId}":{"get":{"tags":["LEARNING: Study notebook sources"],"summary":"Get a source with its guide","description":"Every SourceDto field (incl. No storage link here.","operationId":"learning_get_5","parameters":[{"name":"spaceId","in":"path","description":"Notebook id","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"sourceId","in":"path","description":"Source id","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Source detail","content":{"*/*":{"schema":{"$ref":"#/components/schemas/StudySourceDetailDto"}}}},"401":{"description":"No/invalid JWT","content":{"*/*":{"schema":{"$ref":"#/components/schemas/StudySourceDetailDto"}}}},"404":{"description":"Notebook or source not found","content":{"*/*":{"schema":{"$ref":"#/components/schemas/StudySourceDetailDto"}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.learning.read"]}]}},"/learning/spaces/{spaceId}/artifacts/{artifactId}":{"get":{"tags":["LEARNING: Study notebook studio"],"summary":"Get an artifact","description":"Summary + payload (READY only) + sourceIds + customPrompt. Poll target while GENERATING. Works for Studio artifacts and per-source auto materials alike.","operationId":"learning_get_6","parameters":[{"name":"spaceId","in":"path","description":"Notebook id","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"artifactId","in":"path","description":"Artifact id","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Artifact","content":{"*/*":{"schema":{"$ref":"#/components/schemas/StudyArtifactDto"}}}},"401":{"description":"No/invalid JWT","content":{"*/*":{"schema":{"$ref":"#/components/schemas/StudyArtifactDto"}}}},"404":{"description":"Notebook or artifact not found","content":{"*/*":{"schema":{"$ref":"#/components/schemas/StudyArtifactDto"}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.learning.read"]}]}},"/learning/spaces/{id}":{"get":{"tags":["LEARNING: Study notebooks"],"summary":"Get a notebook","description":"The notebook page in one read: sources (SourceDto, without text), the overview (state NONE / PENDING / READY / STALE / FAILED; text and 3 questions for READY and STALE), Studio artifacts (newest first, without the per-source auto materials), notes count, maxSources = 50 and preferredLocale. The overview is in?locale (Н-11; without it — in preferredLocale, ru when none) and overview.locale echoes it; text of another language is never returned. Owner-only: foreign = 404.","operationId":"learning_get_7","parameters":[{"name":"id","in":"path","description":"Notebook id","required":true,"schema":{"type":"string","format":"uuid"},"example":"3f6f4c1e-2c1a-4c5e-9b1e-1a2b3c4d5e6f"},{"name":"locale","in":"query","description":"Interface language of the viewer: ru | kk | en","required":false,"schema":{"type":"string"},"example":"kk"}],"responses":{"200":{"description":"Notebook detail","content":{"*/*":{"schema":{"$ref":"#/components/schemas/NotebookDetailDto"}}}},"400":{"description":"Unknown locale (LOCALE_INVALID, field locale)","content":{"*/*":{"schema":{"$ref":"#/components/schemas/NotebookDetailDto"}}}},"401":{"description":"No/invalid JWT","content":{"*/*":{"schema":{"$ref":"#/components/schemas/NotebookDetailDto"}}}},"404":{"description":"Notebook not found or owned by someone else","content":{"*/*":{"schema":{"$ref":"#/components/schemas/NotebookDetailDto"}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.learning.read"]}]}},"/learning/terms":{"get":{"tags":["LEARNING: Academic Terms"],"summary":"List academic terms","description":"All academic terms of EVERY calendar, ordered by academic year, term number and calendar. programCode names the calendar a row belongs to — «ALL» is the university-wide one, anything else is an educational programme code; studyLevel names the STUDY LEVEL a row belongs to — «ALL» or BACHELOR/MASTER/MBA/DOCTORATE. Оба «ALL» = общая строка вуза. Term boundaries include the exam window; retake window is null when the next term is not entered yet. enrollmentWindow*/addDropWindow* carry a TIME OF DAY (ISO date-time, Asia/Almaty), the exam/retake windows are dates.","operationId":"learning_listTerms","responses":{"200":{"description":"Academic terms (possibly empty)","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/AcademicTermDto"}}}}},"401":{"description":"No/invalid JWT","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/AcademicTermDto"}}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.learning.read"]}]}},"/learning/terms/current":{"get":{"tags":["LEARNING: Academic Terms"],"summary":"Current academic term","description":"The term whose start..end range (exam window included) covers today's date in the university timezone (Asia/Almaty, UTC+5). У преподавателя, администратора и студента без учебной карточки календарь общий. Правило выбора ТРЁХСТУПЕНЧАТОЕ: своя строка программы; если у программы нет НИ ОДНОГО периода на этот учебный год — строка её УРОВНЯ обучения; если и у уровня нет ни одного периода этого года — общая строка вуза; иначе 404. Дыра в собственном календаре НЕ заполняется чужими датами.","operationId":"learning_currentTerm","responses":{"200":{"description":"Current academic term of the caller's calendar","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AcademicTermDto"}}}},"404":{"description":"No term of that calendar covers the current date (inter-term break or calendar not entered)","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AcademicTermDto"}}}},"401":{"description":"No/invalid JWT","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AcademicTermDto"}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.learning.read"]}]}},"/learning/teacher/students/at-risk":{"get":{"tags":["LEARNING: Students needing support (teacher)"],"summary":"Студенты преподавателя, которым нужна поддержка","description":"Детерминированный список поверх активных наблюдений «Ая заметила» — не новая оценка и никогда не модель. Уровень риска: HIGH — есть активное наблюдение уровня HIGH; MEDIUM — два и более активных ИЛИ одно уровня MEDIUM; одиночное лёгкое наблюдение в список не попадает. В строке: ФИО, программа, дисциплины (свои), уровень, причины человеческим языком на ru/kk/en и рекомендованное действие. basis = COURSE | MENTOR | COURSE_AND_MENTOR объясняет, на каком основании студент здесь. Честная пустота: считается по реальным наблюдениям, ничего не выдумывается. Дисклеймер «ИИ выявляет ранние сигналы, решение принимает преподаватель» рисует фронт.","operationId":"learning_myStudents","parameters":[{"name":"courseId","in":"query","description":"Сузить до одной СВОЕЙ дисциплины","required":false,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Студенты, которым нужна поддержка (может быть пусто)","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/TeacherAtRiskStudentDto"}}}}},"401":{"description":"Нет/невалидный JWT","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/TeacherAtRiskStudentDto"}}}}},"403":{"content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/TeacherAtRiskStudentDto"}}}}},"404":{"description":"Указанной дисциплины нет","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/TeacherAtRiskStudentDto"}}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.learning.read"]}]}},"/learning/teacher/courses/{id}/participant-candidates":{"get":{"tags":["LEARNING: Course participants (manual roster)"],"summary":"Найти студентов для добавления (кабинет преподавателя)","operationId":"learning_teacherCandidates","parameters":[{"name":"id","in":"path","description":"Id открытого курса","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"q","in":"query","description":"ФИО или его часть, от трёх знаков","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"Кандидаты","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/ParticipantCandidateDto"}}}}},"400":{"description":"Курс — не открытый","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/ParticipantCandidateDto"}}}}},"403":{"description":"Вызывающий — не ведущий курса","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/ParticipantCandidateDto"}}}}},"404":{"description":"Курс не найден","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/ParticipantCandidateDto"}}}}},"503":{"description":"Справочник студентов недоступен","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/ParticipantCandidateDto"}}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.learning.read"]}]}},"/learning/teacher/courses/{courseId}/fill":{"get":{"tags":["LEARNING: Teacher - course fill"],"summary":"Чек-лист наполненности дисциплины","description":"Шесть пунктов с подписями на трёх языках и признаком выполнения, плюс «готово N из 6» и доля в процентах. Подписи приезжают С СЕРВЕРА — на фронте их хардкодить нельзя.\nПравила пунктов те же, что в сводке руководства (CourseFillRules), но два из них стоит знать: раздел засчитывается, ТОЛЬКО если в нём есть хотя бы один элемент (дисциплина рождается с десятью пустыми), а задания-черновики, выпущенные при рождении курса под компоненты схемы оценивания, в пункт «работы» не идут. Пустая новорождённая дисциплина поэтому честно показывает 0 из 6, а не 50 %.\nДоступно и на дисциплине, снятой с обращения, и на закрытом учебном годе — чек-лист описывает содержимое, а не право его менять.\nЧисло пунктов брать из itemsTotal.","operationId":"learning_fill","parameters":[{"name":"courseId","in":"path","description":"Идентификатор дисциплины","required":true,"schema":{"type":"string","format":"uuid"},"example":"3f6f4c1e-2c1a-4c5e-9b1e-1a2b3c4d5e6f"}],"responses":{"200":{"description":"Чек-лист дисциплины","content":{"*/*":{"schema":{"$ref":"#/components/schemas/CourseFillDto"}}}},"401":{"description":"Нет токена или он невалиден","content":{"*/*":{"schema":{"$ref":"#/components/schemas/CourseFillDto"}}}},"403":{"content":{"*/*":{"schema":{"$ref":"#/components/schemas/CourseFillDto"}}}},"404":{"description":"Дисциплина не найдена","content":{"*/*":{"schema":{"$ref":"#/components/schemas/CourseFillDto"}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.learning.read"]}]}},"/learning/submissions/{id}/history":{"get":{"tags":["LEARNING: Submissions"],"summary":"History of actions on a submission (student view)","description":"Grade drafts and the AI review are never part of it. A submission sent before the history existed gets a synthesized SUBMITTED from its submittedAt. The current files of the work open from GET /submissions/{id} as before.","operationId":"learning_history","parameters":[{"name":"id","in":"path","description":"Submission id","required":true,"schema":{"type":"string","format":"uuid"},"example":"3f6f4c1e-2c1a-4c5e-9b1e-1a2b3c4d5e6f"}],"responses":{"200":{"description":"Events, oldest first","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/SubmissionHistoryEventDto"}}}}},"401":{"description":"No/invalid JWT","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/SubmissionHistoryEventDto"}}}}},"403":{"description":"Submission belongs to another learner","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/SubmissionHistoryEventDto"}}}}},"404":{"description":"Submission not found","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/SubmissionHistoryEventDto"}}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.learning.read"]}]}},"/learning/spaces/{spaceId}/sources/{sourceId}/file":{"get":{"tags":["LEARNING: Study space source files"],"summary":"Download / stream the file of a material copy in a study space","description":"Streams the bytes of the file this space source points at. The presigned storage URL never leaves the docker network — the caller gets a stream, not an address (a signed URL is a bearer pass: whoever it reaches opens the file, with no session). `Content-Type` and `Content-Disposition` (RFC 6266, the original file name) are the SAME headers the file service would emit — they are signed into the storage URL by that very service. `Range` is carried both ways (206 + `Content-Range`, `Accept-Ranges: bytes`, 416 past the end), so a lecture recording seeks here as it does anywhere else. Nothing is cached and no verdict is stored.","operationId":"learning_serve","parameters":[{"name":"spaceId","in":"path","description":"Study space id","required":true,"schema":{"type":"string","format":"uuid"},"example":"1f0f4c1e-2c1a-4c5e-9b1e-1a2b3c4d5e6f"},{"name":"sourceId","in":"path","description":"Study source id (a row of the space, materialId not null)","required":true,"schema":{"type":"string","format":"uuid"},"example":"a0fcc892-4e5a-465c-8a98-81efd9e484a3"},{"name":"Range","in":"header","description":"Standard HTTP Range header, carried through to the storage","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"The whole file, streamed","content":{"*/*":{"schema":{"$ref":"#/components/schemas/StreamingResponseBody"}}}},"206":{"description":"The requested byte range","content":{"*/*":{"schema":{"$ref":"#/components/schemas/StreamingResponseBody"}}}},"400":{"description":"The source is not a copy of a course material (a learner upload, a link or a text) — its bytes come from the file service, not from here","content":{"*/*":{"schema":{"$ref":"#/components/schemas/StreamingResponseBody"}}}},"401":{"description":"No/invalid JWT","content":{"*/*":{"schema":{"$ref":"#/components/schemas/StreamingResponseBody"}}}},"404":{"description":"Unknown or foreign space; unknown source; the source has no file; the copied material is gone, out of scope, a DRAFT, out of its window or its condition is not met; the file is no longer attached to the element (all indistinguishable on purpose)","content":{"*/*":{"schema":{"$ref":"#/components/schemas/StreamingResponseBody"}}}},"416":{"description":"The requested range lies past the end of the file","content":{"*/*":{"schema":{"$ref":"#/components/schemas/StreamingResponseBody"}}}},"502":{"description":"The storage is unavailable","content":{"*/*":{"schema":{"$ref":"#/components/schemas/StreamingResponseBody"}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.learning.read"]}]}},"/learning/spaces/{spaceId}/artifacts":{"get":{"tags":["LEARNING: Study notebook studio"],"summary":"List Studio artifacts","description":"Studio artifacts of the notebook, newest first, without payload and without the per-source auto materials. legacy = an old artifact without payload.v = 2 (simple viewer).","operationId":"learning_list_14","parameters":[{"name":"spaceId","in":"path","description":"Notebook id","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Artifacts","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/StudyArtifactSummaryDto"}}}}},"401":{"description":"No/invalid JWT","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/StudyArtifactSummaryDto"}}}}},"404":{"description":"Notebook not found or owned by someone else","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/StudyArtifactSummaryDto"}}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.learning.read"]}]}},"/learning/spaces/{id}/course-picker/{courseId}":{"get":{"tags":["LEARNING: Study notebooks"],"summary":"Materials of a discipline for «Из курсов»","description":"Step 2 of the picker: materials and lesson recordings of the discipline open to the caller RIGHT NOW (the same predicate as the Aya course corpus: published, inside the effective availability window, access conditions met; an open course that has not started yet gives nothing), grouped by course sections in structure order. Announcements are never offered. group = RECORDING for VIDEO, MATERIAL otherwise; inNotebook = a copy already lies in THIS notebook.","operationId":"learning_coursePickerMaterials","parameters":[{"name":"id","in":"path","description":"Notebook id","required":true,"schema":{"type":"string","format":"uuid"},"example":"3f6f4c1e-2c1a-4c5e-9b1e-1a2b3c4d5e6f"},{"name":"courseId","in":"path","description":"Learning-side course id","required":true,"schema":{"type":"string","format":"uuid"},"example":"7c9e6679-7425-40de-944b-e07fc1f90ae7"}],"responses":{"200":{"description":"Sections with items","content":{"*/*":{"schema":{"$ref":"#/components/schemas/CoursePickerDto"}}}},"401":{"description":"No/invalid JWT","content":{"*/*":{"schema":{"$ref":"#/components/schemas/CoursePickerDto"}}}},"404":{"description":"Notebook foreign/unknown, or discipline unreadable/unknown","content":{"*/*":{"schema":{"$ref":"#/components/schemas/CoursePickerDto"}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.learning.read"]}]}},"/learning/spaces/course-picker":{"get":{"tags":["LEARNING: Study notebooks"],"summary":"Disciplines for «Из курсов»","description":"Step 1 of the «Из курсов» picker: the student's disciplines with an enrollment not WITHDRAWN that are visible to students — running, finished and failed (their materials stay readable, D4). Sorted: ACTIVE enrollments first, then by title. materialCount / recordingCount = what step 2 offers this student right now (the same predicate: published, open to him, announcements excluded; recordings = VIDEO). Empty without a Learner row.","operationId":"learning_coursePicker","responses":{"200":{"description":"Pickable disciplines","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/CoursePickerCourseDto"}}}}},"401":{"description":"No/invalid JWT","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/CoursePickerCourseDto"}}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.learning.read"]}]}},"/learning/skills/search":{"get":{"tags":["LEARNING: Skill search (student)"],"summary":"Найти навык","description":"Подстрока в коде или названии на любом из трёх языков; навыки на модерации не возвращаются; порядок — по коду. Запрос короче двух знаков — пустой список, а не отказ: поле дотягивает буквы на лету. limit — 1..50, по умолчанию 20; больше 50 обрезается до 50.","operationId":"learning_search","parameters":[{"name":"query","in":"query","description":"Часть кода или названия навыка","required":false,"schema":{"type":"string"},"example":"py"},{"name":"limit","in":"query","description":"Сколько навыков вернуть, 1..50","required":false,"schema":{"type":"integer","format":"int32"},"example":20}],"responses":{"200":{"description":"Найденные навыки (может быть пусто)","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/SkillOptionDto"}}}}},"401":{"description":"Нет или невалидный JWT","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/SkillOptionDto"}}}}},"403":{"content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/SkillOptionDto"}}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.learning.read"]}]}},"/learning/resume/projects":{"get":{"tags":["LEARNING: Resume (student)"],"summary":"Мои проекты в резюме","description":"Одна строка на проект модуля «Проекты»: CONFIRMED — есть живой подтверждённый вклад; IN_PROGRESS — студент в команде идущего проекта, подтверждений нет. Список полный: в нём скрытые проекты и отозванные вклады (иначе спрятанное нечем вернуть). Черновик, приостановленный и завершённый без подтверждений проект сюда не входят — на лист они не попадут. 6).","operationId":"learning_projects","responses":{"200":{"description":"Проекты (может быть пусто)","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/MyResumeProjectDto"}}}}},"401":{"description":"Нет или невалидный JWT","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/MyResumeProjectDto"}}}}},"403":{"content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/MyResumeProjectDto"}}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.learning.read"]}]}},"/learning/resume/preview":{"get":{"tags":["LEARNING: Resume (student)"],"summary":"Моё резюме в редакторе","description":"Тот же PublicResumeDto, из которого собираются публичная страница и PDF, но со ВСЕМИ областями цели, включая 0 % (редактор показывает их все). Ссылку не включает. Прежние ключи skills/courses/sections — всегда пустые списки (один выпуск), academic нет. У подтверждённого проекта в achievements[] — confirmedBy: ФИО руководителя проекта из последнего снимка состава, иначе подтвердившего последний вклад; null — неизвестно.","operationId":"learning_preview","responses":{"200":{"description":"Агрегат резюме (может быть пустым)","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PublicResumeDto"}}}},"401":{"description":"Нет или невалидный JWT","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PublicResumeDto"}}}},"403":{"content":{"*/*":{"schema":{"$ref":"#/components/schemas/PublicResumeDto"}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.learning.read"]}]}},"/learning/resume/pdf":{"get":{"tags":["LEARNING: Resume (student)"],"summary":"Скачать моё резюме в PDF","description":"Тот же лист, что публичная страница: области цели с 0 % не печатаются, файлов сертификатов нет. Портрет вшивается при сборке (подписанная ссылка в документ не попадает); слишком большой или недоступный портрет пропускается, PDF собирается.","operationId":"learning_exportPdf","responses":{"200":{"description":"PDF резюме","content":{"*/*":{"schema":{"type":"string","format":"byte"}}}},"403":{"content":{"*/*":{"schema":{"type":"string","format":"byte"}}}},"502":{"description":"Сервис рендера недоступен","content":{"*/*":{"schema":{"type":"string","format":"byte"}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.learning.read"]}]}},"/learning/quizzes":{"get":{"tags":["LEARNING: Quizzes"],"summary":"Quizzes of a course (student cards)","description":"Quiz summaries of one course for the program tree (case 4.11): title, moduleId, question count, componentId and the CALLER's own attempt state (attempted / bestScorePct / lastAttemptAt). componentId is the assessment component the quiz feeds — null for a self-check quiz (allowed by design, G18) — and it matches the componentId of GET /quizzes/{id}. STUD-42: a CLOSED gradesheet refuses an attempt ONLY for a component-bound quiz, so this is the field the cabinet greys a row out by; without it a self-check quiz was greyed out together with the graded ones. DRAFT quizzes are hidden from students (managers see them with status DRAFT). availableFrom/availableUntil are on every row for the «доступно до …» label. A quiz whose `availableUntil` has passed STAYS in the list with `windowClosed = true`: the card is marked «закрыт, приём завершён», `canAttempt` and `hasOpenAttempt` / `openAttemptId` are forced FALSE/null (start answers 400 there, so offering «Начать» or «Продолжить» would promise a refusal), and the student's own `attempted` / `bestScorePct` / `lastAttemptAt` stay visible. Hiding it also hid the only way into his own attempt history (GET /learning/quizzes/{id}/attempts/me), which the same owner decision keeps open. A student who never took the quiz sees the same marked card without a result — accepted deliberately. NOTHING of the CONTENT comes with that card: GET /learning/quizzes/{id} is still 404 for a closed quiz. bestScorePct counts only COMPLETED / REVIEWED attempts: one waiting for an essay carries a PARTIAL score and is not a result yet. While a session is open `canAttempt` is false (a second attempt cannot begin before the first is closed) and `hasOpenAttempt` / `openAttemptId` say so — the card renders «Продолжить», and the client must not infer it from the two numbers, in which «0 left» and «a session is running» look identical. It used to be «newest first»; the tree shows the course the way it is taught.","operationId":"learning_list_15","parameters":[{"name":"courseId","in":"query","description":"Course id","required":true,"schema":{"type":"string","format":"uuid"},"example":"8a7d0c54-5d43-4485-97f9-f9e149c5dc41"}],"responses":{"200":{"description":"Quiz summaries in structural order","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/QuizSummaryDto"}}}}},"401":{"description":"No/invalid JWT","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/QuizSummaryDto"}}}}},"403":{"description":"Course is out of the caller's scope","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/QuizSummaryDto"}}}}},"404":{"description":"Course not found","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/QuizSummaryDto"}}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.learning.read"]}]}},"/learning/quizzes/{id}":{"get":{"tags":["LEARNING: Quizzes"],"summary":"Quiz card (student) / quiz with questions (teacher)","description":"`questions` is null and `questionsIncluded` is false; what comes back is the CARD the confirmation screen is built from (owner decision 18): `title`, `questionCount`, `totalPoints`, `attemptsAllowed` (0 = unlimited) / `attemptsUsed` / `canAttempt`, `showReview` and the availability window. While questions arrived before the start, «the clock runs on the server» and «starting spends an attempt» meant nothing — the whole quiz could be read, prepared for, and only then started. A student gets the questions from POST /learning/quizzes/{id}/attempts/start. Its `index` is the DISPLAY POSITION inside this very list (0..n-1 in order), NOT the author's pair number: the author's number of a right part IS the correct answer for the left part of the same number, so handing it out would hand out the answer. The attempt sends the display position back and the server translates it. `canAttempt` is false while a session is open (the open session is already counted in `attemptsUsed`). Of the two clocks the EARLIER one wins (owner decision 19), and the SERVER says which — so the confirmation screen can be honest («у вас будет 10 минут, а не 30 — тест закрывается в 18:00») instead of re-deriving the reason from two dates. A tie (the limit runs out exactly at the end of the window) is reported as TIME_LIMIT — the window cut nothing. A forecast on an open session would be a lie (28 minutes into a 30-minute attempt it would again promise 30), so this card is safe to render a countdown from in both states. availableUntil is returned so the page can show how long is left — an attempt submitted after it is refused with a 400, not with a 404.","operationId":"learning_getQuiz","parameters":[{"name":"id","in":"path","description":"Quiz id","required":true,"schema":{"type":"string","format":"uuid"},"example":"3f6f4c1e-2c1a-4c5e-9b1e-1a2b3c4d5e6f"}],"responses":{"200":{"description":"Quiz card (student, questions omitted) or quiz with questions (manager)","content":{"*/*":{"schema":{"$ref":"#/components/schemas/QuizDto"}}}},"401":{"description":"No/invalid JWT","content":{"*/*":{"schema":{"$ref":"#/components/schemas/QuizDto"}}}},"403":{"description":"Course is out of the caller's scope","content":{"*/*":{"schema":{"$ref":"#/components/schemas/QuizDto"}}}},"404":{"description":"Quiz not found (or DRAFT / out-of-window for a student)","content":{"*/*":{"schema":{"$ref":"#/components/schemas/QuizDto"}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.learning.read"]}]}},"/learning/quizzes/{id}/attempts/me":{"get":{"tags":["LEARNING: Quizzes"],"summary":"My attempts on this quiz (history)","description":"CAMPUS-06 (owner decision 20): EVERY attempt this student has made on this quiz — date, score and which one COUNTS TOWARDS THE GRADE. This is the block under the quiz card; the full breakdown of a single row is still GET /learning/quiz-attempts/{id}. There is no other entry point by design: the grades feed (GET /learning/gradebook/me/quiz-attempts) carries the same `quizId` but belongs to a different screen. wrongly. Rows are OLDEST FIRST — a chronicle, not a news feed. The rule is «the BEST of the COMPLETED/REVIEWED attempts» — an attempt still waiting for its essay carries a PARTIAL score and can never be the graded one; a tie goes to the EARLIER attempt so the mark does not jump between reads. EXACTLY ONE row carries true, or none at all while nothing is finished. Its `deadlineAt` says when it closes. Reading this endpoint SETTLES the caller's expired sessions on this quiz first, so a session whose time ran out shows up as its RESULT, not as «running». A quiz whose `availableUntil` has passed still answers 200 here — the student keeps seeing his own dates, scores, numbers and the graded mark. What closes with the window is the BREAKDOWN, not the record: `showReview` comes back FALSE for such a quiz (GET /learning/quiz-attempts/{id} is 404 there, so offering the way in would promise a refusal), and `canAttempt` is FALSE too (the start endpoint answers 400 «Тест закрыт»). The other end of the window is unchanged: a quiz that has NOT opened yet is still 404, exactly like a DRAFT — its existence was never disclosed. into a confirmation that the removed route exists. Their list is the admin one.","operationId":"learning_myAttempts","parameters":[{"name":"id","in":"path","description":"Quiz id","required":true,"schema":{"type":"string","format":"uuid"},"example":"3f6f4c1e-2c1a-4c5e-9b1e-1a2b3c4d5e6f"}],"responses":{"200":{"description":"The caller's own attempts on this quiz, oldest first (possibly empty)","content":{"*/*":{"schema":{"$ref":"#/components/schemas/QuizAttemptHistoryDto"}}}},"401":{"description":"No/invalid JWT","content":{"*/*":{"schema":{"$ref":"#/components/schemas/QuizAttemptHistoryDto"}}}},"403":{"description":"Course is out of the caller's scope","content":{"*/*":{"schema":{"$ref":"#/components/schemas/QuizAttemptHistoryDto"}}}},"404":{"description":"Quiz not found, or — for a student — it is a DRAFT / has not opened yet. A quiz whose window has CLOSED is NOT 404 here","content":{"*/*":{"schema":{"$ref":"#/components/schemas/QuizAttemptHistoryDto"}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.learning.read"]}]}},"/learning/quiz-attempts/{id}":{"get":{"tags":["LEARNING: Quizzes"],"summary":"One quiz attempt with its breakdown","description":"403 is left for the one case that discloses nothing — the caller's OWN attempt on a course that is no longer his (he was withdrawn while the result screen was open). `review` is empty when the quiz has `showReview = false`; the visibility of the QUIZ still comes first and it is the SAME rule the card and the history use — a student gets 404 here, breakdown included, when the quiz is a DRAFT (М6, 2026-08-11: this route used to check the window ONLY, so on an unpublished quiz the history was 404 while the full breakdown opened by direct link), has not opened yet, or is past its window. Numbers are the FROZEN ones of that attempt: editing the quiz afterwards never changes them. For an AWAITING_REVIEW attempt the numbers are the PARTIAL (auto) score and `awaitingReviewCount` says how many answers still wait for the teacher. Someone else's unfinished session stays a 404: the visibility gates run first, so a 400 could never confirm that it exists. For such an attempt `attemptedAt` is the DEADLINE, not the moment anybody happened to touch the row. And reading an EXPIRED session through this route auto-submits it first, so it answers with the result instead of «ещё не отправлена».","operationId":"learning_getAttempt","parameters":[{"name":"id","in":"path","description":"Quiz attempt id","required":true,"schema":{"type":"string","format":"uuid"},"example":"b1b2c3d4-e5f6-4a7b-8c9d-0e1f2a3b4c5d"}],"responses":{"200":{"description":"Attempt with its per-question breakdown","content":{"*/*":{"schema":{"$ref":"#/components/schemas/QuizAttemptDto"}}}},"400":{"description":"The attempt has not been submitted yet","content":{"*/*":{"schema":{"$ref":"#/components/schemas/QuizAttemptDto"}}}},"401":{"description":"No/invalid JWT","content":{"*/*":{"schema":{"$ref":"#/components/schemas/QuizAttemptDto"}}}},"403":{"description":"The caller's OWN attempt on a course that is out of his scope (withdrawn) — someone else's attempt is 404, not this","content":{"*/*":{"schema":{"$ref":"#/components/schemas/QuizAttemptDto"}}}},"404":{"description":"Attempt not found or belongs to somebody else — ONE answer for both (existence is not disclosed); also the quiz is invisible to a student: a DRAFT, not open yet, or past its availability window","content":{"*/*":{"schema":{"$ref":"#/components/schemas/QuizAttemptDto"}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.learning.read"]}]}},"/learning/public/transcript-verification/{token}":{"get":{"tags":["LEARNING: Transcript verification (public)"],"summary":"Проверить транскрипт по токену из QR","description":"Отдаёт только номер документа, ФИО, образовательную программу, дату формирования и valid=true. Оценок и ИИН нет. Доступ: публичный.","operationId":"learning_verify_1","parameters":[{"name":"token","in":"path","description":"Токен из QR-кода","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Документ выдан системой","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PublicTranscriptVerificationDto"}}}},"404":{"description":"Неизвестный токен","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PublicTranscriptVerificationDto"}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.learning.read"]}]}},"/learning/public/resume/{token}":{"get":{"tags":["LEARNING: Resume (public)"],"summary":"Get a public resume by its share token","description":"Resolves the ACTIVE share by its token and returns the resume aggregate — the SAME body the PDF is built from. 7); confirmed/total still count every goal skill. A confirmed project row carries confirmedBy — the project supervisor's name for «Confirmed by the project supervisor · {name}» (null when unknown). Legacy keys skills / courses / sections are always empty lists for one release. A revoked/unknown token is a 404.","operationId":"learning_get_10","parameters":[{"name":"token","in":"path","description":"Public resume share token","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"The public resume aggregate","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PublicResumeDto"}}}},"404":{"description":"Unknown or revoked token","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PublicResumeDto"}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.learning.read"]}]}},"/learning/public/resume/{token}/photo":{"get":{"tags":["LEARNING: Resume (public)"],"summary":"The student's photo, scoped to the share token","description":"Streams the portrait of the student this token resolves to. No auth: the token IS the authorisation. 4: the photo is always published when there is one — a revoked token and a student without a photo are both a 404 and deliberately indistinguishable. Served inline (an <img> source), not as an attachment. Anything else the storage reports — image/svg+xml above all, but also HTML or a document uploaded into the profile under the guise of a photo — is refused with a 404 and never reaches the browser. This route is the only public one that asks the browser to RENDER bytes (inline) from a type the storage supplies, so without the allow-list a public address on the api domain would serve an executable document. Both public streams also answer with X-Content-Type-Options: nosniff, so the browser may not guess a type past the allow-list. The screen falls back to initials on a 404.","operationId":"learning_photo","parameters":[{"name":"token","in":"path","description":"Public resume share token","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"The photo bytes (a raster image)","content":{"*/*":{"schema":{"$ref":"#/components/schemas/StreamingResponseBody"}}}},"404":{"description":"Unknown/revoked token, no photo, the stored object is not a raster image, or it is gone from storage — deliberately indistinguishable","content":{"*/*":{"schema":{"$ref":"#/components/schemas/StreamingResponseBody"}}}},"502":{"description":"Storage did not answer","content":{"*/*":{"schema":{"$ref":"#/components/schemas/StreamingResponseBody"}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.learning.read"]}]}},"/learning/public/resume/{token}/file/{fileId}":{"get":{"tags":["LEARNING: Resume (public)"],"summary":"Download an attachment of a portfolio work, scoped to the share token","description":"Streams the bytes of one file the student attached to a portfolio work. No auth: the share token IS the authorisation AND the scope — the id must be the row id of an attachment belonging to a work of the learner THIS token resolves to. 8). A revoked token 404s the same way, so revoking the link kills the files with it. `Range` is honoured (206 + Content-Range); the response is always an attachment named after the file the student uploaded, with X-Content-Type-Options: nosniff. No presigned storage URL ever leaves the service.","operationId":"learning_file","parameters":[{"name":"token","in":"path","description":"Public resume share token","required":true,"schema":{"type":"string"}},{"name":"fileId","in":"path","description":"Attachment row id, as carried by the public resume","required":true,"schema":{"type":"string"}},{"name":"Range","in":"header","description":"Optional HTTP Range header","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"The file bytes","content":{"*/*":{"schema":{"$ref":"#/components/schemas/StreamingResponseBody"}}}},"206":{"description":"Partial content for a Range request","content":{"*/*":{"schema":{"$ref":"#/components/schemas/StreamingResponseBody"}}}},"404":{"description":"Unknown/revoked token, foreign file id, a file not uploaded by the resume owner (rows bound before the upload check), or the object is gone from storage — deliberately indistinguishable","content":{"*/*":{"schema":{"$ref":"#/components/schemas/StreamingResponseBody"}}}},"416":{"description":"Range outside the file","content":{"*/*":{"schema":{"$ref":"#/components/schemas/StreamingResponseBody"}}}},"502":{"description":"Storage did not answer","content":{"*/*":{"schema":{"$ref":"#/components/schemas/StreamingResponseBody"}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.learning.read"]}]}},"/learning/public/gradesheet-verification/{token}":{"get":{"tags":["LEARNING: Gradesheet verification (public)"],"summary":"Verify a signed vedomost by its public token","description":"404 for an unknown token.","operationId":"learning_verify_2","parameters":[{"name":"token","in":"path","description":"Public verification token","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Verification result (metadata + validity + masked signer)","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PublicGradesheetVerificationDto"}}}},"404":{"description":"Unknown token","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PublicGradesheetVerificationDto"}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.learning.read"]}]}},"/learning/public/course-certificate-verification/{token}":{"get":{"tags":["LEARNING: Open course certificate verification (public)"],"summary":"Проверить сертификат по токену из QR","description":"status VALID — сертификат действителен; REVOKED — отозван (итоговая оценка пересмотрена в незачёт). Балл не отдаётся. Доступ: публичный.","operationId":"learning_verify_3","parameters":[{"name":"token","in":"path","description":"Токен из QR-кода","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Сертификат найден","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PublicCourseCertificateVerificationDto"}}}},"404":{"description":"Неизвестный токен","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PublicCourseCertificateVerificationDto"}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.learning.read"]}]}},"/learning/me/week-plan":{"get":{"tags":["LEARNING: Student plan"],"summary":"План недели","description":"Занятия недели (из расписания), сроки сдачи, попадающие в неделю, и незакрытые учебные шаги — одним ответом. Каждый пункт несёт признак «сделано/нет», ссылку в кабинет и фразу на трёх языках (язык выбирает кабинет — тот же приём, что у ленты «Ая заметила»).\nКабинет добавляет их из своего чтения GET /api/users/me/onboarding и GET /api/users/mentors.\nПравила вхождения:\n• ASSIGNMENT_DUE — срок работы попадает в неделю и дисциплина в активной записи (закрытое окно приёма строку НЕ убирает, оно меняет подпись);\n• PLACEMENT — есть хоть одно направление диагностики, которое можно начать (пустой банк у всех направлений — пункта нет ни у кого);\n• CAREER_GOAL — всегда;\n• PREP_BLOCK — вместе с PLACEMENT, если настроено хоть одно соответствие «направление → что подтянуть». До результатов диагностики пункт говорит, что появится после неё; после подбора — несёт count материалов и ссылку в маршрут и закрывается (done = true), когда студент открыл блоки на маршруте (GET /api/learning/me/prep-plan); если диагностика пройдена и подтягивать нечего — приходит с done = true сразу.\nИначе один чек-лист сообщал бы «по нему подобраны подготовительные блоки» и «подтягивать нечего» одновременно.\nНичего не выдумывается: нет занятий, сроков, доступной диагностики или настроенных подготовительных блоков — соответствующих пунктов в ответе просто нет, и нет их сразу у всех, а не выборочно.","operationId":"learning_weekPlan","parameters":[{"name":"weekOffset","in":"query","description":"Смещение недели от текущей: 0 — текущая, 1 — следующая. Ограничено ±8 (дальше расписание не материализует даты)","required":false,"schema":{"type":"integer","format":"int32"},"example":0},{"name":"locale","in":"query","description":"Язык интерфейса: ru | kk | en","required":false,"schema":{"type":"string"},"example":"ru"}],"responses":{"200":{"description":"План недели (возможно, короткий)","content":{"*/*":{"schema":{"$ref":"#/components/schemas/WeekPlanDto"}}}},"401":{"description":"Нет/невалидный JWT","content":{"*/*":{"schema":{"$ref":"#/components/schemas/WeekPlanDto"}}}},"403":{"content":{"*/*":{"schema":{"$ref":"#/components/schemas/WeekPlanDto"}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.learning.read"]}]}},"/learning/me/study-plan":{"get":{"tags":["LEARNING: Student study plan (IUP)"],"summary":"Мой индивидуальный учебный план на год","description":"Шапка, режим (NO_ELECTIVES / FALLBACK / PENDING / TRAJECTORY / NOT_STARTED / NO_PLAN), состояние выбора по окнам записи и добора (OPEN / NOT_OPEN_YET / CLOSED / WINDOW_UNKNOWN / LOCKED / NOT_APPLICABLE), выбор, триместры со строками и итогами кредитов, задолженности прошлых лет. Строки — той же сборкой, что транскрипт: триместры раньше effectiveFromTerm — факт записи. Без academicYear — год ИУП «сейчас» (год с открытым окном, иначе год идущего периода, иначе год по дате). history у студента пуст.","operationId":"learning_myStudyPlan","parameters":[{"name":"academicYear","in":"query","description":"Учебный год; пусто — год ИУП «сейчас»","required":false,"schema":{"type":"string"},"example":"2026-2027"}],"responses":{"200":{"description":"ИУП на год","content":{"*/*":{"schema":{"$ref":"#/components/schemas/StudyPlanDto"}}}},"400":{"description":"ACADEMIC_YEAR_INVALID — год не в виде 2026-2027","content":{"*/*":{"schema":{"$ref":"#/components/schemas/StudyPlanDto"}}}},"401":{"description":"Нет или неверный JWT","content":{"*/*":{"schema":{"$ref":"#/components/schemas/StudyPlanDto"}}}},"403":{"content":{"*/*":{"schema":{"$ref":"#/components/schemas/StudyPlanDto"}}}},"404":{"description":"LEARNER_NOT_FOUND — нет учебной карточки","content":{"*/*":{"schema":{"$ref":"#/components/schemas/StudyPlanDto"}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.learning.read"]}]}},"/learning/me/study-plan/trajectories":{"get":{"tags":["LEARNING: Student study plan (IUP)"],"summary":"Траектории моего курса","description":"Опубликованные траектории программы студента для его курса в году: дисциплины года по триместрам с кредитами (обязательные + по одной из каждого направления), итог кредитов, пометки «не освоен пререквизит» (не запрет, К-6а). Прошедшие триместры (fact = true) — не план траектории, а обязательные и записанные дисциплины года студента (fromTrajectory = false); totalCredits = они + план траектории остальных триместров. Пусто вне режимов PENDING и TRAJECTORY.","operationId":"learning_myTrajectories","parameters":[{"name":"academicYear","in":"query","description":"Учебный год; пусто — год ИУП «сейчас»","required":false,"schema":{"type":"string"},"example":"2026-2027"}],"responses":{"200":{"description":"Список (возможно пустой)","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/TrajectoryOptionDto"}}}}},"400":{"description":"ACADEMIC_YEAR_INVALID","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/TrajectoryOptionDto"}}}}},"401":{"description":"Нет или неверный JWT","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/TrajectoryOptionDto"}}}}},"403":{"content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/TrajectoryOptionDto"}}}}},"404":{"description":"LEARNER_NOT_FOUND","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/TrajectoryOptionDto"}}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.learning.read"]}]}},"/learning/me/study-plan/pdf":{"get":{"tags":["LEARNING: Student study plan (IUP)"],"summary":"PDF моего ИУП","description":"Простая выгрузка плана на год: шапка, траектория, триместры «Код · Дисциплина · Компонент · Кредиты · Статус», итоги, задолженности прошлых лет, момент формирования. Без подписи, номера, реестра и QR; в базу ничего не пишется.","operationId":"learning_myStudyPlanPdf","parameters":[{"name":"academicYear","in":"query","description":"Учебный год; пусто — год ИУП «сейчас»","required":false,"schema":{"type":"string"},"example":"2026-2027"},{"name":"lang","in":"query","description":"Язык документа: ru (по умолчанию), kk, en","required":false,"schema":{"type":"string"},"example":"ru"}],"responses":{"200":{"description":"application/pdf, inline; filename=iup-<код>-<год>.pdf","content":{"*/*":{"schema":{"type":"string","format":"byte"}}}},"400":{"description":"ACADEMIC_YEAR_INVALID или в карточке нет ФИО","content":{"*/*":{"schema":{"type":"string","format":"byte"}}}},"401":{"description":"Нет или неверный JWT","content":{"*/*":{"schema":{"type":"string","format":"byte"}}}},"403":{"content":{"*/*":{"schema":{"type":"string","format":"byte"}}}},"404":{"description":"LEARNER_NOT_FOUND","content":{"*/*":{"schema":{"type":"string","format":"byte"}}}},"502":{"description":"Сервис отрисовки PDF недоступен","content":{"*/*":{"schema":{"type":"string","format":"byte"}}}},"504":{"description":"Отрисовка не уложилась в срок","content":{"*/*":{"schema":{"type":"string","format":"byte"}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.learning.read"]}]}},"/learning/me/semester/summary":{"get":{"tags":["LEARNING: Semester summary (student)"],"summary":"Итоги периода одним ответом","description":"GPA периода и накопительный, кредиты (учтённые в среднем и зачтённые), закрытые дисциплины, посещаемость за окно семестра, навыки, по которым за период появились свидетельства (включая входную диагностику), карточки «Ая заметила» этого периода и сохранённая рефлексия.\nПериод задаётся парой academicYear + termNo; без них берётся ТЕКУЩИЙ по академическому календарю. Календарь не заведён и текущий период определить нечем — 400 (это отсутствие периода, а не пустые итоги). Период без данных — законный ответ: нули и пустые списки.","operationId":"learning_summary","parameters":[{"name":"academicYear","in":"query","description":"Учебный год","required":false,"schema":{"type":"string"},"example":"2026-2027"},{"name":"termNo","in":"query","description":"Номер триместра 1..3","required":false,"schema":{"type":"integer","format":"int32"},"example":1},{"name":"locale","in":"query","description":"Язык интерфейса: ru | kk | en","required":false,"schema":{"type":"string"},"example":"ru"}],"responses":{"200":{"description":"Сводка периода","content":{"*/*":{"schema":{"$ref":"#/components/schemas/SemesterSummaryDto"}}}},"400":{"description":"Период не задан, а текущий определить нечем","content":{"*/*":{"schema":{"$ref":"#/components/schemas/SemesterSummaryDto"}}}},"401":{"description":"Нет/невалидный JWT","content":{"*/*":{"schema":{"$ref":"#/components/schemas/SemesterSummaryDto"}}}},"403":{"content":{"*/*":{"schema":{"$ref":"#/components/schemas/SemesterSummaryDto"}}}},"404":{"description":"Названного периода нет в календаре","content":{"*/*":{"schema":{"$ref":"#/components/schemas/SemesterSummaryDto"}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.learning.read"]}]}},"/learning/me/prep-plan":{"get":{"tags":["LEARNING: Student plan"],"summary":"Подготовительные блоки маршрута","description":"A6: что подтянуть по итогам входной диагностики, почему (уровень, доля и дата результата направления) и чем (дисциплина, материал или ссылка).\nСоответствие «направление → материал» настраивается администратором (/api/learning/admin/placement/recommendations), в коде оно не зашито. Диагностика не пройдена — пустой список: это честный ответ «сначала пройдите направления».\nУ теста — уровень и доля верных ответов. У анкеты правильных ответов не существует, поэтому её блок подбирается по КОНКРЕТНОМУ ответу о себе (признак вопроса: планирование, режим…), а не по доле: доля у анкеты означала бы «выполняется у всех», и пункт плана недели про подготовительный блок не закрывался бы ни у кого.\nПустой ответ шагом не считается. Флаг ставит ТОЛЬКО экран, который блоки рисует (маршрут); экрану, которому список нужен лишь чтобы выбрать формулировку, флаг ставить нельзя — иначе шаг засчитается за то, чего студент не видел.","operationId":"learning_prepPlan","parameters":[{"name":"locale","in":"query","description":"Язык интерфейса: ru | kk | en","required":false,"schema":{"type":"string"},"example":"ru"},{"name":"shown","in":"query","description":"Вызывающий экран ПОКАЗЫВАЕТ эти блоки студенту (маршрут). Только с ним засчитывается шаг «подготовительный блок открыт»","required":false,"schema":{"type":"boolean","default":false},"example":true}],"responses":{"200":{"description":"Подготовительные блоки (возможно, пусто)","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PrepPlanDto"}}}},"401":{"description":"Нет/невалидный JWT","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PrepPlanDto"}}}},"403":{"content":{"*/*":{"schema":{"$ref":"#/components/schemas/PrepPlanDto"}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.learning.read"]}]}},"/learning/me/placement":{"get":{"tags":["LEARNING: Placement (student)"],"summary":"Экран входной диагностики","description":"Все активные направления с состоянием у вызывающего студента: NOT_STARTED / IN_PROGRESS (есть незавершённая попытка, её id в openAttemptId) / COMPLETED (есть результат) / BANK_EMPTY (у направления нет ни одного утверждённого вопроса — начать нельзя, и экран обязан сказать это прямо). Счётчики считает сервер: startableDirections исключает направления с пустым банком, поэтому «осталось N» не обещает работу, которой не существует. Вызывающий без учебной карточки получает справочник без личного состояния.","operationId":"learning_overview","parameters":[{"name":"locale","in":"query","description":"Язык интерфейса: ru | kk | en. Неизвестное значение — ru","required":false,"schema":{"type":"string"},"example":"ru"}],"responses":{"200":{"description":"Направления и прогресс","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PlacementOverviewDto"}}}},"401":{"description":"Нет/невалидный JWT","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PlacementOverviewDto"}}}},"403":{"content":{"*/*":{"schema":{"$ref":"#/components/schemas/PlacementOverviewDto"}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.learning.read"]}]}},"/learning/me/placement/results":{"get":{"tags":["LEARNING: Placement (student)"],"summary":"Мои результаты диагностики","description":"По строке на каждое пройденное направление: уровень (у анкеты его нет), доля, дата, текст вывода из справочника направления и признак «стоит подтянуть». подготовительные блоки), и на экране обязан звучать как «что подтянуть», а не как ярлык отставания.","operationId":"learning_myResults","parameters":[{"name":"locale","in":"query","description":"Язык интерфейса: ru | kk | en","required":false,"schema":{"type":"string"},"example":"ru"}],"responses":{"200":{"description":"Результаты (возможно, пусто)","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/PlacementResultDto"}}}}},"401":{"description":"Нет/невалидный JWT","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/PlacementResultDto"}}}}},"403":{"content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/PlacementResultDto"}}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.learning.read"]}]}},"/learning/me/placement/attempts/{attemptId}":{"get":{"tags":["LEARNING: Placement (student)"],"summary":"Состояние попытки","description":"Возобновление прерванного прохождения: тот же вопрос, на котором студент остановился, и сколько уже отвечено. У завершённой попытки вместо вопроса приходит результат. Чужая попытка — 404 (существование не раскрывается).","operationId":"learning_attemptState","parameters":[{"name":"attemptId","in":"path","description":"Идентификатор попытки","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"locale","in":"query","description":"Язык интерфейса: ru | kk | en","required":false,"schema":{"type":"string"},"example":"ru"}],"responses":{"200":{"description":"Состояние попытки","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PlacementAttemptStateDto"}}}},"401":{"description":"Нет/невалидный JWT","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PlacementAttemptStateDto"}}}},"403":{"content":{"*/*":{"schema":{"$ref":"#/components/schemas/PlacementAttemptStateDto"}}}},"404":{"description":"Попытки нет либо она чужая","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PlacementAttemptStateDto"}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.learning.read"]}]}},"/learning/me/observations":{"get":{"tags":["LEARNING: Observations"],"summary":"My active observations","description":"Active observations of the calling student: not dismissed and created within the active window (default 14 days). Sorted by importance (HIGH -> MEDIUM -> LOW) then newest-first. Each item carries all three locales (messageRu/Kk/En — the frontend picks), the parsed numeric payload, a campus deeplink and a seen flag. A caller without a Learner row (teacher/admin) gets an empty list.\nA phrasing or translation fix therefore reaches observations created days ago too, and names of disciplines/skills/goals come from the current directory (a rename shows up here). The text stored with the row is only a fallback for rows whose payload lacks a parameter the template needs.","operationId":"learning_myObservations","responses":{"200":{"description":"Active observations (possibly empty)","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/ObservationDto"}}}}},"401":{"description":"No/invalid JWT","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/ObservationDto"}}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.learning.read"]}]}},"/learning/me/gamification":{"get":{"tags":["LEARNING: Gamification (student)"],"summary":"Мой уровень, очки и достижения","description":"Очки опыта и уровень с лестницей из десяти ступеней, каталог достижений (25; при закрытом флаге клубов — 21) с полученными ступенями, прогрессом к следующей и текстом прогресса на трёх языках, и настройки витрины.\nСбой соседа ответ не роняет.\nДостижения «Разносторонность» и «Путь к цели» без цели несут `unavailableReason` NO_GOAL или GOAL_HAS_NO_SKILLS.","operationId":"learning_overview_1","responses":{"200":{"description":"Обзор уровня и достижений","content":{"*/*":{"schema":{"$ref":"#/components/schemas/GamificationOverviewDto"}}}},"401":{"description":"Нет или невалидный JWT","content":{"*/*":{"schema":{"$ref":"#/components/schemas/GamificationOverviewDto"}}}},"403":{"content":{"*/*":{"schema":{"$ref":"#/components/schemas/GamificationOverviewDto"}}}},"404":{"description":"У вызывающего нет учебной карточки","content":{"*/*":{"schema":{"$ref":"#/components/schemas/GamificationOverviewDto"}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.learning.read"]}]}},"/learning/me/gamification/rules":{"get":{"tags":["LEARNING: Gamification (student)"],"summary":"Как начисляются очки","description":"Правила начисления (учёба, навыки, проекты и клубы) с очками и уточнениями, плюс лестница уровней. Клубные правила — только при открытом флаге клубов. Правила живут в коде; админ-экрана настройки нет.","operationId":"learning_rules","responses":{"200":{"description":"Правила и лестница","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PointRulesDto"}}}},"401":{"description":"Нет или невалидный JWT","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PointRulesDto"}}}},"403":{"content":{"*/*":{"schema":{"$ref":"#/components/schemas/PointRulesDto"}}}},"404":{"description":"У вызывающего нет учебной карточки","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PointRulesDto"}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.learning.read"]}]}},"/learning/me/elective-hints":{"get":{"tags":["LEARNING: Student plan"],"summary":"Подсказки при выборе элективов","description":"Дисциплина без единого признака в ответ не попадает — это подсказка, а не второй каталог.\nЭкран кампуса зовёт её РЯДОМ с каталогом и сводит выдачи по courseCode.\nПрограмма студента не определена, элективов в РУП нет или все уже выбраны — пустой список.","operationId":"learning_electiveHints","parameters":[{"name":"locale","in":"query","description":"Язык интерфейса: ru | kk | en","required":false,"schema":{"type":"string"},"example":"ru"}],"responses":{"200":{"description":"Подсказки (возможно, пусто)","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/ElectiveHintDto"}}}}},"401":{"description":"Нет/невалидный JWT","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/ElectiveHintDto"}}}}},"403":{"content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/ElectiveHintDto"}}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.learning.read"]}]}},"/learning/me/dashboard-level":{"get":{"tags":["LEARNING: Student dashboard"],"summary":"Уровень кабинета студента","description":"Какой из ДВУХ кабинетов рисовать вошедшему студенту:\n• level = 1 — активных записей на дисциплины нет: человек только начал (знакомство, входная диагностика, выбор ментора, запись на дисциплины). Занятий, сроков и прогресса у него ещё не существует, и показывать их пустыми блоками нечестно;\n• level = 2 — есть хотя бы одна активная запись: обычный кабинет с занятиями, сроками и прогрессом.\nОстальные поля ответа — слагаемые этого решения, а не второй его источник; собирать уровень заново на фронте нельзя.\nactiveEnrollments — записи в статусе ACTIVE. Закрытая ведомость переводит запись в COMPLETED/FAILED, снятие — в WITHDRAWN; такие записи сюда НЕ идут, и доучившийся студент без новых дисциплин снова видит первый кабинет.\nhasSchedule — есть ли у студента занятия на ТЕКУЩЕЙ неделе по данным расписания.\nРучка рассчитана на вызов при КАЖДОМ заходе на главную: один COUNT по записям плюс один короткий вопрос расписанию, падающий открыто.","operationId":"learning_dashboardLevel","responses":{"200":{"description":"Уровень кабинета","content":{"*/*":{"schema":{"$ref":"#/components/schemas/DashboardLevelDto"}}}},"401":{"description":"Нет/невалидный JWT","content":{"*/*":{"schema":{"$ref":"#/components/schemas/DashboardLevelDto"}}}},"403":{"content":{"*/*":{"schema":{"$ref":"#/components/schemas/DashboardLevelDto"}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.learning.read"]}]}},"/learning/me/course-certificates":{"get":{"tags":["LEARNING: Open course certificates"],"summary":"Мои сертификаты открытых курсов","description":"Все выданные студенту, включая отозванные (revokedAt).","operationId":"learning_mine_1","responses":{"200":{"description":"Сертификаты, свежие сверху","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/MyCourseCertificateDto"}}}}},"403":{"content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/MyCourseCertificateDto"}}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.learning.read"]}]}},"/learning/me/course-certificates/{id}/pdf":{"get":{"tags":["LEARNING: Open course certificates"],"summary":"PDF моего сертификата","description":"Лист рендерится по запросу из снимка: ФИО, название курса, дата прохождения, номер и QR проверки; балла нет. Язык листа — locale (ru, kk, en), по умолчанию ru.","operationId":"learning_myPdf","parameters":[{"name":"id","in":"path","description":"Id сертификата","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"locale","in":"query","description":"Язык листа: ru | kk | en","required":false,"schema":{"type":"string"},"example":"ru"}],"responses":{"200":{"description":"application/pdf","content":{"*/*":{"schema":{"type":"string","format":"byte"}}}},"403":{"content":{"*/*":{"schema":{"type":"string","format":"byte"}}}},"404":{"description":"Сертификата нет или он чужой","content":{"*/*":{"schema":{"type":"string","format":"byte"}}}},"502":{"description":"Сервис рендера недоступен","content":{"*/*":{"schema":{"type":"string","format":"byte"}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.learning.read"]}]}},"/learning/me/attendance":{"get":{"tags":["LEARNING: Attendance (student)"],"summary":"My attendance","description":"The caller's attendance grouped by course: per-status counters (present/absent/late/excused), ONE share of attendance, the exam-admission verdict that follows from it, and every mark (date+status) newest-first. ratePct is kept for compatibility and carries the SAME number; only when admissionRatePct is null (an empty retake window, a vedomost closed before STUD-18) is it the whole-journal share with the same formula, 0 when nothing is marked. Never render null as 0 %. It is null on a discipline closed BEFORE STUD-18 as well: that vedomost was never judged on attendance and is not judged now. admissionCountedFrom (non-null only on a RETAKE) says that the admission share above counts the marks made strictly after that date — show it, or the share and the counters look like a bug. missesLeft = how many further classes may be missed while staying above the threshold; attendancesNeeded = how many classes in a row bring him back above it (null while above). waived/waivedReason = a teacher admitted him despite the threshold and why — both describe the admission IN FORCE and become false/null once it is withdrawn, and the reason he stated for withdrawing it arrives in admissionRevokedReason instead. frozen=true = the discipline is closed: the VERDICT (admissionRatePct, threshold, attendanceAdmitted, waived) is the one frozen into the vedomost, while the counters and the list of marks stay the live journal — the journal is what the student is looking at, and it keeps moving after a closure. A course with no marks reports zeros, a null admissionRatePct and an empty records list; a caller with no live enrollment (or no learner record at all) gets an empty list. У студента, у которого в один день лекция потока И практика группы одной дисциплины, записей ДВЕ с одинаковой датой: без sectionId экран ставил им один React-ключ и печатал обеим время и вид ПЕРВОЙ пары дня. Ключ строки на клиенте — пара (sectionId, date), НЕ одна date. `markedAt` — когда её поставили или последний раз меняли. Имена собираются ОДНИМ пакетным рейсом на весь ответ.","operationId":"learning_myAttendance","responses":{"200":{"description":"Per-course attendance (possibly empty)","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/MyAttendanceCourseDto"}}}}},"401":{"description":"No/invalid JWT","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/MyAttendanceCourseDto"}}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.learning.read"]}]}},"/learning/me/attendance/lessons":{"get":{"tags":["LEARNING: My attendance lessons"],"summary":"My lessons in a date range, with or without a mark","description":"Сшивка «занятие расписания × моя отметка × моё обращение», которую нельзя сделать на клиенте: занятий как строк в базе НЕТ (расписание разворачивает даты на лету), а learning знает только уже поставленные отметки. Пустой `lessons` при `true` — ЗАКОННЫЙ период без занятий. Экран обязан говорить это разными словами. Читать надо `appealBlockedCode` (UPPER_SNAKE), а `appealBlockedReason` — русский запасной текст: узнавать причину по фразе нельзя, на kk/en её не будет. Коды: NOT_STARTED (занятие ещё не началось) · ALREADY_PENDING (обращение уже на рассмотрении) · ALREADY_DECIDED (уже рассмотрено) · GRADESHEET_CLOSED (ведомость закрыта) · TERM_CLOSED (триместр закрыт) · WINDOW_OVER (срок подачи истёк) · NO_MARK (отметки по занятию ещё нет). Оба поля null при `appealable = true`. Окно ограничено 200 днями. Событие без потока (программы или дисциплины, у которого нет секции) в ответ не попадает: отметить его некуда.","operationId":"learning_myLessons","parameters":[{"name":"from","in":"query","description":"Начало периода, включительно (ГГГГ-ММ-ДД)","required":true,"schema":{"type":"string","format":"date"},"example":"2026-09-07"},{"name":"to","in":"query","description":"Конец периода, включительно (ГГГГ-ММ-ДД)","required":true,"schema":{"type":"string","format":"date"},"example":"2026-09-13"}],"responses":{"200":{"description":"Занятия периода (возможно, пустой список)","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MyAttendanceLessonsDto"}}}},"400":{"description":"Не указана граница периода, конец раньше начала либо окно длиннее 200 дней","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MyAttendanceLessonsDto"}}}},"401":{"description":"Нет/неверный JWT","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MyAttendanceLessonsDto"}}}},"403":{"content":{"*/*":{"schema":{"$ref":"#/components/schemas/MyAttendanceLessonsDto"}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.learning.read"]}]}},"/learning/materials/{materialId}/check-questions":{"get":{"tags":["LEARNING: Check questions"],"summary":"Проверочные вопросы страницы","description":"Тела вопросов БЕЗ правильных ответов и БЕЗ разбора — ровно то, что можно положить в исходник страницы. Разбор приезжает только ответом на попытку ответить. Пустой список — нормальный ответ: на странице просто нет проверочных вопросов.","operationId":"learning_list_16","parameters":[{"name":"materialId","in":"path","description":"Идентификатор страницы (материала)","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Список (возможно пустой)","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/CheckQuestionDto"}}}}},"403":{"description":"Дисциплина вне области доступа","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/CheckQuestionDto"}}}}},"404":{"description":"Страница не найдена.","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/CheckQuestionDto"}}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.learning.read"]}]}},"/learning/materials/{id}":{"get":{"tags":["LEARNING: Materials"],"summary":"Get material metadata","description":"Returns the material with the id of its file (s3FileId, mirroring files[0]) — NEVER a storage address and NEVER a signature. A presigned URL is a bearer pass: it opens the file for anyone it reaches, with no session, and it used to travel into the page source of every screen that rendered this record. The browser reads the bytes through its own cabinet route instead (`/api/material/{id}`, `/api/storage/{s3FileId}`), where the right is checked per request. `indexState` — попал ли текст элемента в корпус Тьютора (секунды). `kitStartedAt` — начало текущей сборки, null во всех остальных состояниях. Студенту черновик при этом недоступен ни строкой, ни артефактом.","operationId":"learning_getMaterial","parameters":[{"name":"id","in":"path","description":"Material id","required":true,"schema":{"type":"string","format":"uuid"},"example":"3f6f4c1e-2c1a-4c5e-9b1e-1a2b3c4d5e6f"}],"responses":{"200":{"description":"Material metadata + s3FileId + the full files[] list","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MaterialDetailDto"}}}},"401":{"description":"No/invalid JWT","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MaterialDetailDto"}}}},"403":{"description":"Material's course is out of the caller's scope","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MaterialDetailDto"}}}},"404":{"description":"Material not found (or a DRAFT / out-of-window material requested by a student)","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MaterialDetailDto"}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.learning.read"]}]}},"/learning/materials/{id}/spaces":{"get":{"tags":["LEARNING: Materials"],"summary":"Which of MY study spaces already hold this material","description":"Returns the ids of the CALLER'S OWN study spaces that already contain a copy of this material. It is what lets the «Отправить в пространство» dialog mark a row «Уже здесь» instead of making the student discover it by getting a 409. Somebody else's spaces are out of scope by construction, not by a filter on the client.","operationId":"learning_getMaterialSpaces","parameters":[{"name":"id","in":"path","description":"Material id","required":true,"schema":{"type":"string","format":"uuid"},"example":"3f6f4c1e-2c1a-4c5e-9b1e-1a2b3c4d5e6f"}],"responses":{"200":{"description":"materialId + the ids of the caller's spaces already holding it (possibly empty)","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MaterialSpacesDto"}}}},"401":{"description":"No/invalid JWT","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MaterialSpacesDto"}}}},"404":{"description":"Material not found, is a draft, is outside its availability window, or belongs to a course the caller may not read (all the same)","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MaterialSpacesDto"}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.learning.read"]}]}},"/learning/materials/{id}/preview":{"get":{"tags":["LEARNING: Material files"],"summary":"The hover-preview sheet of a video material","description":"Streams ONE JPEG — the tile grid of frames sampled across the video — from which the player cuts the frame shown under the cursor on the time bar. Its layout (how many seconds one tile covers, tile size, columns, count) comes in the `videoPreview` object of GET /learning/materials/{id}. Both cabinets (student and teacher) come through THIS door. Cacheable for a day (`private, max-age=86400`): the sheet is immutable — it is built from one file and changes only when that file does.","operationId":"learning_servePreview","parameters":[{"name":"id","in":"path","description":"Material id","required":true,"schema":{"type":"string","format":"uuid"},"example":"3f6f4c1e-2c1a-4c5e-9b1e-1a2b3c4d5e6f"}],"responses":{"200":{"description":"The sprite sheet (image/jpeg)","content":{"*/*":{"schema":{"$ref":"#/components/schemas/StreamingResponseBody"}}}},"401":{"description":"No/invalid JWT","content":{"*/*":{"schema":{"$ref":"#/components/schemas/StreamingResponseBody"}}}},"403":{"description":"Material's course is out of the caller's scope","content":{"*/*":{"schema":{"$ref":"#/components/schemas/StreamingResponseBody"}}}},"404":{"description":"Material not found; a DRAFT / out-of-window / condition-not-met material requested by a student; or the material has no sheet yet (it is built in the background and is best-effort — a video without one still plays)","content":{"*/*":{"schema":{"$ref":"#/components/schemas/StreamingResponseBody"}}}},"502":{"description":"The storage is unavailable","content":{"*/*":{"schema":{"$ref":"#/components/schemas/StreamingResponseBody"}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.learning.read"]}]}},"/learning/materials/{id}/pdf":{"get":{"tags":["LEARNING: Materials"],"summary":"Download a page / announcement as PDF","description":"CAMPUS-09 (owner decision 9, verbatim: «Скачивание: PDF генерируем для страниц-лекций и объявлений; загруженные преподавателем файлы отдаём как есть»). Renders the element's own text (contentHtml) into a PDF and returns the BYTES with `Content-Disposition: attachment` — the file name is the material's title, carried in the RFC 5987 form (`filename*=UTF-8''…`) so a Cyrillic title survives the HTTP header. FILE and VIDEO answer 400 — those bytes are handed over AS THEY ARE through the cabinet route built on s3FileId (converting a docx loses its formulas, and an archive is not a document). LINK answers 400 too: its content lives on somebody else's server.","operationId":"learning_getMaterialPdf","parameters":[{"name":"id","in":"path","description":"Material id","required":true,"schema":{"type":"string","format":"uuid"},"example":"3f6f4c1e-2c1a-4c5e-9b1e-1a2b3c4d5e6f"}],"responses":{"200":{"description":"application/pdf bytes, attachment","content":{"*/*":{"schema":{"type":"string","format":"byte"}}}},"400":{"description":"The material is a FILE / VIDEO (download it as it is) or a LINK","content":{"*/*":{"schema":{"type":"string","format":"byte"}}}},"401":{"description":"No/invalid JWT","content":{"*/*":{"schema":{"type":"string","format":"byte"}}}},"403":{"description":"Material's course is out of the caller's scope","content":{"*/*":{"schema":{"type":"string","format":"byte"}}}},"404":{"description":"Material not found (or a DRAFT / out-of-window material requested by a student)","content":{"*/*":{"schema":{"type":"string","format":"byte"}}}},"502":{"description":"The render service is unavailable","content":{"*/*":{"schema":{"type":"string","format":"byte"}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.learning.read"]}]}},"/learning/materials/{id}/file":{"get":{"tags":["LEARNING: Material files"],"summary":"Download / stream an attachment of a material","description":"Streams the bytes of ONE attachment of the material. The presigned storage URL never leaves the docker network — the caller gets a stream, not an address (a signed URL is a bearer pass: whoever it reaches opens the file, with no session). `Content-Type` and `Content-Disposition` (RFC 6266, the original file name) are the SAME headers the file service would emit — they are signed into the storage URL by that very service — so the cabinet renders and saves the file exactly as before. `Range` is carried both ways: a lecture video seeks here as it does through the file service (206 + `Content-Range`, `Accept-Ranges: bytes`, 416 for a range past the end). A material closed a second ago stops serving bytes on the very next request; nothing is cached and no verdict is stored. Absent = the first attachment (the one the material card mirrors as s3FileId).","operationId":"learning_serve_1","parameters":[{"name":"id","in":"path","description":"Material id","required":true,"schema":{"type":"string","format":"uuid"},"example":"3f6f4c1e-2c1a-4c5e-9b1e-1a2b3c4d5e6f"},{"name":"attachment","in":"query","description":"Id of the attachment row (files[].id of GET /learning/materials/{id}); absent = the first attachment","required":false,"schema":{"type":"string","format":"uuid"},"example":"a0fcc892-4e5a-465c-8a98-81efd9e484a3"},{"name":"Range","in":"header","description":"Standard HTTP Range header, carried through to the storage","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"The whole file, streamed","content":{"*/*":{"schema":{"$ref":"#/components/schemas/StreamingResponseBody"}}}},"206":{"description":"The requested byte range","content":{"*/*":{"schema":{"$ref":"#/components/schemas/StreamingResponseBody"}}}},"401":{"description":"No/invalid JWT","content":{"*/*":{"schema":{"$ref":"#/components/schemas/StreamingResponseBody"}}}},"403":{"description":"Material's course is out of the caller's scope","content":{"*/*":{"schema":{"$ref":"#/components/schemas/StreamingResponseBody"}}}},"404":{"description":"Material not found; a DRAFT / out-of-window / condition-not-met material requested by a student; an unknown attachment; a material with no file at all; or the object is missing in storage (all indistinguishable on purpose)","content":{"*/*":{"schema":{"$ref":"#/components/schemas/StreamingResponseBody"}}}},"416":{"description":"The requested range lies past the end of the file","content":{"*/*":{"schema":{"$ref":"#/components/schemas/StreamingResponseBody"}}}},"502":{"description":"The storage is unavailable","content":{"*/*":{"schema":{"$ref":"#/components/schemas/StreamingResponseBody"}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.learning.read"]}]}},"/learning/materials/{id}/content":{"get":{"tags":["LEARNING: Materials"],"summary":"Get the text of a material inline","description":"Access is gated exactly like GET /learning/materials/{id}: a DRAFT material, or one outside its availability window at EITHER end, is 404 for a student; a course out of scope is 403. Everything else — PDF, DOCX, video, and markup types such as `text/html` — answers 400 and must be read through the cabinet route built on s3FileId of GET /learning/materials/{id}. A leading UTF-8 BOM (what a Windows editor writes) is stripped, so the text starts with its first real character — a markdown heading stays a heading and a JSON material stays parseable.","operationId":"learning_getMaterialContent","parameters":[{"name":"id","in":"path","description":"Material id","required":true,"schema":{"type":"string","format":"uuid"},"example":"3f6f4c1e-2c1a-4c5e-9b1e-1a2b3c4d5e6f"}],"responses":{"200":{"description":"Material id, title, mimeType and the full UTF-8 text","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MaterialContentDto"}}}},"400":{"description":"Material is not a text type, is larger than 2 MB, or is not valid UTF-8","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MaterialContentDto"}}}},"401":{"description":"No/invalid JWT","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MaterialContentDto"}}}},"403":{"description":"Material's course is out of the caller's scope","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MaterialContentDto"}}}},"404":{"description":"Material not found (or a DRAFT / out-of-window material requested by a student), or its file is missing in storage","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MaterialContentDto"}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.learning.read"]}]}},"/learning/materials/{id}/artifacts":{"get":{"tags":["LEARNING: Material artifacts"],"summary":"List the material's AI artifacts","description":"Returns the auto-generated artifact set of the material, ordered by type (TRANSCRIPT, NOTES, SUMMARY, GLOSSARY, FLASHCARDS, QUIZ). An empty list means generation has not completed yet (tabs show a 'generating' state).","operationId":"learning_listArtifacts","parameters":[{"name":"id","in":"path","description":"Material id","required":true,"schema":{"type":"string","format":"uuid"},"example":"3f6f4c1e-2c1a-4c5e-9b1e-1a2b3c4d5e6f"}],"responses":{"200":{"description":"Artifact list (possibly empty)","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/MaterialArtifactDto"}}}}},"401":{"description":"No/invalid JWT","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/MaterialArtifactDto"}}}}},"403":{"description":"Material's course is out of the caller's scope","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/MaterialArtifactDto"}}}}},"404":{"description":"Material not found (or DRAFT requested by a student)","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/MaterialArtifactDto"}}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.learning.read"]}]}},"/learning/lesson-feedback/options":{"get":{"tags":["LEARNING: Lesson feedback (student)"],"summary":"Feedback form options","description":"Everything the form needs so nothing is hardcoded on the client: the tag vocabulary (code + labelRu/labelKk/labelEn — the service owns the translations, the client must never hardcode its own), how many tags may be picked, the rating range, the comment length limit, how long the author may edit their feedback (editWindowHours) and how many days after a class it can still be rated (feedbackWindowDays — 56 by default: the horizon the published schedule can still confirm a class over). Static per deployment. Access: any authenticated caller.","operationId":"learning_options","responses":{"200":{"description":"Form options","content":{"*/*":{"schema":{"$ref":"#/components/schemas/LessonFeedbackOptionsDto"}}}},"401":{"description":"No/invalid JWT","content":{"*/*":{"schema":{"$ref":"#/components/schemas/LessonFeedbackOptionsDto"}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.learning.read"]}]}},"/learning/lesson-feedback/my":{"get":{"tags":["LEARNING: Lesson feedback (student)"],"summary":"My feedback","description":"Every feedback the CALLER has left, newest class first; optionally narrowed to one course. The schedule screen subtracts this list from its own past class dates to decide where to show the «Оцените занятие» mark, and reads `editable` to render the form read-only after the edit window. A caller without a Learner row gets an empty list.","operationId":"learning_listMine","parameters":[{"name":"courseId","in":"query","description":"Narrow to one learning course id","required":false,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"My feedback (possibly empty)","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/LessonFeedbackDto"}}}}},"401":{"description":"No/invalid JWT","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/LessonFeedbackDto"}}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.learning.read"]}]}},"/learning/health":{"get":{"tags":["LEARNING: Health"],"summary":"Health ping (no auth)","operationId":"learning_health","responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"object","additionalProperties":{"type":"string"}}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.learning.read"]}]}},"/learning/gradebook/me":{"get":{"tags":["LEARNING: Gradebook"],"summary":"My grades","description":"Approved grades of the calling student across courses, newest first: assignment title, totalScore/maxScore, teacher feedback, per-criterion scores with criterion names, approvedAt. A caller without a Learner row (teacher/admin) gets an empty list.","operationId":"learning_myGradebook","responses":{"200":{"description":"My gradebook entries (possibly empty)","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/GradebookEntryDto"}}}}},"401":{"description":"No/invalid JWT","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/GradebookEntryDto"}}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.learning.read"]}]}},"/learning/gradebook/me/transcript":{"get":{"tags":["LEARNING: Gradebook"],"description":"The calling student's full academic record: the SAME cumulative GPA and per-course rows as GET /gradebook/me/gpa (the unchanged calc core — a superseded retake is already dropped), additionally partitioned into academic terms. Grouping is by the REAL closure moment (CourseGrade.finalizedAt resolved to the covering AcademicTerm — academicYear + termNo), NOT the curriculum slot (Course.trimester): a retake therefore lands in its own later term. Each term carries its own credit-weighted termGpa (HALF_UP, scale 2) and termCredits; cumulativeGpa is the ONE aggregate over ALL courses (reconciles with /me/gpa to two decimals) and is NEVER the average of the per-term GPAs. Empty (first-year, no terminal grades) => 200 with cumulativeGpa=null, totalCredits=0, terms=[] (never 404). A caller without a Learner row gets the same empty transcript.","operationId":"learning_myTranscript","responses":{"200":{"description":"Transcript grouped by term (possibly empty)","content":{"*/*":{"schema":{"$ref":"#/components/schemas/TranscriptDto"}}}},"401":{"description":"No/invalid JWT","content":{"*/*":{"schema":{"$ref":"#/components/schemas/TranscriptDto"}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.learning.read"]}]}},"/learning/gradebook/me/transcript/pdf":{"get":{"tags":["LEARNING: Gradebook"],"summary":"Export my transcript as PDF","description":"The official transcript document by the student's curriculum — exactly what GET /gradebook/me/plan-transcript/pdf issues with scope=ALL and lang=ru: header (full name, IIN, university, programme, level, mode and language of study, admission year, year of study, funding, periods), academic year -> year of study -> trimester, statuses in words, totals, document number TR-<year>-<6 digits> and a QR code to the public verification page. Every download registers a new numbered document.","operationId":"learning_myTranscriptPdf","responses":{"200":{"description":"The transcript PDF; header X-Document-Number","content":{"*/*":{"schema":{"type":"string","format":"byte"}}}},"400":{"description":"The caller's account carries no name — the document cannot be issued (fix it in the user card, not here)","content":{"*/*":{"schema":{"type":"string","format":"byte"}}}},"401":{"description":"No/invalid JWT","content":{"*/*":{"schema":{"type":"string","format":"byte"}}}},"404":{"description":"The caller has no learner card","content":{"*/*":{"schema":{"type":"string","format":"byte"}}}},"502":{"description":"The render service is unavailable","content":{"*/*":{"schema":{"type":"string","format":"byte"}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.learning.read"]}]}},"/learning/gradebook/me/recredits":{"get":{"tags":["LEARNING: Student transcript by plan"],"summary":"Мои подтверждённые перезачёты","description":"Перезачёты, подтверждённые офисом регистратора: дисциплина плана, ранее изученная дисциплина, кредиты, результат, основание, решение. Черновики и отменённые не отдаются.","operationId":"learning_myRecredits","responses":{"200":{"description":"Список (возможно пустой)","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/MyRecreditDto"}}}}},"401":{"description":"Нет или неверный JWT","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/MyRecreditDto"}}}}},"403":{"content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/MyRecreditDto"}}}}},"404":{"description":"У вызывающего нет учебной карточки","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/MyRecreditDto"}}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.learning.read"]}]}},"/learning/gradebook/me/quiz-attempts":{"get":{"tags":["LEARNING: Gradebook"],"summary":"My quiz attempts (task 33)","description":"ALL quiz attempts of the calling student, newest first, so quiz results appear in the grades feed alongside approved submission grades. Each row carries the quiz title and its owning course (id/code/title), scorePct, attemptedAt and attemptNumber — the 1-based chronological ordinal of the attempt WITHIN its quiz (oldest = 1), so repeat attempts are distinguishable. While an attempt waits for its essay to be graded its `scorePct` is PARTIAL (the auto part only) and must NOT be shown as a result — after the teacher grades it the same number changes. The client does not re-derive this rule from anything else. A caller without a Learner row (teacher/admin) or a student who never attempted a quiz gets an empty list [].","operationId":"learning_myQuizAttempts","responses":{"200":{"description":"My quiz attempts, newest first (possibly empty)","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/QuizAttemptFeedDto"}}}}},"401":{"description":"No/invalid JWT","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/QuizAttemptFeedDto"}}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.learning.read"]}]}},"/learning/gradebook/me/plan-transcript":{"get":{"tags":["LEARNING: Student transcript by plan"],"summary":"Мой учебный план и транскрипт","description":"Строки — дисциплины плана студента (редакция учебного года поступления + курс), даже без оценок, по месту дисциплины в плане; курсы-пререквизиты и курсы вне плана — своими строками в своём году и триместре. Статусы: PLANNED, IN_PROGRESS, PASSED, RECREDITED, ACADEMIC_DEBT, RETAKE, RESTUDY; прежняя попытка, заменённая повторным изучением, — строка replaced=true. GPA — по последней закрытой попытке; перезачёт входит в GPA, если у него есть буква. scope=ALL — «Итоги обучения» накопительно; YEAR (academicYear) и COURSE (courseNo) — только выбранный период и его итоги.","operationId":"learning_myPlanTranscript","parameters":[{"name":"scope","in":"query","description":"Период: ALL (по умолчанию), YEAR, COURSE","required":false,"schema":{"type":"string","enum":["ALL","YEAR","COURSE"]},"example":"ALL"},{"name":"academicYear","in":"query","description":"Учебный год для scope=YEAR","required":false,"schema":{"type":"string"},"example":"2026-2027"},{"name":"courseNo","in":"query","description":"Курс обучения для scope=COURSE","required":false,"schema":{"type":"integer","format":"int32"},"example":1}],"responses":{"200":{"description":"Транскрипт по плану","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PlanTranscriptDto"}}}},"400":{"description":"scope=YEAR без academicYear или scope=COURSE без courseNo","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PlanTranscriptDto"}}}},"401":{"description":"Нет или неверный JWT","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PlanTranscriptDto"}}}},"403":{"content":{"*/*":{"schema":{"$ref":"#/components/schemas/PlanTranscriptDto"}}}},"404":{"description":"У вызывающего нет учебной карточки","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PlanTranscriptDto"}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.learning.read"]}]}},"/learning/gradebook/me/plan-transcript/pdf":{"get":{"tags":["LEARNING: Student transcript by plan"],"summary":"PDF моего транскрипта","description":"Официальный документ: шапка (ФИО, ИИН, вуз, ОП, уровень, форма и язык обучения, год поступления, курс, финансирование, период обучения и документа), год → курс → триместр, статусы словами, итоги, номер TR-<год>-<6 цифр> и QR на публичную проверку. Каждое скачивание — новый номер в реестре выданных документов.","operationId":"learning_myPlanTranscriptPdf","parameters":[{"name":"scope","in":"query","description":"Период: ALL (по умолчанию), YEAR, COURSE","required":false,"schema":{"type":"string","enum":["ALL","YEAR","COURSE"]},"example":"ALL"},{"name":"academicYear","in":"query","description":"Учебный год для scope=YEAR","required":false,"schema":{"type":"string"},"example":"2026-2027"},{"name":"courseNo","in":"query","description":"Курс обучения для scope=COURSE","required":false,"schema":{"type":"integer","format":"int32"},"example":1},{"name":"lang","in":"query","description":"Язык документа: ru (по умолчанию), kk, en","required":false,"schema":{"type":"string"},"example":"ru"}],"responses":{"200":{"description":"application/pdf","content":{"*/*":{"schema":{"type":"string","format":"byte"}}}},"400":{"description":"Неверные параметры периода или в карточке нет ФИО","content":{"*/*":{"schema":{"type":"string","format":"byte"}}}},"401":{"description":"Нет или неверный JWT","content":{"*/*":{"schema":{"type":"string","format":"byte"}}}},"403":{"content":{"*/*":{"schema":{"type":"string","format":"byte"}}}},"404":{"description":"У вызывающего нет учебной карточки","content":{"*/*":{"schema":{"type":"string","format":"byte"}}}},"502":{"description":"Сервис отрисовки PDF недоступен","content":{"*/*":{"schema":{"type":"string","format":"byte"}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.learning.read"]}]}},"/learning/gradebook/me/gpa":{"get":{"tags":["LEARNING: Gradebook"],"summary":"My cumulative GPA (case 1.12 / G18)","description":"Credit-weighted over the latest closed attempt per discipline (a retake or a restudy replaces the earlier grade). IN_PROGRESS grades never count. The per-course list holds course grades only (latest terminal per course; a discipline overridden by a confirmed recredit is left out). A caller without a Learner row gets an empty summary.","operationId":"learning_myGpa","responses":{"200":{"description":"Cumulative GPA + per-course grades (possibly empty)","content":{"*/*":{"schema":{"$ref":"#/components/schemas/GpaSummaryDto"}}}},"401":{"description":"No/invalid JWT","content":{"*/*":{"schema":{"$ref":"#/components/schemas/GpaSummaryDto"}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.learning.read"]}]}},"/learning/gradebook/me/courses":{"get":{"tags":["LEARNING: Gradebook"],"summary":"My grades across ALL my courses (UC-S15)","description":"One entry per course the caller is enrolled in (non-WITHDRAWN), ordered by course code — the same payload as GET /gradebook/me/course/{id}: per-component scores, РД (admission rating) with its threshold, admitted/notAdmitted/admissionDecided, the STUD-18 attendance block, projected, totalPct, letter, GPA value and status (IN_PROGRESS while the course is open, FINALIZED/FAILED after the vedomost is closed). Built for the grades screen so it lists every discipline instead of one arbitrary course, and so the frontend does not fan out a request per course. The server translates the slot, so the client must never do ((t-1)%3)+1 itself — that would be a third copy of the rule and would drift away from the timetable, the transcript and /me/semester/summary. BOTH fields are null together when the period is undecided (the course has no slot, or its programme calendar has not been entered yet) — that is an answer, not a failure: such a course belongs to no selectable period. Codes today: NO_ASSESSMENT_COMPONENTS (no params) and COMPONENT_HAS_NO_ELEMENTS {component}. An unknown code must fall back to the Russian string, never break the screen. A finalized (snapshot) row carries neither list. A single-trimester course (or the stream of ONE part of a multi-trimester discipline) has one entry = its own period with the course credits; a stream of a WHOLE multi-trimester discipline has one entry per part of ITS study year whose period exists in the calendar. Empty = the period is undecided (same meaning as termNo = null). Sum it for the «planned credits of the period» tile; academicYear/termNo stay the stream's own period. Plan rows without a course (research work, defence) are never here — the list is built from enrolments. A caller without a Learner row (teacher/admin) gets an empty list.","operationId":"learning_myCourseGrades","responses":{"200":{"description":"Per-course grade views (possibly empty)","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/CourseGradeDto"}}}}},"401":{"description":"No/invalid JWT","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/CourseGradeDto"}}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.learning.read"]}]}},"/learning/gradebook/me/course/{id}":{"get":{"tags":["LEARNING: Gradebook"],"summary":"My final grade for a course (case 1.12 / G18)","description":"While the course is not finalized this is the LIVE projection (recomputed on read from graded submissions + best quiz attempts); once finalized it is the immutable snapshot. projected=true (course still open): only GRADED work counts — an ungraded element is out of both the numerator and the denominator, the weights are RENORMALIZED over the components that have graded work, and the exam component is excluded until the admission verdict exists. projected=false (finalized): every published element counts, a missed submission is an honest 0 and the denominator is the full 100 — so a projected 90% can close as 27%. Render a projected row as a forecast («предварительно»), never as a final grade. `scoringMode` = EXPLICIT_WEIGHTS (every work of the component carries its own weight and they sum to 100 %) or MAX_SCORE_SUM (the old rule — a work weighs as much as its max score, so publishing a new work re-weights the previous ones); it is null on a CLOSED row because the ведомость snapshot does not store how it was computed. notAdmittedReason is null whenever notAdmitted is false. It becomes part of the verdict at finalize (projected=false).","operationId":"learning_myCourseGrade","parameters":[{"name":"id","in":"path","description":"Course id","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Course grade view (live or finalized)","content":{"*/*":{"schema":{"$ref":"#/components/schemas/CourseGradeDto"}}}},"401":{"description":"No/invalid JWT","content":{"*/*":{"schema":{"$ref":"#/components/schemas/CourseGradeDto"}}}},"403":{"description":"No learner profile / not enrolled in the course","content":{"*/*":{"schema":{"$ref":"#/components/schemas/CourseGradeDto"}}}},"404":{"description":"Course not found","content":{"*/*":{"schema":{"$ref":"#/components/schemas/CourseGradeDto"}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.learning.read"]}]}},"/learning/gradebook/me/course/{id}/elements":{"get":{"tags":["LEARNING: Gradebook"],"summary":"My gradeable elements of a course (Р2 / Р3, 2026-08-13)","description":"Rows: id, type (ASSIGNMENT|QUIZ), title, componentId/componentName/componentKind (MIDTERM_CONTROL|FINAL_EXAM; all null when the work feeds no component), componentWeightPct (the weight of the COMPONENT in the course), elementWeightPct (Р2 — the explicit weight of THIS work INSIDE its component, null when not set), inFormula, maxScore (assignment: its rubric max, null without a rubric; quiz: always 100), myScore (assignment: points; quiz: the percentage of the best counted attempt — null when there is no grade yet), scorePct, state, deadline, windowClosed, attemptsUsed. A submission RETURNED for rework reads as SUBMITTED — this list answers «is there a grade for it», the rework note lives on the assignment card. AWAITING_REVIEW is the quiz whose essay is not marked yet: its score is PARTIAL and does not feed the grade. Ordered by the course's component order, then by title; the work outside the formula comes last.","operationId":"learning_myCourseElements","parameters":[{"name":"id","in":"path","description":"Course id","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"The gradeable work of the course (possibly empty)","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/MyCourseElementDto"}}}}},"401":{"description":"No/invalid JWT","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/MyCourseElementDto"}}}}},"403":{"description":"No learner profile / not enrolled in the course","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/MyCourseElementDto"}}}}},"404":{"description":"Course not found","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/MyCourseElementDto"}}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.learning.read"]}]}},"/learning/grade-scale":{"get":{"tags":["LEARNING: Grade scale"],"summary":"Get the acting grade scale","description":"Returns every step of the ladder, HIGHEST FIRST (A … F). Bounds are INCLUSIVE on both ends: `minPct: 90, maxPct: 94` means 90 and 94 both get this letter, and the server matches a total percent rounded HALF_UP to a whole number (49.50 → 50). The list is never empty: an empty table falls back to the МОН РК ladder. Render it, do NOT re-derive it: neither «percent >= 50» nor the GPA is the rule — FX carries GPA 0.50 and is a fail, and the boundary moves when the admin edits the ladder.","operationId":"learning_scale_1","responses":{"200":{"description":"The acting ladder, highest step first","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/GradeBandDto"}}}}},"401":{"description":"No/invalid JWT","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/GradeBandDto"}}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.learning.read"]}]}},"/learning/flashcard-decks":{"get":{"tags":["LEARNING: Flashcard decks"],"summary":"List course flashcard decks","description":"Deck summaries of the course, newest first: PUBLISHED only for students, including DRAFT for the owning teacher/admin.","operationId":"learning_list_17","parameters":[{"name":"courseId","in":"query","description":"Course id","required":true,"schema":{"type":"string","format":"uuid"},"example":"3f6f4c1e-2c1a-4c5e-9b1e-1a2b3c4d5e6f"}],"responses":{"200":{"description":"Deck summaries","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/FlashcardDeckSummaryDto"}}}}},"401":{"description":"No/invalid JWT","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/FlashcardDeckSummaryDto"}}}}},"403":{"description":"Course is out of the caller's scope","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/FlashcardDeckSummaryDto"}}}}},"404":{"description":"Course not found","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/FlashcardDeckSummaryDto"}}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.learning.read"]}]}},"/learning/flashcard-decks/{id}":{"get":{"tags":["LEARNING: Flashcard decks"],"summary":"Get a flashcard deck with its cards","description":"Deck with cards ordered by orderIndex.","operationId":"learning_getDeck","parameters":[{"name":"id","in":"path","description":"Flashcard deck id","required":true,"schema":{"type":"string","format":"uuid"},"example":"3f6f4c1e-2c1a-4c5e-9b1e-1a2b3c4d5e6f"}],"responses":{"200":{"description":"Deck with cards","content":{"*/*":{"schema":{"$ref":"#/components/schemas/FlashcardDeckDto"}}}},"401":{"description":"No/invalid JWT","content":{"*/*":{"schema":{"$ref":"#/components/schemas/FlashcardDeckDto"}}}},"403":{"description":"Course is out of the caller's scope","content":{"*/*":{"schema":{"$ref":"#/components/schemas/FlashcardDeckDto"}}}},"404":{"description":"Deck not found (or DRAFT requested by a student)","content":{"*/*":{"schema":{"$ref":"#/components/schemas/FlashcardDeckDto"}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.learning.read"]}]}},"/learning/flashcard-decks/course-wide":{"get":{"tags":["LEARNING: Flashcard decks"],"summary":"Колоды карточек ВСЕЙ дисциплины","description":"T-03: колоды, не привязанные ни к одному материалу, — блок на странице дисциплины. Пара к ручке по материалу: вместе они делят колоды курса без остатка, поэтому одна колода не появится на двух экранах сразу.\nСтуденту — только опубликованные; преподавателю дисциплины и администратору портала также черновики.","operationId":"learning_listCourseWide","parameters":[{"name":"courseId","in":"query","description":"Идентификатор дисциплины","required":true,"schema":{"type":"string","format":"uuid"},"example":"3f6f4c1e-2c1a-4c5e-9b1e-1a2b3c4d5e6f"}],"responses":{"200":{"description":"Колоды дисциплины без привязки к материалу","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/FlashcardDeckSummaryDto"}}}}},"401":{"description":"Нет токена или он невалиден","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/FlashcardDeckSummaryDto"}}}}},"403":{"description":"Дисциплина вне области видимости вызывающего","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/FlashcardDeckSummaryDto"}}}}},"404":{"description":"Дисциплина не найдена","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/FlashcardDeckSummaryDto"}}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.learning.read"]}]}},"/learning/flashcard-decks/by-material/{materialId}":{"get":{"tags":["LEARNING: Flashcard decks"],"summary":"Колоды карточек ОДНОГО материала","description":"T-03: то, что студент видит блоком на странице материала. Опубликованные колоды этого материала, новые первыми; преподавателю дисциплины и администратору портала видны и черновики.\nЗдесь колоды, которые преподаватель завёл и опубликовал сам.","operationId":"learning_listByMaterial","parameters":[{"name":"materialId","in":"path","description":"Идентификатор материала","required":true,"schema":{"type":"string","format":"uuid"},"example":"3f6f4c1e-2c1a-4c5e-9b1e-1a2b3c4d5e6f"}],"responses":{"200":{"description":"Колоды материала (может быть пусто)","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/FlashcardDeckSummaryDto"}}}}},"401":{"description":"Нет токена или он невалиден","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/FlashcardDeckSummaryDto"}}}}},"403":{"description":"Дисциплина вне области видимости вызывающего","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/FlashcardDeckSummaryDto"}}}}},"404":{"description":"Материал не найден или недоступен вызывающему","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/FlashcardDeckSummaryDto"}}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.learning.read"]}]}},"/learning/courses":{"get":{"tags":["LEARNING: Courses"],"summary":"List courses in the caller's scope (paged)","description":"The answer is PageResponse{content, page, size, totalElements, totalPages} — NOT a bare array any more. Filtering and sorting happen in the database, so `totalElements` counts exactly the set the page was cut from (the client used to receive every course and slice it itself, which is why the pager never matched the list). TWO SERVER DEFAULTS, both product rules, neither of them the client's to re-implement: the CURRENT academic year, and completed disciplines HIDDEN. An EXPLICIT academicYear/includeCompleted is honoured verbatim for every scope. «Завершённая» is the single PREP-12 definition, widened by D5 — the gradesheet is closed OR the discipline itself is CLOSED OR it is withdrawn from circulation (ARCHIVED) — and «closed» is read from the caller's own point of view, exactly like gradingFinalized below, so the toggle and the badge on one card can never disagree. Returns courses visible to the caller (see tag description for scoping). Empty database or no enrollments → an empty page (content: [], totalElements: 0), not an error. Разрешается она парой (программа, код, учебный год) потока, ОДНИМ пакетным запросом на страницу. null = плана под поток нет либо план компонента не несёт; клиент в обоих случаях просто не рисует тег. Each course carries gradingFinalized — «grading is closed», read from the CALLER's point of view (STUD-23). The student's reading is the one that decides whether his submission and his quiz attempt will be counted (both are 409 when it is true), and it does not flip back to false because a classmate got a retake. Преподаватель и администратор рисуют чип всегда; СТУДЕНТУ чип рисуется только при status!= OPEN — «Открыто» на его карточке не сообщает ничего. Пересдача возвращает дисциплину в OPEN и снимает closedAt. It arrives WITH the page and costs a fixed number of queries whatever the page size — before this the cabinet walked every page of the list and then asked the mastery endpoint once PER discipline, which server-side paging cannot support at all. The three ARRIVE TOGETHER or are ABSENT TOGETHER — a numeric totalElements next to a null completionPct never happens — so the client declares all three nullable and renders their absence as «работать пока не над чем», never as a zero bar. В кабинетах преподавателя и студента они ИГНОРИРУЮТСЯ молча (400 не даётся): у студента нет ящика фильтров вовсе, и ось, применённая к чужой области, молча забрала бы у него дисциплины, которые он обязан видеть. Дефолтов у этих осей нет ни одного. Каждая строка несёт syllabusFilled — наполнен ли поток силлабусом (activationStatus == ACTIVE); это зеркало фильтра noSyllabus.","operationId":"learning_listCourses","parameters":[{"name":"academicYear","in":"query","description":"Учебный год, «2026-2027» через дефис — единый канон платформы. `ALL` = every year. Длинное тире принимается и приводится к дефису; всё остальное отвергается 400, а не молча даёт пустой список.","required":false,"schema":{"type":"string"},"example":"2026-2027"},{"name":"includeCompleted","in":"query","description":"«Показывать завершённые дисциплины».","required":false,"schema":{"type":"boolean"},"example":false},{"name":"trimester","in":"query","description":"Триместр дисциплины (exact match).","required":false,"schema":{"type":"integer","format":"int32"},"example":1},{"name":"status","in":"query","description":"An explicit `includeCompleted=false` next to it is still honoured verbatim.","required":false,"schema":{"type":"string","enum":["OPEN","CLOSED","ARCHIVED"]},"example":"OPEN"},{"name":"component","in":"query","description":"Компонент учебного плана: OK (ОК) | VK (ВК) | KV (КВ). Поток, которому плана не нашлось (расписание завело дисциплину, которой нет ни в одной утверждённой редакции ОП), и план без компонента (публикация из academic старше Д-6) не совпадают ни с одним значением фильтра. До этой волны предикат стоял на курсовой копии колонки, у которой с задачи 5 не осталось писателя, — фильтр отвечал пустой страницей на любое значение.","required":false,"schema":{"type":"string","enum":["OK","VK","KV"]},"example":"OK"},{"name":"search","in":"query","description":"Поиск по коду и трём названиям (ru/kk/en), без учёта регистра.","required":false,"schema":{"type":"string"},"example":"алгор"},{"name":"sort","in":"query","description":"Сортировка, ДЕСЯТЬ значений: title | title_desc | trimester | trimester_desc | year | year_desc | program | program_desc | students | students_desc. Omitted = title. Anything else is 400 — a silently ignored sort makes the screen lie. Every ordering is made total by code+id, so rows do not swap between pages.","required":false,"schema":{"type":"string"},"example":"title"},{"name":"teacherUserId","in":"query","description":"Дисциплины ЭТОГО преподавателя — владельца потока ИЛИ его ассистента (то же множество, что «мои дисциплины» самого преподавателя).","required":false,"schema":{"type":"string"},"example":"9f1c2e41-0000-0000-0000-000000000001"},{"name":"programCode","in":"query","description":"Код образовательной программы. Совпадение по программе строки курса ИЛИ по любой ОП потока (поток бывает общим для нескольких программ).","required":false,"schema":{"type":"string"},"example":"AI_ML"},{"name":"studyLevel","in":"query","description":"Уровень обучения программы (Program.degreeLevel), регистр не важен. BACHELOR дополнительно захватывает программы, у которых уровень не заполнен — на живой базе он пуст у части строк. Список значений не проверяется: неизвестный уровень даёт пустую страницу, а не 400, чтобы новый уровень вуза не требовал правки кода.","required":false,"schema":{"type":"string"},"example":"MASTER"},{"name":"language","in":"query","description":"Язык обучения потока (Course.language), без учёта регистра.","required":false,"schema":{"type":"string"},"example":"ru"},{"name":"noTeacher","in":"query","description":"Только дисциплины БЕЗ преподавателя: teacherUserId пуст или не задан. Ассистент потока преподавателем дисциплину не делает.","required":false,"schema":{"type":"boolean"},"example":true},{"name":"noSyllabus","in":"query","description":"Только дисциплины БЕЗ силлабуса: activationStatus не ACTIVE. Зеркало поля syllabusFilled строки ответа.","required":false,"schema":{"type":"boolean"},"example":true},{"name":"kind","in":"query","description":"Omitted = все виды. Неизвестное значение — 400.","required":false,"schema":{"type":"string"},"example":"DISCIPLINE,PREREQUISITE"},{"name":"page","in":"query","description":"Номер страницы с нуля. Negative = 400.","required":false,"schema":{"type":"integer","format":"int32","default":0},"example":0},{"name":"size","in":"query","description":"Размер страницы. CEILING 100 in every scope — a bigger size is clamped to the ceiling (never refused, never trimmed to nothing): one request must not be able to pull the whole discipline table. The clamp is visible in the answer — `size` and `totalPages` are the applied ones.","required":false,"schema":{"type":"integer","format":"int32"},"example":20}],"responses":{"200":{"description":"One page of the courses in scope (possibly empty)","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PageResponseCourseDto"}}}},"400":{"description":"page below 0, an academicYear in an unknown format, an unknown sort key, or a status/component that is not a value of its enum","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PageResponseCourseDto"}}}},"401":{"description":"No/invalid JWT","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PageResponseCourseDto"}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.learning.read"]}]}},"/learning/courses/{id}":{"get":{"tags":["LEARNING: Courses"],"summary":"Get course tree (course → modules)","description":"Returns the course with its modules (sections), sorted by orderIndex. The elements of a section come from their own endpoints (materials / assignments / quizzes) and are grouped by their moduleId. Consequently EVERY section of the course is returned to every caller who may read it, students included: a section whose content is all closed renders as an EMPTY section, not as a missing one. The remaining startDate/weekNo are the calendar, not a visibility rule. The course block carries gradingFinalized (see the list endpoint). «Освоено» is filled on the LIST row and by GET /competency/me/mastery?courseId=…; this page does not recompute it. Read the nulls as «not asked for here», not as «nothing done».","operationId":"learning_getCourse","parameters":[{"name":"id","in":"path","description":"Course id","required":true,"schema":{"type":"string","format":"uuid"},"example":"3f6f4c1e-2c1a-4c5e-9b1e-1a2b3c4d5e6f"}],"responses":{"200":{"description":"Course tree","content":{"*/*":{"schema":{"$ref":"#/components/schemas/CourseTreeDto"}}}},"401":{"description":"No/invalid JWT","content":{"*/*":{"schema":{"$ref":"#/components/schemas/CourseTreeDto"}}}},"403":{"description":"Course exists but is out of the caller's scope","content":{"*/*":{"schema":{"$ref":"#/components/schemas/CourseTreeDto"}}}},"404":{"description":"Course not found","content":{"*/*":{"schema":{"$ref":"#/components/schemas/CourseTreeDto"}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.learning.read"]}]}},"/learning/courses/{id}/materials":{"get":{"tags":["LEARNING: Courses"],"summary":"List course materials","description":"Materials across all modules of the course. It is NOT «sorted by creation time» — that was the pre-Д-12 behaviour and is what this description used to promise. Metadata only — the presigned download URL comes from GET /materials/{id}. Отдельной страницы у него нет»): an ANNOUNCEMENT row carries its FULL body — `contentHtml` (sanitized HTML, NOT truncated: «Показать полностью» is a client-side collapse, and cutting it here would take away the expansion) plus `authorName` (resolved in ONE batch call for the whole list; null when unknown — a material created before CAMPUS-08 has no author stored, and inventing one would sign it with a person who never wrote it). The date is `publishedAt`, stamped at the FIRST publication. Which rows carry it is stated by the server in `rendersInline`, NOT re-derived from `type`. The three counts `kitArtifactCount` / `kitPendingCount` / `kitReleasedCount` break the built tabs down: how many exist, how many still await the teacher's release and how many are open to students. Without them READY meant three different things at once — «nothing built», «built and waiting for you», «released». In a student's payload all three are `null`, and `null` means «not counted», NOT «zero»: zero is the honest answer «no tabs at all» and reads on screen as «AI materials have not been built». `kitPendingCount` is counted by the very rule the release queue uses (MaterialArtifactRepository.WITH_AI_KIT), so the badge on a row and the queue on the materials dashboard can never disagree.","operationId":"learning_listMaterials","parameters":[{"name":"id","in":"path","description":"Course id","required":true,"schema":{"type":"string","format":"uuid"},"example":"3f6f4c1e-2c1a-4c5e-9b1e-1a2b3c4d5e6f"}],"responses":{"200":{"description":"Materials in the caller's scope (possibly empty)","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/MaterialDto"}}}}},"401":{"description":"No/invalid JWT","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/MaterialDto"}}}}},"403":{"description":"Course exists but is out of the caller's scope","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/MaterialDto"}}}}},"404":{"description":"Course not found","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/MaterialDto"}}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.learning.read"]}]}},"/learning/courses/{id}/items":{"get":{"tags":["LEARNING: Courses"],"summary":"List the course's elements as ONE ordered list","description":"CAMPUS-10 (owner decision 6, verbatim: «Деления на „Материалы к разделу“ и „Задания и тесты“ нет. Один список элементов в порядке, который выставил преподаватель»). Materials, assignments and quizzes of the whole course in the SINGLE Д-12 sequence: section by section (module.orderIndex), and inside a section the position the teacher laid out — a quiz may stand between two materials. Elements that live at COURSE level (an assignment or a quiz with no section) come last, with moduleId null. Its course page drew materials and quizzes in two labelled blocks and never requested the assignments at all, so a task sitting at position 3 of a section was invisible to the student (defect Д-01). Nothing is re-stated here, so a new field of a card reaches this list on its own. An element that has not opened yet is absent for every type. Filtering this list by that flag would therefore leave a manager seeing every assignment and every quiz regardless. The teacher's preview belongs to the CONSTRUCTOR, whose admin DTOs do carry the flag for all three types (ModuleItemDto, AssignmentAdmin*Dto, QuizAdmin*Dto).","operationId":"learning_listItems","parameters":[{"name":"id","in":"path","description":"Course id","required":true,"schema":{"type":"string","format":"uuid"},"example":"3f6f4c1e-2c1a-4c5e-9b1e-1a2b3c4d5e6f"}],"responses":{"200":{"description":"The course's elements in Д-12 order (possibly empty)","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/CourseItemDto"}}}}},"401":{"description":"No/invalid JWT","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/CourseItemDto"}}}}},"403":{"description":"Course exists but is out of the caller's scope","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/CourseItemDto"}}}}},"404":{"description":"Course not found","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/CourseItemDto"}}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.learning.read"]}]}},"/learning/courses/{id}/instances":{"get":{"tags":["LEARNING: Courses"],"summary":"Другие учебные годы этой дисциплины","description":"T-01: у дисциплины теперь по экземпляру на КАЖДЫЙ учебный год (ключ — программа + код + год), и это единственный список, по которому строится переключатель года на её странице. Порядок — НОВЫЙ ГОД ПЕРВЫМ. У каждой строки: id экземпляра (по нему открывают соседний год обычной ручкой GET /courses/{id}), сам год, триместр, статус, frozenAt и current. Оценки, посещаемость, проверка сдач и ведомости на нём работают как обычно: пересдачи прошлого года закрываются в июле, когда новый экземпляр уже заведён. Экран обязан деградировать до просмотра, а не прятать дисциплину. Область — та же, что у самой дисциплины: кому доступна открытая, тому доступен и её список лет; открытие соседнего года проходит свою проверку доступа на своей ручке. Дисциплина, которую ни разу не переносили, отвечает списком из ОДНОЙ строки — это не ошибка, и переключатель в таком случае просто не показывается.","operationId":"learning_listInstances","parameters":[{"name":"id","in":"path","description":"Course id","required":true,"schema":{"type":"string","format":"uuid"},"example":"3f6f4c1e-2c1a-4c5e-9b1e-1a2b3c4d5e6f"}],"responses":{"200":{"description":"Экземпляры дисциплины, новый год первым (минимум один — сам открытый)","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/CourseInstanceDto"}}}}},"401":{"description":"No/invalid JWT","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/CourseInstanceDto"}}}}},"403":{"description":"Course exists but is out of the caller's scope","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/CourseInstanceDto"}}}}},"404":{"description":"Course not found","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/CourseInstanceDto"}}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.learning.read"]}]}},"/learning/courses/by-stream/{streamId}":{"get":{"tags":["LEARNING: Courses"],"summary":"Дисциплина ПОТОКА расписания","description":"Переход «занятие в расписании -> его журнал посещаемости» (решение владельца 15.09.2026, п. 4: у занятия в расписании преподавателя есть кнопка «Отметить»). Расписание адресует занятие ПОТОКОМ и секцией, а журнал живёт по адресу ДИСЦИПЛИНЫ (/courses/{courseId}/attendance) — связь знает только учебный контур: идентификаторы дисциплин learning расписанию неизвестны. Один поток = одна дисциплина (courses.stream_id NOT NULL и уникален), поэтому ответ всегда ровно один. language — язык обучения потока (ru/kk/en), может быть null у потока, которому его не проставили. Чужой преподаватель — 403.","operationId":"learning_getCourseByStream","parameters":[{"name":"streamId","in":"path","description":"Идентификатор потока в расписании (course_streams.id)","required":true,"schema":{"type":"string","format":"uuid"},"example":"ac2fa4b1-0000-0000-0000-000000000001"}],"responses":{"200":{"description":"Дисциплина этого потока","content":{"*/*":{"schema":{"$ref":"#/components/schemas/CourseByStreamDto"}}}},"401":{"description":"No/invalid JWT","content":{"*/*":{"schema":{"$ref":"#/components/schemas/CourseByStreamDto"}}}},"403":{"description":"Дисциплина есть, но вне области вызывающего","content":{"*/*":{"schema":{"$ref":"#/components/schemas/CourseByStreamDto"}}}},"404":{"description":"Дисциплины этого потока в учебном контуре нет","content":{"*/*":{"schema":{"$ref":"#/components/schemas/CourseByStreamDto"}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.learning.read"]}]}},"/learning/content-images/{owner}/{ownerId}/{fileId}":{"get":{"tags":["LEARNING: Content images"],"summary":"An image from a text","description":"Streams the bytes of ONE image (`Cache-Control: private, max-age=300`). THE RULE: the image is given to whoever may see the text it stands in, and exactly when they may see it — the door has no rule of its own. It calls the gate that serves that text, then checks that `fileId` stands as an IMAGE block in the STORED document of that owner. Every refusal is 404 — existence is not disclosed.","operationId":"learning_serve_2","parameters":[{"name":"owner","in":"path","description":"Whose text: material | assignment | assignment-attachment | quiz | quiz-attempt | bank-question | bank-quiz","required":true,"schema":{"type":"string"},"example":"quiz-attempt"},{"name":"ownerId","in":"path","description":"Id of that owner (material, assignment, attachment, quiz, attempt, bank row)","required":true,"schema":{"type":"string","format":"uuid"},"example":"3f6f4c1e-2c1a-4c5e-9b1e-1a2b3c4d5e6f"},{"name":"fileId","in":"path","description":"Storage file id of the image (the IMAGE block's fileId)","required":true,"schema":{"type":"string","format":"uuid"},"example":"a0fcc892-4e5a-465c-8a98-81efd9e484a3"}],"responses":{"200":{"description":"The image bytes","content":{"*/*":{"schema":{"$ref":"#/components/schemas/StreamingResponseBody"}}}},"400":{"description":"ownerId or fileId is not a UUID","content":{"*/*":{"schema":{"$ref":"#/components/schemas/StreamingResponseBody"}}}},"401":{"description":"No/invalid JWT","content":{"*/*":{"schema":{"$ref":"#/components/schemas/StreamingResponseBody"}}}},"404":{"description":"Unknown owner, the text is not visible to the caller right now, or the image does not stand in its stored document","content":{"*/*":{"schema":{"$ref":"#/components/schemas/StreamingResponseBody"}}}},"502":{"description":"The storage is unavailable","content":{"*/*":{"schema":{"$ref":"#/components/schemas/StreamingResponseBody"}}}},"503":{"description":"The storage is overloaded","content":{"*/*":{"schema":{"$ref":"#/components/schemas/StreamingResponseBody"}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.learning.read"]}]}},"/learning/catalog":{"get":{"tags":["LEARNING: Open course catalog"],"summary":"Каталог открытых курсов","description":"Открытые курсы с включённой самозаписью, в обращении и не закончившиеся. В-5: фильтры оценивания, сертификата, сроков, навыков и ведущего; оси складываются через И, значения внутри сроков и навыков — через ИЛИ. Ответ — страница (те же пять ключей, что у любой страницы) и facets: навыки и ведущие, встречающиеся во всём каталоге, с числом курсов — считаются без учёта выбранных фильтров и поиска. enrolled и enrollmentOrigin — запись вызывающего.","operationId":"learning_list_18","parameters":[{"name":"search","in":"query","description":"Поиск по названию ru/kk/en","required":false,"schema":{"type":"string"},"example":"данн"},{"name":"completionMode","in":"query","description":"Оценивание: GRADED — с оценкой, UNGRADED — без оценки","required":false,"schema":{"type":"string","enum":["GRADED","UNGRADED"]},"example":"GRADED"},{"name":"certificate","in":"query","description":"true — только с сертификатом, false — только без","required":false,"schema":{"type":"boolean"},"example":true},{"name":"period","in":"query","description":"Сроки, любой из: RUNNING — идёт сейчас, UPCOMING — скоро начнётся, OPEN_ENDED — без срока; через запятую","required":false,"schema":{"type":"array","items":{"type":"string","enum":["RUNNING","UPCOMING","OPEN_ENDED"]}},"example":"RUNNING,UPCOMING"},{"name":"skillIds","in":"query","description":"Навыки справочника, любой из; через запятую","required":false,"schema":{"type":"array","items":{"type":"string","format":"uuid"}}},{"name":"teacherKeycloakId","in":"query","required":false,"schema":{"type":"string"}},{"name":"page","in":"query","description":"Номер страницы с нуля","required":false,"schema":{"type":"integer","format":"int32","default":0},"example":0},{"name":"size","in":"query","description":"Размер страницы, не больше 100","required":false,"schema":{"type":"integer","format":"int32"},"example":20}],"responses":{"200":{"description":"Страница каталога (бывает пустой) и значения фильтров","content":{"*/*":{"schema":{"$ref":"#/components/schemas/CatalogPageDto"}}}},"400":{"description":"page меньше 0; неизвестное значение оси","content":{"*/*":{"schema":{"$ref":"#/components/schemas/CatalogPageDto"}}}},"403":{"content":{"*/*":{"schema":{"$ref":"#/components/schemas/CatalogPageDto"}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.learning.read"]}]}},"/learning/catalog/{id}":{"get":{"tags":["LEARNING: Open course catalog"],"summary":"Карточка курса каталога","description":"Курс из каталога или курс, на который студент уже записан. Выключенная самозапись прячет курс и по прямой ссылке.","operationId":"learning_get_11","parameters":[{"name":"id","in":"path","description":"Id открытого курса","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Карточка курса","content":{"*/*":{"schema":{"$ref":"#/components/schemas/CatalogCourseDto"}}}},"403":{"content":{"*/*":{"schema":{"$ref":"#/components/schemas/CatalogCourseDto"}}}},"404":{"description":"Курса нет в каталоге и студент на него не записан","content":{"*/*":{"schema":{"$ref":"#/components/schemas/CatalogCourseDto"}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.learning.read"]}]}},"/learning/assignments":{"get":{"tags":["LEARNING: Assignments"],"summary":"List assignments in the caller's scope","description":"Assignments of the caller's courses ordered by deadline. componentId — the assessment component the work feeds (null = feeds nothing; allowed by design). STUD-23: a CLOSED gradesheet (course card's gradingFinalized) refuses a submission ONLY for componentId!= null, so gate «Сдать» on BOTH — the same pair as on the quiz. Render such a row as «приём завершён» and keep «Сдать» dead — POST /assignments/{id}/submissions answers 400 on it. `windowClosed` is the SERVER's answer; do not re-derive it from availableUntil. If you are drawing «что сдавать ближайшим», filter by `!windowClosed` — that is exactly what the Aya deadline rpc and the nightly «дедлайны на неделе» observation do. `availableUntil` is carried on every row for the «доступно до …» label; it is NOT the deadline — the deadline still accepts late work (flagged `late`), the window's end stops the task from being submitted. Такая строка остаётся в списке (это часть программы дисциплины), но кнопки «Сдать» у неё нет, а её `deadline` — СПРАВОЧНАЯ дата: в «что сдавать ближайшим» такая работа не входит, и сервер её уже отфильтровал у себя (Ая, наблюдение «дедлайны на неделе», план недели). Студент пересдал — оба поля снова null, потому что возврат стал историей: печатать вчерашнее замечание над свежей работой нельзя. История возвратов остаётся у карточки задания (GET /assignments/{id}/submissions/my) — здесь только действующее состояние.","operationId":"learning_listAssignments","responses":{"200":{"description":"Assignments in scope (empty list if none)","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/AssignmentListItemDto"}}}}},"401":{"description":"No/invalid JWT","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/AssignmentListItemDto"}}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.learning.read"]}]}},"/learning/assignments/{id}":{"get":{"tags":["LEARNING: Assignments"],"summary":"Get assignment card","description":"Full card: description, deadline, submission format and the grading rubric (criteria with maxPoints, ordered). deadlineWarning is a soft academic-calendar note (deadline on holidays / outside any term), null when the deadline is fine — never a block. componentId — the assessment component this work feeds (null = feeds nothing; allowed by design). STUD-23: a CLOSED gradesheet (course card's gradingFinalized) refuses a submission ONLY for componentId!= null — gate «Сдать» on BOTH, exactly as on the quiz card, instead of letting the student finish the work and meet a 409. Same shape as the closed quiz: the card stays, its content does not. `deadline` при этом остаётся и печатается как справочная дата.","operationId":"learning_getAssignment","parameters":[{"name":"id","in":"path","description":"Assignment id","required":true,"schema":{"type":"string","format":"uuid"},"example":"3f6f4c1e-2c1a-4c5e-9b1e-1a2b3c4d5e6f"}],"responses":{"200":{"description":"Assignment card","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AssignmentDetailDto"}}}},"401":{"description":"No/invalid JWT","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AssignmentDetailDto"}}}},"403":{"description":"Assignment's course is out of the caller's scope","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AssignmentDetailDto"}}}},"404":{"description":"Assignment not found","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AssignmentDetailDto"}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.learning.read"]}]}},"/learning/assignments/{id}/submissions/my":{"get":{"tags":["LEARNING: Assignments"],"summary":"List my submissions for an assignment","description":"The caller's OWN attempt history for the assignment — all versions, newest first (GAP-7, the \"История попыток\" block). Each item carries the same shape as GET /submissions/{id}, including returnComment (the teacher's \"what to fix\" note on a RETURNED version) and the grade block for GRADED versions. Never submitted → empty list. Since 2026-08-12 the card is not gated either, so this history is reachable by walking the course list, not only by holding on to the assignment id; the window now refuses WRITING only (POST /assignments/{id}/submissions → 400).","operationId":"learning_listMySubmissions","parameters":[{"name":"id","in":"path","description":"Assignment id","required":true,"schema":{"type":"string","format":"uuid"},"example":"3f6f4c1e-2c1a-4c5e-9b1e-1a2b3c4d5e6f"}],"responses":{"200":{"description":"My submissions, version desc (empty list if none)","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/SubmissionDto"}}}}},"401":{"description":"No/invalid JWT","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/SubmissionDto"}}}}},"403":{"description":"Course out of scope, or the caller has no Learner row (not a student)","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/SubmissionDto"}}}}},"404":{"description":"Assignment not found","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/SubmissionDto"}}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.learning.read"]}]}},"/learning/assignments/{assignmentId}/attachments/{attachmentId}/file":{"get":{"tags":["LEARNING: Assignment attachment files"],"summary":"Download / stream an attachment of an assignment","description":"Streams the bytes of ONE attachment of the assignment (the brief, the dataset, the report template, the walkthrough video). The presigned storage URL never leaves the docker network — the caller gets a stream, not an address (a signed URL is a bearer pass: whoever it reaches opens the file, with no session). `Content-Type` and `Content-Disposition` (RFC 6266, the original file name) are the SAME headers the file service would emit — they are signed into the storage URL by that very service — so the cabinet renders and saves the file exactly as before. `Range` is carried both ways (206 + `Content-Range`, `Accept-Ranges: bytes`, 416 for a range past the end). An assignment closed a second ago stops serving bytes on the very next request; nothing is cached and no verdict is stored.","operationId":"learning_serve_3","parameters":[{"name":"assignmentId","in":"path","description":"Assignment id","required":true,"schema":{"type":"string","format":"uuid"},"example":"3f6f4c1e-2c1a-4c5e-9b1e-1a2b3c4d5e6f"},{"name":"attachmentId","in":"path","description":"Id of the attachment row (attachments[].id of GET /learning/assignments/{id})","required":true,"schema":{"type":"string","format":"uuid"},"example":"a0fcc892-4e5a-465c-8a98-81efd9e484a3"},{"name":"Range","in":"header","description":"Standard HTTP Range header, carried through to the storage","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"The whole file, streamed","content":{"*/*":{"schema":{"$ref":"#/components/schemas/StreamingResponseBody"}}}},"206":{"description":"The requested byte range","content":{"*/*":{"schema":{"$ref":"#/components/schemas/StreamingResponseBody"}}}},"401":{"description":"No/invalid JWT","content":{"*/*":{"schema":{"$ref":"#/components/schemas/StreamingResponseBody"}}}},"403":{"description":"Assignment's course is out of the caller's scope","content":{"*/*":{"schema":{"$ref":"#/components/schemas/StreamingResponseBody"}}}},"404":{"description":"Attachment not found; it belongs to another assignment; a DRAFT / not-yet-open / past-deadline / condition-not-met assignment requested by a student; a page attachment, which carries no file at all; or the object is missing in storage (all indistinguishable on purpose)","content":{"*/*":{"schema":{"$ref":"#/components/schemas/StreamingResponseBody"}}}},"416":{"description":"The requested range lies past the end of the file","content":{"*/*":{"schema":{"$ref":"#/components/schemas/StreamingResponseBody"}}}},"502":{"description":"The storage is unavailable","content":{"*/*":{"schema":{"$ref":"#/components/schemas/StreamingResponseBody"}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.learning.read"]}]}},"/competency/me/trajectory":{"get":{"tags":["LEARNING: Competency"],"summary":"My roadmap (light, read-only)","description":"Owner-only light roadmap of the calling learner: the chosen goal and the disciplines of the learner's curriculum with their status, recomputed on every read. Nodes are the plan rows of the learner's programme for the current academic year plus every stream he is really enrolled in (an elective of another programme, a stream outside the plan); withdrawn disciplines are skipped. status: DONE (enrollment COMPLETED), IN_PROGRESS (ACTIVE), FAILED (a failed enrollment without a retake), AVAILABLE (not enrolled, all prerequisites DONE) or LOCKED. nodeId = courseId = the plan row id (or the stream id outside the plan) — deterministic, and the key of GET /me/trajectory/skills, NOT the address of a course page. year = ceil(trimester / 3); trimesterCredits — the credits of the row per plan slot, their sum = credits; a multi-trimester row is DONE only when the stream of its LAST part is completed. targetTracks — the chosen goal (one, T9) or empty. The only write is a one-time fill of the learner's missing programme from his own enrollments (STUD-04). Goal readiness, areas and skills live in GET /me/trajectory/overview.","operationId":"learning_myTrajectory","responses":{"200":{"description":"Roadmap: chosen goal and curriculum nodes","content":{"*/*":{"schema":{"$ref":"#/components/schemas/TrajectoryDto"}}}},"400":{"description":"Cyclic prerequisites in the curriculum (dirty data)","content":{"*/*":{"schema":{"$ref":"#/components/schemas/TrajectoryDto"}}}},"401":{"description":"No/invalid JWT","content":{"*/*":{"schema":{"$ref":"#/components/schemas/TrajectoryDto"}}}},"404":{"description":"Caller has no learner profile","content":{"*/*":{"schema":{"$ref":"#/components/schemas/TrajectoryDto"}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.learning.read"]}]}},"/competency/me/trajectory/skills":{"get":{"tags":["LEARNING: Competency"],"summary":"Skill maps of my trajectory courses","description":"Owner-only (phase 3, T5): for every node of the CALLER'S OWN roadmap (the program-RUP roadmap, same node set as GET /me/trajectory), the skills that course builds — union of its learning outcomes' mapsToSkills edges, in first-appearance order, pending-moderation skills excluded. Courses are ordered by trimester then code, matching the trajectory nodes. A caller without a Learner/Trajectory (or without a program) gets an empty list.","operationId":"learning_myTrajectorySkills","responses":{"200":{"description":"Per-course skill maps of the caller's trajectory (possibly empty)","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/CourseSkillsDto"}}}}},"401":{"description":"No/invalid JWT","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/CourseSkillsDto"}}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.learning.read"]}]}},"/competency/me/trajectory/overview":{"get":{"tags":["LEARNING: Competency"],"summary":"My trajectory overview","description":"state and goal are exactly GET /me/goal. a skill counted only through a close skill). inProgressSkillCount per area — «Learning: N», the number of its LEARNING skills (pct counts obtained skills only). whereToLearn per area: roadmap disciplines teaching any of its skills (status IN_PROGRESS for the current trimester / AHEAD / DONE, courseId = the stream the student is enrolled in, null when not enrolled) followed by projects the student is currently in whose skills overlap (kind PROJECT, projectId). nextSteps — ALWAYS, up to 20, by date: published assignments of ACTIVE enrollments whose window is open, that require a submission, have no access lock, a deadline ahead and no own submission (or a RETURNED one); and open tests not attempted yet whose window closes ahead (a test without a closing date is not a step). raisesAreaIds — goal areas that contain skills of the work's discipline (the skills of its learning outcomes), in area order; empty without a goal or when the discipline gives no goal skill. otherConfirmedSkills — confirmed skills outside the goal (all confirmed skills when there is no goal).","operationId":"learning_myTrajectoryOverview","responses":{"200":{"description":"Overview (state NO_GOAL / NO_SKILLS / READY)","content":{"*/*":{"schema":{"$ref":"#/components/schemas/TrajectoryOverviewDto"}}}},"401":{"description":"No/invalid JWT","content":{"*/*":{"schema":{"$ref":"#/components/schemas/TrajectoryOverviewDto"}}}},"403":{"content":{"*/*":{"schema":{"$ref":"#/components/schemas/TrajectoryOverviewDto"}}}},"404":{"description":"Caller has no learner profile","content":{"*/*":{"schema":{"$ref":"#/components/schemas/TrajectoryOverviewDto"}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.learning.read"]}]}},"/competency/me/mastery":{"get":{"tags":["LEARNING: Competency"],"summary":"My mastery","description":"Without courseId — all mastery records of the caller (skill code/names, Khan band, BKT probability, lastEventAt), sorted by skill code; a caller without a Learner row (teacher/admin) gets an empty list. With courseId — ALL skills of that course (union of its learning outcomes' skill edges): skills without evidence come with probability 0 and null band, plus the coursePct aggregate = average probability over the course skills x 100 (deterministic, missing evidence counts as 0). The courseId branch ALSO returns the course-work progress of the caller: completedElements / totalElements over the PUBLISHED assignments (turned in — a RETURNED work is open again) and PUBLISHED quizzes (attempted) of the course, and completionPct = their share x 100. That is the honest «освоено» of a course card (there is no manual lesson tick); it is NULL together with the counters when the course has nothing published yet, and for a caller without a Learner row.","operationId":"learning_myMastery","parameters":[{"name":"courseId","in":"query","description":"Scope to one course and add the coursePct aggregate + the course-work progress counters","required":false,"schema":{"type":"string","format":"uuid"},"example":"3f6f4c1e-2c1a-4c5e-9b1e-1a2b3c4d5e6f"}],"responses":{"200":{"description":"Mastery overview (records possibly empty)","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MasteryOverviewDto"}}}},"401":{"description":"No/invalid JWT","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MasteryOverviewDto"}}}},"403":{"description":"courseId given but the course is out of the caller's scope","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MasteryOverviewDto"}}}},"404":{"description":"courseId given but course not found","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MasteryOverviewDto"}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.learning.read"]}]}},"/competency/me/mastery/{skillId}/explain":{"get":{"tags":["LEARNING: Competency"],"summary":"Explain my mastery of a skill","description":"The record is rebuilt from the evidence log on every change: a closed course grade gives the course's skills a level by the final grade (90-100 Mastered, 75-89 Proficient, other passes Familiar), a verified certificate exactly Familiar, the entry assessment and confirmed project contributions fold by BKT (project: floor Familiar); the effective level is the highest. Returns the current band/probability, a freshness view (probability decayed to now by the forgetting parameter — the stored record itself never rolls back with time) with the days since the last evidence, the rebuild snapshot in evidenceRefs (which source decided the level, per-source counts) and the recent counted observations (cap 10, most recent first). The path is inherently self-scoped; a caller without a Learner row or without a record on the skill gets 404.","operationId":"learning_explainMastery","parameters":[{"name":"skillId","in":"path","description":"Skill id to explain","required":true,"schema":{"type":"string","format":"uuid"},"example":"3f6f4c1e-2c1a-4c5e-9b1e-1a2b3c4d5e6f"}],"responses":{"200":{"description":"BKT breakdown for the skill","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MasteryExplainDto"}}}},"401":{"description":"No/invalid JWT","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MasteryExplainDto"}}}},"404":{"description":"Caller has no Learner row or no mastery on the skill","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MasteryExplainDto"}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.learning.read"]}]}},"/competency/me/goal":{"get":{"tags":["LEARNING: Competency"],"summary":"My goal and goal readiness","description":"The caller's goal (the career track chosen on the trajectory) with the goal readiness by the T7 formula: area % = floor(average points of the area's visible skills; Familiar 50, Proficient 75, Mastered 100, Attempted/no record 0), readiness = floor(weighted average of area % by area weight); step 1..5 (0-29 / 30-49 / 50-69 / 70-89 / 90-100); confirmed/total — confirmed and all distinct visible skills of the goal; weakest — the area with the lowest % (ties: bigger weight, then order). A skill counts at the level of an approved close skill when that level is higher than its own. Read-only. state: NO_GOAL (goal = null) — no goal chosen or the goal was deleted; NO_SKILLS — the goal has no areas with visible skills yet (readinessPct/step/weakest = null, confirmed = total = 0); READY — full summary.","operationId":"learning_myGoal","responses":{"200":{"description":"Goal summary (possibly NO_GOAL / NO_SKILLS)","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MyGoalDto"}}}},"401":{"description":"No/invalid JWT","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MyGoalDto"}}}},"403":{"content":{"*/*":{"schema":{"$ref":"#/components/schemas/MyGoalDto"}}}},"404":{"description":"Caller has no learner profile","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MyGoalDto"}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.learning.read"]}]}},"/competency/courses/{id}/skills":{"get":{"tags":["LEARNING: Competency"],"summary":"Course skill map","description":"Skills the course builds: union of its learning outcomes' mapsToSkills edges, in first-appearance order (outcomes by orderIndex).","operationId":"learning_courseSkills","parameters":[{"name":"id","in":"path","description":"Course id","required":true,"schema":{"type":"string","format":"uuid"},"example":"3f6f4c1e-2c1a-4c5e-9b1e-1a2b3c4d5e6f"}],"responses":{"200":{"description":"Skills of the course (possibly empty)","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/SkillDto"}}}}},"401":{"description":"No/invalid JWT","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/SkillDto"}}}}},"403":{"description":"Course is out of the caller's scope","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/SkillDto"}}}}},"404":{"description":"Course not found","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/SkillDto"}}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.learning.read"]}]}},"/competency/career/tracks":{"get":{"tags":["LEARNING: Competency"],"summary":"Goals to choose from","description":"Each goal carries areaCount (areas with at least one visible skill) and skillCount (distinct visible skills).","operationId":"learning_careerTracks","responses":{"200":{"description":"Goals (possibly empty)","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/CareerTrackDto"}}}}},"401":{"description":"No/invalid JWT","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/CareerTrackDto"}}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.learning.read"]}]}},"/academic/workload/refs/match-criteria":{"get":{"tags":["ACADEMIC: Workload References"],"summary":"Веса рейтинга критериев","description":"6 критериев рейтинга соответствия ППС учебной строке с редактируемыми весами (COMPETENCY/EXPERIENCE/LANGUAGE_DIGITAL/BALANCE/KPI_TRAJECTORY/QUALITY), версией на учебный год (E3-У7, дефолт ТЗ: 0.30/0.15/0.15/0.20/0.10/0.10). Σ весов = 1.000. Трёхъязычно.","operationId":"academic_matchCriteria","parameters":[{"name":"academicYear","in":"query","description":"Учебный год-версия, формат 2026-2027; по умолчанию — текущий пилотный год","required":false,"schema":{"type":"string"},"example":"2026-2027"}],"responses":{"200":{"description":"Критерии рейтинга года","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/MatchCriterionDto"}}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.academic.read"]}]}},"/academic/versions/{vId}/learning-outcomes":{"get":{"tags":["ACADEMIC: Academic Learning Outcomes (результаты обучения редакции)"],"summary":"Результаты обучения редакции","description":"Результаты обучения версии в натуральном порядке кода (ON2 раньше ON10) с текстами на трёх языках, глаголом и уровнем Блума, кодами компетенций и кодами дисциплин этой редакции, которые их формируют. Результат с пустым disciplineCodes публикация в учебный контур не повезёт: в каноне результат живёт только на строке плана.","operationId":"academic_list","parameters":[{"name":"vId","in":"path","description":"ID версии ОП","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Результаты обучения версии (может быть пусто)","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/VersionOutcomeDto"}}}}},"404":{"description":"Версия не найдена","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/VersionOutcomeDto"}}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.academic.read"]}]}},"/academic/versions/{vId}/disciplines/{did}":{"get":{"tags":["ACADEMIC: Academic Disciplines"],"summary":"Дисциплина по id","description":"Карточка дисциплины. Должна принадлежать указанной версии, иначе 404. attachedTeacherKeycloakIds — преподаватели, закреплённые за дисциплиной по записи глобального реестра (расписанием или руками). kind — признак строки плана (лейбл, не null); trimesterCredits — доли по триместрам ([] = один триместр; у многотриместровой строки trimester = первый триместр списка).","operationId":"academic_get","parameters":[{"name":"vId","in":"path","description":"ID версии","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"did","in":"path","description":"ID дисциплины","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Дисциплина","content":{"*/*":{"schema":{"$ref":"#/components/schemas/DisciplineDto"}}}},"404":{"description":"Версия/дисциплина не найдена или не принадлежит версии","content":{"*/*":{"schema":{"$ref":"#/components/schemas/DisciplineDto"}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.academic.read"]}]}},"/academic/versions/{vId}/curriculum":{"get":{"tags":["ACADEMIC: Academic Curriculum (РУП)"],"summary":"Учебный план версии","description":"Текущий РУП версии: раскладка дисциплина→триместр, суммы кредитов (total/mandatory/university/elective), суммы по триместрам и предупреждения перегруза (порог — CreditNorm.trimesterCreditThreshold уровня квалификации программы, тот же, что у валидатора слоя 1). Суммы всегда пересчитываются из ВСЕХ актуальных дисциплин версии — раскладка задаёт только триместр, а не состав: пока план не сохранён, суммы уже верны, а триместр берётся из собственного поля дисциплины (то же правило, что на клиенте). Дисциплина без триместра входит в суммы, но не попадает в trimesterCredits. Нули — только у версии без дисциплин. academicYear — учебный год плана, снимок года редакции («2026-2027»). В trimesterLayout ответа её нет вовсе: раскладка к ней не применяется. Перегруз (warnings) сверяется с trimesterCreditsStudent — нагрузкой одного студента, из направления идёт одна альтернатива.","operationId":"academic_get_1","parameters":[{"name":"vId","in":"path","description":"ID версии","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Учебный план (раскладка пуста, пока не сохранён; суммы кредитов верны в любом случае)","content":{"*/*":{"schema":{"$ref":"#/components/schemas/CurriculumPlanDto"}}}},"404":{"description":"Версия не найдена","content":{"*/*":{"schema":{"$ref":"#/components/schemas/CurriculumPlanDto"}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.academic.read"]}]}},"/academic/syllabus-approver-chain":{"get":{"tags":["ACADEMIC: Syllabus Approver Chain (Кто утверждает силлабус)"],"summary":"Цепочка утверждающих и кто утверждает сейчас","description":"Без schoolDepartmentId — цепочка ВУЗА; hasCarrier у шага означает «носитель есть хоть где-то», acting и explanation при этом пусты (действующий утверждающий определяется только для конкретной школы). С schoolDepartmentId — цепочка, действующая ДЛЯ ЭТОЙ школы (своя, иначе вузовская: inherited=true), hasCarrier считается по этой школе, acting = действующий утверждающий, explanation — готовая трёхъязычная подпись («Декан» / «Проректор, декан не назначен»). customized=true — цепочку менял вуз, а не сид. availableFunctions — полный справочник функций для выбора шагов (лейблы отдаёт бэк).","operationId":"academic_get_2","parameters":[{"name":"schoolDepartmentId","in":"query","description":"Школа, для которой смотрим цепочку; не задано = цепочка вуза","required":false,"schema":{"type":"integer","format":"int64"},"example":27}],"responses":{"200":{"description":"Цепочка + действующий утверждающий","content":{"*/*":{"schema":{"$ref":"#/components/schemas/SyllabusApproverChainDto"}}}},"401":{"description":"Не аутентифицирован","content":{"*/*":{"schema":{"$ref":"#/components/schemas/SyllabusApproverChainDto"}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.academic.read"]}]}},"/academic/syllabus-admin/rubric-template":{"get":{"tags":["ACADEMIC: Syllabus Admin: Rubric Template"],"summary":"Действующий шаблон рубрики","description":"Шаблон целиком, все три языка сразу: его читает и учебный отдел, и редактор силлабуса. Выбора языка здесь нет.","operationId":"academic_getTemplate","responses":{"200":{"description":"Действующий шаблон рубрики","content":{"*/*":{"schema":{"$ref":"#/components/schemas/RubricTemplateRefDto"}}}},"404":{"description":"Действующий шаблон не найден","content":{"*/*":{"schema":{"$ref":"#/components/schemas/RubricTemplateRefDto"}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.academic.read"]}]}},"/academic/syllabi/{sid}/week-plan":{"get":{"tags":["ACADEMIC: Syllabus Week Plan"],"summary":"План недель","description":"Все недели версии с часами, семинаром, заданиями СРС и событиями. Дополнительно возвращает сверку часов плана с часами паспорта по каждому виду занятий и сверку часов музея с обязательными — расхождение показывается замечанием, но записи не отменяет.","operationId":"academic_getWeekPlan","parameters":[{"name":"sid","in":"path","description":"Идентификатор силлабуса","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"План недель","content":{"*/*":{"schema":{"$ref":"#/components/schemas/WeekPlanSetDto"}}}},"404":{"description":"Силлабус не найден","content":{"*/*":{"schema":{"$ref":"#/components/schemas/WeekPlanSetDto"}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.academic.read"]}]}},"/academic/syllabi/{sid}/sections/{sectionKey}":{"get":{"tags":["ACADEMIC: Syllabus"],"summary":"Раздел силлабуса","description":"Один раздел активной версии. У версии ОДИН язык, выбранный при создании, — выбора языка на разделе нет. Поле freeText говорит, свободная ли это проза (такие разделы правит PUT), autoComplete — считается ли раздел заполненным автоматически по данным других экранов.","operationId":"academic_getSection","parameters":[{"name":"sid","in":"path","description":"ID силлабуса","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"sectionKey","in":"path","description":"Ключ раздела (OVERVIEW/METHODS/ASSESSMENT/...)","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Раздел","content":{"*/*":{"schema":{"$ref":"#/components/schemas/SyllabusSectionDto"}}}},"400":{"description":"Неизвестный ключ раздела","content":{"*/*":{"schema":{"$ref":"#/components/schemas/SyllabusSectionDto"}}}},"404":{"description":"Силлабус / его версия / раздел не найдены","content":{"*/*":{"schema":{"$ref":"#/components/schemas/SyllabusSectionDto"}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.academic.read"]}]}},"/academic/syllabi/{sid}/rubric":{"get":{"tags":["ACADEMIC: Syllabus Course Rubric"],"summary":"Курсовая рубрика","description":"Критерии версии с индикаторами и текстами уровней, вводный абзац и подписи уровней с процентными полосами. Полосы выводятся из шкалы оценок и не хранятся.","operationId":"academic_getRubric","parameters":[{"name":"sid","in":"path","description":"Идентификатор силлабуса","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Курсовая рубрика","content":{"*/*":{"schema":{"$ref":"#/components/schemas/CourseRubricDto"}}}},"404":{"description":"Силлабус не найден","content":{"*/*":{"schema":{"$ref":"#/components/schemas/CourseRubricDto"}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.academic.read"]}]}},"/academic/syllabi/{sid}/passport":{"get":{"tags":["ACADEMIC: Syllabus Passport"],"summary":"Паспорт курса","description":"Паспорт активной версии: часы по видам занятий, кредиты, триместр, реквизиты и преподаватель. Значения — снимок на момент последнего обновления, а не живые данные плана: утверждённый документ не должен меняться вслед за правкой учебного плана.","operationId":"academic_passport","parameters":[{"name":"sid","in":"path","description":"Идентификатор силлабуса","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Паспорт курса","content":{"*/*":{"schema":{"$ref":"#/components/schemas/SyllabusPassportDto"}}}},"404":{"description":"Силлабус не найден","content":{"*/*":{"schema":{"$ref":"#/components/schemas/SyllabusPassportDto"}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.academic.read"]}]}},"/academic/syllabi/{sid}/course-parameters":{"get":{"tags":["ACADEMIC: Syllabus Assessment"],"summary":"Параметры курса","description":"Пороги допуска и посещаемости, спецификация экзамена, обязательные часы музея, канал связи и режим использования ИИ. Пустой порог означает, что действует настройка кампуса.","operationId":"academic_getCourseParameters","parameters":[{"name":"sid","in":"path","description":"Идентификатор силлабуса","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Параметры курса","content":{"*/*":{"schema":{"$ref":"#/components/schemas/CourseParametersDto"}}}},"404":{"description":"Силлабус не найден","content":{"*/*":{"schema":{"$ref":"#/components/schemas/CourseParametersDto"}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.academic.read"]}]}},"/academic/syllabi/{sid}/assignments/{aid}/rubric":{"get":{"tags":["ACADEMIC: Syllabus Assignments"],"summary":"Рубрика задания","description":"Выбранные критерии курсовой рубрики с баллами, их индикаторами и текстами уровней; максимум задания — сумма баллов. Доступ: чтение сотрудника.","operationId":"academic_getAssignmentRubric","parameters":[{"name":"sid","in":"path","description":"Идентификатор силлабуса","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"aid","in":"path","description":"Идентификатор задания","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Рубрика задания","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AssignmentRubricDto"}}}},"404":{"description":"Задание не найдено","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AssignmentRubricDto"}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.academic.read"]}]}},"/academic/syllabi/{sid}/assessment":{"get":{"tags":["ACADEMIC: Syllabus Assessment"],"summary":"Схема оценивания","description":"Периоды версии с элементами, суммами баллов и готовыми формулами итоговой оценки, плюс мягкие замечания (перебор баллов периода, сумма весов не 100 и подобные) — они показываются, но записи не отменяют.","operationId":"academic_getAssessment","parameters":[{"name":"sid","in":"path","description":"Идентификатор силлабуса","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Схема оценивания","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AssessmentSetDto"}}}},"404":{"description":"Силлабус не найден","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AssessmentSetDto"}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.academic.read"]}]}},"/academic/catalog/teachers/{keycloakId}/disciplines":{"get":{"tags":["ACADEMIC: Academic Catalog Disciplines"],"summary":"Дисциплины преподавателя","description":"Дисциплины реестра, закреплённые за преподавателем (keycloak sub). Пустой список — законное состояние (ассистент). Существование преподавателя на чтении НЕ проверяется — неизвестный sub даёт пустой список, не 404.","operationId":"academic_disciplinesOf","parameters":[{"name":"keycloakId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Список дисциплин (может быть пуст)","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/CatalogDisciplineDto"}}}}},"400":{"description":"keycloakId — не UUID","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/CatalogDisciplineDto"}}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.academic.read"]}]}},"/academic/catalog/disciplines/{id}":{"get":{"tags":["ACADEMIC: Academic Catalog Disciplines"],"summary":"Дисциплина реестра по id","description":"Карточка дисциплины глобального реестра.","operationId":"academic_get_3","parameters":[{"name":"id","in":"path","description":"ID дисциплины реестра","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Дисциплина","content":{"*/*":{"schema":{"$ref":"#/components/schemas/CatalogDisciplineDto"}}}},"404":{"description":"Дисциплина не найдена","content":{"*/*":{"schema":{"$ref":"#/components/schemas/CatalogDisciplineDto"}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.academic.read"]}]}},"/academic/assessment-methods/{id}":{"get":{"tags":["ACADEMIC: Academic Assessment Methods"],"summary":"Метод оценивания по id","description":"Карточка метода оценивания.","operationId":"academic_get_4","parameters":[{"name":"id","in":"path","description":"ID метода","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Метод","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AssessmentMethodDto"}}}},"404":{"description":"Метод не найден","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AssessmentMethodDto"}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.academic.read"]}]}},"/academic/workload/plans":{"get":{"tags":["ACADEMIC: Workload Plans"],"summary":"Список планов педнагрузки","description":"Планы, отфильтрованные по школе (query schoolDepartmentId). Сортировка — по дате создания, свежие сверху.","operationId":"academic_plans","parameters":[{"name":"schoolDepartmentId","in":"query","description":"Фильтр по школе (OrgDepartment.id); без параметра — все доступные актору","required":false,"schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"Список планов (в рамках прав актора)","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/WorkloadPlanDto"}}}}},"403":{"content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/WorkloadPlanDto"}}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.academic.read"]}]}},"/academic/workload/plans/{planId}/demand/lines":{"get":{"tags":["ACADEMIC: Workload Plans"],"summary":"Строки потребности плана","description":"Вся потребность плана (CURRICULUM из ОП + MANUAL ручные), в порядке заведения. totalHours — снимок = hoursPerGroup × (streamFlag? 1: groupCount).","operationId":"academic_demandLines","parameters":[{"name":"planId","in":"path","description":"ID плана","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Строки потребности","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/WorkloadDemandLineDto"}}}}},"403":{"description":"Нет прав на чтение этого плана","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/WorkloadDemandLineDto"}}}}},"404":{"description":"План не найден","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/WorkloadDemandLineDto"}}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.academic.read"]}]}},"/academic/workload/plans/{planId}/appeals":{"get":{"tags":["ACADEMIC: Workload Teacher Sheet"],"summary":"Апелляции плана","description":"Все апелляции плана (список для директора). Доступ: директор школы плана / проректор / администратор платформы (fail-closed — прочим 403).","operationId":"academic_appeals","parameters":[{"name":"planId","in":"path","description":"id плана педнагрузки","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Список апелляций","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/AppealDto"}}}}},"403":{"description":"Нет права чтения плана","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/AppealDto"}}}}},"404":{"description":"План не найден","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/AppealDto"}}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.academic.read"]}]}},"/academic/workload/plans/{planId}/allocations":{"get":{"tags":["ACADEMIC: Workload Allocation"],"summary":"Назначения плана + реестр нераспределённого","description":"Все назначения плана (кто на какую строку, доля, часы, признак перегруза/ручной правки) + реестр нераспределённого: строки потребности без ПОЛНОЙ суммы долей, с причиной (NO_TEACHERS — команда плана не собрана, соберите ППС: пересчёт оценок на пустой команде ничего не даст; NOT_SCORED — команда есть, но оценки по строке не рассчитаны, нажмите «пересчитать»; NO_ELIGIBLE — оценки есть, допустимых нет; NO_CAPACITY — не хватило ёмкости; PARTIAL_SHARES — Σ долей < 100%).","operationId":"academic_allocations","parameters":[{"name":"planId","in":"path","description":"ID плана","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Назначения + реестр нераспределённого","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AllocationsDto"}}}},"403":{"description":"Нет прав на чтение этого плана","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AllocationsDto"}}}},"404":{"description":"План не найден","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AllocationsDto"}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.academic.read"]}]}},"/academic/versions/{vId}/elective-groups":{"get":{"tags":["ACADEMIC: Academic Elective Groups (направления)"],"summary":"Направления редакции","description":"Направления версии по orderIndex, затем по коду. members — участники направления (disciplineId, код, трёхъязычное название, кредиты, триместр, номер альтернативы), отсортированы по номеру альтернативы (пустой номер — в конец), затем по коду. Названия печатаются из записи базы дисциплин, и только при её отсутствии — из исторических полей строки плана. Направление без участников — законное состояние: оно остаётся в списке с пустым members, но в каталог записи студента не попадает.","operationId":"academic_list_1","parameters":[{"name":"vId","in":"path","description":"ID версии","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Направления версии","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/ElectiveGroupDto"}}}}},"404":{"description":"Версия не найдена","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/ElectiveGroupDto"}}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.academic.read"]}]}},"/academic/versions/{vId}/disciplines":{"get":{"tags":["ACADEMIC: Academic Disciplines"],"summary":"Дисциплины версии ОП","description":"Список дисциплин под версию (по коду). cycle/component/controlForm/instructionLanguages — с трёхъязычным лейблом; activityHours — часы по видам занятий (по lessonType); academicYear — снимок учебного года редакции в написании «2026-2027». catalog — запись базы дисциплин, на которую ссылается строка: {id, code, nameKk, nameRu, nameEn, classifierCode, verified, source}. Печатать название и классификаторный код нужно ОТТУДА; null остаётся только у строк, заведённых до привязки, и тогда клиент падает обратно на исторические поля строки. attachedTeacherKeycloakIds — keycloak sub преподавателей, закреплённых за записью базы дисциплин: и назначенные расписанием (ведущий потока, ассистент, преподаватель практической группы), и проставленные руками. Пусто — закреплений нет. Только чтение: набор задают расписание и форма закрепления. kind — признак строки плана с трёхъязычным лейблом: REGULAR (учебная дисциплина), PRACTICE, RESEARCH_WORK, FINAL_ATTESTATION; никогда не null (строка до волны читается как REGULAR). trimesterCredits — доли по триместрам [{trimester, credits}] по возрастанию триместра: [] — дисциплина одного триместра; непустой — строка идёт в нескольких триместрах, её trimester = ПЕРВЫЙ триместр списка, и раскладка РУП к ней не применяется.","operationId":"academic_list_2","parameters":[{"name":"vId","in":"path","description":"ID версии","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Список дисциплин","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/DisciplineDto"}}}}},"404":{"description":"Версия не найдена","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/DisciplineDto"}}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.academic.read"]}]}},"/academic/syllabus-admin/policy-defaults":{"get":{"tags":["ACADEMIC: Syllabus Admin: Policy Defaults"],"summary":"Ревизии правил вуза","description":"Список ревизий, новые сверху: номер, действующая ли, происхождение, дата введения и автор.","operationId":"academic_listDefaults","responses":{"200":{"description":"Ревизии правил","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/PolicyDefaultsSummaryDto"}}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.academic.read"]}]}},"/academic/syllabus-admin/assessment-periods":{"get":{"tags":["ACADEMIC: Syllabus Admin: Assessment References"],"summary":"Периоды оценивания","description":"Все периоды справочника, включая отключённые, в порядке печати.","operationId":"academic_listPeriods","responses":{"200":{"description":"Периоды оценивания","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/AssessmentPeriodRefDto"}}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.academic.read"]}]}},"/academic/syllabus-admin/assessment-forms":{"get":{"tags":["ACADEMIC: Syllabus Admin: Assessment References"],"summary":"Формы оценивания","description":"Все формы справочника, включая отключённые, в порядке печати.","operationId":"academic_listForms","responses":{"200":{"description":"Формы оценивания","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/AssessmentFormRefDto"}}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.academic.read"]}]}},"/academic/syllabi":{"get":{"tags":["ACADEMIC: Syllabus"],"summary":"Список силлабусов","description":"Карточки силлабусов для экрана «база силлабусов» (новые сверху). status — фильтрует ВНУТРИ области (в публичной области непубличный статус даёт пустой список). Карточка обогащена: название дисциплины (ru/kk/en, fallback — код курса), код ОП (programCode, «» если неизвестен), кредиты, ФИО ответственного (null если не резолвится), учебный год, прогресс разделов (sectionsComplete/sectionsTotal=14). Статус — с трёхъязычным лейблом. Принадлежность силлабуса курсу определяется ТОЛЬКО по этому набору: courseId — первый из него и оставлен ради читателей, написанных до перехода на потоки. Пустой набор = силлабус ещё ни разу не доехал до LMS.","operationId":"academic_list_3","parameters":[{"name":"status","in":"query","description":"Фильтр по статусу силлабуса (внутри области)","required":false,"schema":{"type":"string"}},{"name":"mine","in":"query","description":"true — мои (я ответственный преподаватель дисциплины), все статусы; иначе — только публичные всех преподавателей","required":false,"schema":{"type":"boolean"}}],"responses":{"200":{"description":"Список силлабусов","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/SyllabusSummaryDto"}}}}},"400":{"description":"Неизвестный статус в фильтре","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/SyllabusSummaryDto"}}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.academic.read"]}]}},"/academic/syllabi/{sid}/tools":{"get":{"tags":["ACADEMIC: Syllabus Content"],"summary":"Цифровые инструменты курса","description":"Список инструментов версии. Доступ: чтение сотрудника.","operationId":"academic_listTools","parameters":[{"name":"sid","in":"path","description":"Идентификатор силлабуса","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Цифровые инструменты","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/DigitalToolDto"}}}}},"404":{"description":"Силлабус не найден","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/DigitalToolDto"}}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.academic.read"]}]}},"/academic/syllabi/{sid}/teaching-methods":{"get":{"tags":["ACADEMIC: Syllabus Content"],"summary":"Выбранные методы преподавания","description":"Методы, выбранные для этой версии из справочника вуза. Доступ: чтение сотрудника.","operationId":"academic_listMethodRefs","parameters":[{"name":"sid","in":"path","description":"Идентификатор силлабуса","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Методы преподавания версии","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/TeachingMethodRefDto"}}}}},"404":{"description":"Силлабус не найден","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/TeachingMethodRefDto"}}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.academic.read"]}]}},"/academic/syllabi/{sid}/outcomes":{"get":{"tags":["ACADEMIC: Syllabus Content"],"summary":"Результаты обучения дисциплины","description":"Список РОД версии в порядке кода. Доступ: чтение сотрудника.","operationId":"academic_listOutcomes","parameters":[{"name":"sid","in":"path","description":"Идентификатор силлабуса","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Результаты обучения дисциплины","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/DisciplineOutcomeDto"}}}}},"404":{"description":"Силлабус не найден","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/DisciplineOutcomeDto"}}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.academic.read"]}]}},"/academic/syllabi/{sid}/literature":{"get":{"tags":["ACADEMIC: Syllabus Content"],"summary":"Литература курса","description":"Источники версии: сначала основные, затем дополнительные, внутри блока — в установленном порядке. Поле ordinal — печатный номер ВНУТРИ своего блока.","operationId":"academic_listLiterature","parameters":[{"name":"sid","in":"path","description":"Идентификатор силлабуса","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Литература","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/LiteratureSourceDto"}}}}},"404":{"description":"Силлабус не найден","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/LiteratureSourceDto"}}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.academic.read"]}]}},"/academic/syllabi/{sid}/import":{"get":{"tags":["ACADEMIC: Syllabus import from a file"],"summary":"Состояние разбора файла","description":"Последний прогон разбора: статус, стадия, процент, число обращений к ИИ, исходный документ, применённые разделы. ЧЕРНОВИКА здесь нет — он приходит отдельной ручкой /import/draft (экран опрашивает состояние каждые несколько секунд, и цитаты чужого документа в таком ответе ездить не должны).\nВремя: elapsedSeconds — сколько прогон идёт по часам СЕРВЕРА, etaSeconds — остаток, посчитанный НА ЭТОМ чтении (по стадии, разделам и числу страниц; у завершённого прогона null). Ход по разделам: documentSections — одиннадцать разделов документа в порядке силлабуса с подписями, sectionsDoneKeys — пройденные, currentSectionKey — тот, что разбирается сейчас.\nДоступ: автор силлабуса либо учебный отдел.","operationId":"academic_current","parameters":[{"name":"sid","in":"path","description":"Идентификатор силлабуса","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Состояние последнего прогона","content":{"*/*":{"schema":{"$ref":"#/components/schemas/SyllabusImportRunDto"}}}},"403":{"description":"Не автор и не учебный отдел","content":{"*/*":{"schema":{"$ref":"#/components/schemas/SyllabusImportRunDto"}}}},"404":{"description":"Силлабуса нет либо разборов файла не было","content":{"*/*":{"schema":{"$ref":"#/components/schemas/SyllabusImportRunDto"}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.academic.read"]}]}},"/academic/syllabi/{sid}/assignments":{"get":{"tags":["ACADEMIC: Syllabus Assignments"],"summary":"Задания курса","description":"Задания версии в порядке создания. Доступ: чтение сотрудника.","operationId":"academic_listAssignments","parameters":[{"name":"sid","in":"path","description":"Идентификатор силлабуса","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Задания курса","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/AssignmentTemplateDto"}}}}},"404":{"description":"Силлабус не найден","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/AssignmentTemplateDto"}}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.academic.read"]}]}},"/academic/committee-memberships":{"get":{"tags":["ACADEMIC: Academic Committee Memberships (Академ-функции)"],"summary":"Назначенные академ-функции","description":"Все назначения (сгруппированы по функции). schoolDepartmentName подтягивается из справочника подразделений; при недоступности справочника остаётся null — на права это не влияет.","operationId":"academic_list_4","responses":{"200":{"description":"Список назначений","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/CommitteeMembershipDto"}}}}},"403":{"content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/CommitteeMembershipDto"}}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.academic.read"]}]}},"/academic/catalog/disciplines":{"get":{"tags":["ACADEMIC: Academic Catalog Disciplines"],"summary":"Список дисциплин реестра","description":"Все фильтры необязательны и комбинируются. degree — код справочника уровней (регистр не важен); academicYear — в любом читаемом написании (нормализуется в «2026-2027», нечитаемое значение просто не матчит ничего); courseYear — курс степени; programId — ОП, к которой дисциплина относится; q — подстрока по коду и названиям kk/ru/en без учёта регистра; verified — только проверенные (true) или только непроверенные (false), то есть рождённые импортом учебного плана и расписанием. degree в ответе — трёхъязычный лейбл.","operationId":"academic_list_5","parameters":[{"name":"degree","in":"query","description":"Код степени (BACHELOR/MASTER/MBA/...)","required":false,"schema":{"type":"string"},"example":"BACHELOR"},{"name":"academicYear","in":"query","description":"Учебный год «введена с»","required":false,"schema":{"type":"string"},"example":"2026-2027"},{"name":"courseYear","in":"query","description":"Курс степени (1..4)","required":false,"schema":{"type":"integer","format":"int32"},"example":1},{"name":"programId","in":"query","description":"ID образовательной программы","required":false,"schema":{"type":"string","format":"uuid"}},{"name":"q","in":"query","description":"Поиск по коду и названиям kk/ru/en","required":false,"schema":{"type":"string"},"example":"ИКТ"},{"name":"verified","in":"query","description":"Только проверенные (true) / только непроверенные (false)","required":false,"schema":{"type":"boolean"},"example":false}],"responses":{"200":{"description":"Список дисциплин (отсортирован: год по убыванию, код по возрастанию)","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/CatalogDisciplineDto"}}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.academic.read"]}]}},"/academic/assessment-methods":{"get":{"tags":["ACADEMIC: Academic Assessment Methods"],"summary":"Методы оценивания","description":"Список методов оценивания (по коду). type — с трёхъязычным лейблом.","operationId":"academic_list_6","responses":{"200":{"description":"Список методов","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/AssessmentMethodDto"}}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.academic.read"]}]}},"/academic/workload/refs/position-profiles":{"get":{"tags":["ACADEMIC: Workload References"],"summary":"Профили позиций ППС (проценты блоков)","description":"Процентная раскладка ёмкости по 6 блокам работ для каждой из 3 позиций ППС (Teaching-focused / Teaching Researcher / Research Leader), версией на учебный год (Приложение А ТЗ). Сумма долей позиции = 100. lectureAllowed — допущена ли позиция к ЛЕКЦИЯМ на этот год (вход правила HC-01: к лекциям допускает либо учёное звание в должности профиля, либо этот флаг позиции). Read-only: раскладка и допуск задаются сидом, меняются новой версией года. Позиции и блоки — трёхъязычно.","operationId":"academic_positionProfiles","parameters":[{"name":"academicYear","in":"query","description":"Учебный год-версия, формат 2026-2027; по умолчанию — текущий пилотный год","required":false,"schema":{"type":"string"},"example":"2026-2027"}],"responses":{"200":{"description":"Профили позиций года","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/FacultyPositionProfileDto"}}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.academic.read"]}]}},"/academic/workload/plans/{planId}":{"get":{"tags":["ACADEMIC: Workload Plans"],"summary":"План педнагрузки по id","description":"Карточка плана: год, школа, статус (трёхъязычно), цель оптимизации (задел).","operationId":"academic_plan","parameters":[{"name":"planId","in":"path","description":"ID плана","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"План","content":{"*/*":{"schema":{"$ref":"#/components/schemas/WorkloadPlanDto"}}}},"403":{"description":"Нет прав на чтение этого плана","content":{"*/*":{"schema":{"$ref":"#/components/schemas/WorkloadPlanDto"}}}},"404":{"description":"План не найден","content":{"*/*":{"schema":{"$ref":"#/components/schemas/WorkloadPlanDto"}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.academic.read"]}]}},"/academic/workload/plans/{planId}/workflow":{"get":{"tags":["ACADEMIC: Workload Workflow"],"summary":"Состояние маршрута согласования плана","description":"Текущий статус плана, доступные из него действия (с allowedForMe — есть ли у спрашивающего функция для перехода) и полная история переходов.","operationId":"academic_workflow","parameters":[{"name":"planId","in":"path","description":"id плана педнагрузки","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Состояние маршрута","content":{"*/*":{"schema":{"$ref":"#/components/schemas/WorkloadWorkflowStateDto"}}}},"404":{"description":"План не найден","content":{"*/*":{"schema":{"$ref":"#/components/schemas/WorkloadWorkflowStateDto"}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.academic.read"]}]}},"/academic/workload/plans/{planId}/validate":{"get":{"tags":["ACADEMIC: Workload Allocation"],"summary":"Валидация плана (полный прогон правил)","description":"Детерминированный прогон по всем назначениям и строкам: находки CRITICAL (Σ долей строки ≠ 100% HC-11; объединённый поток назначен более одного раза HC-12; ineligible-назначение — не должно существовать по построению, но проверяется) и SUBSTANTIAL (принятый с основанием перегруз ёмкости HC-05, с текстом основания). Каждая находка — severity + машинный HC-код с трёхъязычными лейблами + человекочитаемое сообщение + entityRef (LINE:/ALLOCATION:) для подсветки на фронте. hasCritical → план не готов к утверждению (маршрут E3.6 повесит гейт).","operationId":"academic_validate","parameters":[{"name":"planId","in":"path","description":"ID плана","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Находки со счётчиками CRITICAL/SUBSTANTIAL","content":{"*/*":{"schema":{"$ref":"#/components/schemas/WorkloadValidationDto"}}}},"403":{"description":"Нет прав на чтение этого плана","content":{"*/*":{"schema":{"$ref":"#/components/schemas/WorkloadValidationDto"}}}},"404":{"description":"План не найден","content":{"*/*":{"schema":{"$ref":"#/components/schemas/WorkloadValidationDto"}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.academic.read"]}]}},"/academic/workload/plans/{planId}/staff":{"get":{"tags":["ACADEMIC: Workload Capacity"],"summary":"Снимки ППС плана","description":"Вся команда плана: позиция, ставка, доля периода, тип договора, пометки сбора, флаг ручной правки, языки владения и должность-как-есть (входы правил допустимости), а также capacityNote — причина нулевой ёмкости (код + трёхъязычная подпись: RATE_NOT_SET — ставка не задана, CONTRACT_HOURS_NOT_CALCULATED — не штатный договор; null — ёмкость считается штатно). Сортировка — по имени.","operationId":"academic_staff","parameters":[{"name":"planId","in":"path","description":"ID плана","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Снимки занятости","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/EmploymentSnapshotDto"}}}}},"403":{"description":"Нет прав на чтение команды этого плана","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/EmploymentSnapshotDto"}}}}},"404":{"description":"План не найден","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/EmploymentSnapshotDto"}}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.academic.read"]}]}},"/academic/workload/plans/{planId}/my-sheet":{"get":{"tags":["ACADEMIC: Workload Teacher Sheet"],"summary":"Моя ведомость нагрузки","description":"Ведомость преподавателя: 6 блоков работ с назначениями/часами, своя ёмкость, свои апелляции. Доступна с момента выноса плана на ознакомление (статус «Ознакомление преподавателей» и позже); ранее — 403.","operationId":"academic_mySheet","parameters":[{"name":"planId","in":"path","description":"id плана педнагрузки","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Ведомость преподавателя","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MyWorkloadSheetDto"}}}},"403":{"description":"План ещё не вынесен на ознакомление","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MyWorkloadSheetDto"}}}},"404":{"description":"План не найден","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MyWorkloadSheetDto"}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.academic.read"]}]}},"/academic/workload/plans/{planId}/matrix":{"get":{"tags":["ACADEMIC: Workload Matrix"],"summary":"Матрица «строка потребности × кандидаты»","description":"По одной строке потребности отдаёт всех преподавателей команды плана как кандидатов: eligible (проходит ли активные жёсткие правила E3-К3: HC-01 лекции/должность, HC-03 язык, HC-04 штатность), rejectionCodes (проваленные правила с трёхъязычными лейблами; пусто у допустимого), score (рейтинг Mᵢⱼ 0–100 или null у недопустимого — недопустимых не ранжируем) и components (расшифровка рейтинга по критериям с фактически применённым весом после перенормировки У7 и человеческим объяснением; критерии «нет данных» в расшифровку не попадают). Порядок кандидатов детерминирован: допустимые сначала, затем по убыванию рейтинга, тай-брейк по keycloakId. Значения — из кэша последнего пересчёта (POST.../recalculate); пока по строке не было пересчёта — candidates пуст, scored=false и notice называет причину трёхъязычно: NO_TEACHERS (команда плана не собрана — собрать ППС; пересчёт на пустой команде бесполезен) либо NOT_SCORED (команда есть, правила по строке не считали — POST.../recalculate). Пустая матрица НЕ означает «никто не подошёл». Параметр lineId ОБЯЗАТЕЛЕН (без него — 400).","operationId":"academic_matrix","parameters":[{"name":"planId","in":"path","description":"ID плана","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"lineId","in":"query","description":"ID строки потребности (обязателен)","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Строка + кандидаты с допустимостью и рейтингом","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MatrixDto"}}}},"400":{"description":"Не передан обязательный параметр lineId","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MatrixDto"}}}},"403":{"description":"Нет прав на чтение этого плана","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MatrixDto"}}}},"404":{"description":"План не найден / строка не найдена / строка не из этого плана","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MatrixDto"}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.academic.read"]}]}},"/academic/workload/plans/{planId}/individual-plans":{"get":{"tags":["ACADEMIC: Workload Teacher Sheet"],"summary":"Проекты ИПП плана","description":"Все проекты ИПП плана (для директора/проректора). Доступ: директор школы плана / проректор / администратор платформы (fail-closed).","operationId":"academic_individualPlans","parameters":[{"name":"planId","in":"path","description":"id плана педнагрузки","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Список проектов ИПП","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/IndividualPlanDraftDto"}}}}},"403":{"description":"Нет права чтения плана","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/IndividualPlanDraftDto"}}}}},"404":{"description":"План не найден","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/IndividualPlanDraftDto"}}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.academic.read"]}]}},"/academic/workload/plans/{planId}/individual-plans/my":{"get":{"tags":["ACADEMIC: Workload Teacher Sheet"],"summary":"Мой проект индивидуального плана","description":"Проект ИПП преподавателя (6 блоков × назначения × часы), сгенерированный при утверждении плана. 404, если план ещё не утверждён или у преподавателя нет назначений.","operationId":"academic_myIndividualPlan","parameters":[{"name":"planId","in":"path","description":"id плана педнагрузки","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Проект ИПП","content":{"*/*":{"schema":{"$ref":"#/components/schemas/IndividualPlanDraftDto"}}}},"404":{"description":"ИПП не сгенерирован / план не найден","content":{"*/*":{"schema":{"$ref":"#/components/schemas/IndividualPlanDraftDto"}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.academic.read"]}]}},"/academic/workload/plans/{planId}/capacity":{"get":{"tags":["ACADEMIC: Workload Capacity"],"summary":"Ёмкость команды плана","description":"Рассчитанная ёмкость каждого ППС: суммарная + по 6 блокам (целевое/назначено/доступно), а также тип договора, ставка и note — причина нулевой ёмкости (код + трёхъязычная подпись: RATE_NOT_SET / CONTRACT_HOURS_NOT_CALCULATED; null — ёмкость считается штатно). Ёмкость считается ТОЛЬКО штатным (1584 × ставка × доля периода); у совместителя и ГПХ договорная ветка расчёта в этом заходе не реализована — их часы задаются ручным назначением с основанием, и note об этом прямо говорит. Пусто, пока не выполнен пересчёт. Свою ёмкость преподаватель смотрит через capacity/my.","operationId":"academic_capacity","parameters":[{"name":"planId","in":"path","description":"ID плана","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Записи ёмкости","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/CapacityRecordDto"}}}}},"403":{"description":"Нет прав на чтение ёмкости этого плана","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/CapacityRecordDto"}}}}},"404":{"description":"План не найден","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/CapacityRecordDto"}}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.academic.read"]}]}},"/academic/workload/plans/{planId}/capacity/my":{"get":{"tags":["ACADEMIC: Workload Capacity"],"summary":"Моя ёмкость в плане","description":"Ёмкость ТЕКУЩЕГО пользователя (преподавателя) в плане — строго своя, по sub из JWT (fail-closed: чужую не отдаёт). Нет записи → 204 (ёмкость ещё не рассчитана / вас нет в команде плана).","operationId":"academic_myCapacity","parameters":[{"name":"planId","in":"path","description":"ID плана","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Ваша запись ёмкости","content":{"*/*":{"schema":{"$ref":"#/components/schemas/CapacityRecordDto"}}}},"204":{"description":"Вашей записи ёмкости в этом плане нет","content":{"*/*":{"schema":{"$ref":"#/components/schemas/CapacityRecordDto"}}}},"404":{"description":"План не найден","content":{"*/*":{"schema":{"$ref":"#/components/schemas/CapacityRecordDto"}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.academic.read"]}]}},"/academic/workload/plans/my":{"get":{"tags":["ACADEMIC: Workload Teacher Sheet"],"summary":"Мои планы педнагрузки","description":"Планы, в команду которых входит преподаватель И которые уже вынесены на ознакомление (статус «Ознакомление преподавателей» и позже). Доступ: любой аутентифицированный — выдача строго по sub из JWT (чужих планов не покажет). Это ЕДИНСТВЕННЫЙ способ для преподавателя узнать id своего плана: общий список планов доступен только директору/проректору/админу, а личные ручки (ведомость, апелляции, ИПП) требуют planId в пути. Преподаватель не в команде ни одного плана → пустой список (не 403).","operationId":"academic_myPlans","responses":{"200":{"description":"Планы преподавателя (возможно пустой список)","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/WorkloadPlanDto"}}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.academic.read"]}]}},"/academic/syllabus-references/week-event-types":{"get":{"tags":["ACADEMIC: Syllabus References"],"summary":"Типы событий недели","description":"Значения типов событий недели (визит, тест, защита и прочие) трёхъязычно.","operationId":"academic_weekEventTypes","responses":{"200":{"description":"Типы событий недели","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/SyllabusEnumLabelDto"}}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.academic.read"]}]}},"/academic/syllabus-references/teaching-methods":{"get":{"tags":["ACADEMIC: Syllabus References"],"summary":"Методы преподавания","description":"Справочник методов преподавания вуза: код, трёхъязычное название и описание.","operationId":"academic_teachingMethods","responses":{"200":{"description":"Методы преподавания","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/TeachingMethodDto"}}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.academic.read"]}]}},"/academic/syllabus-references/rubric-template":{"get":{"tags":["ACADEMIC: Syllabus References"],"summary":"Шаблон рубрики вуза","description":"Действующий шаблон целиком, все три языка сразу — выбора языка здесь нет. Силлабус снимает с него копию при создании.","operationId":"academic_rubricTemplate","responses":{"200":{"description":"Шаблон рубрики","content":{"*/*":{"schema":{"$ref":"#/components/schemas/RubricTemplateRefDto"}}}},"404":{"description":"Действующий шаблон не найден","content":{"*/*":{"schema":{"$ref":"#/components/schemas/RubricTemplateRefDto"}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.academic.read"]}]}},"/academic/syllabus-references/rubric-levels":{"get":{"tags":["ACADEMIC: Syllabus References"],"summary":"Уровни рубрики","description":"Четыре уровня рубрики с подписями, буквенной меткой и процентной полосой. Полоса выводится из шкалы оценок и нигде не хранится.","operationId":"academic_rubricLevels","responses":{"200":{"description":"Уровни рубрики","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/RubricLevelDto"}}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.academic.read"]}]}},"/academic/syllabus-references/reading-kinds":{"get":{"tags":["ACADEMIC: Syllabus References"],"summary":"Виды чтений семинара","description":"Значения видов чтения (обязательное, рекомендуемое) трёхъязычно.","operationId":"academic_readingKinds","responses":{"200":{"description":"Виды чтений","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/SyllabusEnumLabelDto"}}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.academic.read"]}]}},"/academic/syllabus-references/policy-defaults":{"get":{"tags":["ACADEMIC: Syllabus References"],"summary":"Правила вуза","description":"Действующая ревизия правил: 17 текстов на трёх языках, 14 чисел и сокращения. Чтение сотрудника; правка — в административной двери.","operationId":"academic_policyDefaults","responses":{"200":{"description":"Действующие правила вуза","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PolicyDefaultsAdminDto"}}}},"404":{"description":"Действующая ревизия не найдена","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PolicyDefaultsAdminDto"}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.academic.read"]}]}},"/academic/syllabus-references/policy-blocks":{"get":{"tags":["ACADEMIC: Syllabus References"],"summary":"Блоки правил курса","description":"17 блоков правил: код, трёхъязычная подпись и раздел, на экране которого блок правится (это не место печати в документе).","operationId":"academic_policyBlocks","responses":{"200":{"description":"Блоки правил","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/PolicyBlockDto"}}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.academic.read"]}]}},"/academic/syllabus-references/languages":{"get":{"tags":["ACADEMIC: Syllabus References"],"summary":"Языки силлабуса","description":"Три языка документа: русский, казахский, английский.","operationId":"academic_languages","responses":{"200":{"description":"Языки силлабуса","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/SyllabusEnumLabelDto"}}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.academic.read"]}]}},"/academic/syllabus-references/grading-scale":{"get":{"tags":["ACADEMIC: Syllabus References"],"summary":"Шкала оценивания","description":"Буквенная шкала: буква, GPA, процентный диапазон и традиционная оценка трёхъязычно, по убыванию.","operationId":"academic_gradingScale","responses":{"200":{"description":"Шкала оценивания","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/GradingScaleDto"}}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.academic.read"]}]}},"/academic/syllabus-references/exam-formats":{"get":{"tags":["ACADEMIC: Syllabus References"],"summary":"Форматы экзамена","description":"Значения форматов экзамена трёхъязычно.","operationId":"academic_examFormats","responses":{"200":{"description":"Форматы экзамена","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/SyllabusEnumLabelDto"}}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.academic.read"]}]}},"/academic/syllabus-references/default-texts":{"get":{"tags":["ACADEMIC: Syllabus References"],"summary":"Готовые формулировки","description":"Постоянные формулировки сроков и форм сдачи для кнопки «вставить обычную формулировку» в плане недель. Приходят УЖЕ с разрешёнными подстановками: кнопка пишет строку прямо в поле версии, которое через подстановку на выходе не проходит.","operationId":"academic_defaultTexts","responses":{"200":{"description":"Готовые формулировки","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/DefaultTextDto"}}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.academic.read"]}]}},"/academic/syllabus-references/bloom-levels":{"get":{"tags":["ACADEMIC: Syllabus References"],"summary":"Уровни таксономии Блума","description":"Шесть уровней (REMEMBER..CREATE) с трёхъязычной подписью, порядковым номером и списком глаголов уровня. Справочник заведён волной разбора файла: до неё поле bloomLevel у результата обучения было свободной строкой без проверки, и неверный уровень нельзя было ни выбрать из списка, ни исправить. verbs нужны не селекту, а разбору загруженного файла: уровень выводится СОПОСТАВЛЕНИЕМ глагола формулировки, а не извлекается моделью.","operationId":"academic_bloomLevels","responses":{"200":{"description":"Шесть уровней Блума","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/BloomLevelDto"}}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.academic.read"]}]}},"/academic/syllabus-references/assignment-types":{"get":{"tags":["ACADEMIC: Syllabus References"],"summary":"Типы заданий","description":"Значения типов заданий трёхъязычно.","operationId":"academic_assignmentTypes","responses":{"200":{"description":"Типы заданий","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/SyllabusEnumLabelDto"}}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.academic.read"]}]}},"/academic/syllabus-references/assessment-periods":{"get":{"tags":["ACADEMIC: Syllabus References"],"summary":"Периоды оценивания","description":"Справочник периодов: код, название, вес по умолчанию, потолок баллов, признак экзамена. По умолчанию возвращаются только действующие.","operationId":"academic_assessmentPeriods","parameters":[{"name":"activeOnly","in":"query","description":"Только действующие строки","required":false,"schema":{"type":"boolean","default":true},"example":true}],"responses":{"200":{"description":"Периоды оценивания","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/AssessmentPeriodRefDto"}}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.academic.read"]}]}},"/academic/syllabus-references/assessment-forms":{"get":{"tags":["ACADEMIC: Syllabus References"],"summary":"Формы оценивания","description":"Справочник форм элементов оценивания. По умолчанию возвращаются только действующие.","operationId":"academic_assessmentForms","parameters":[{"name":"activeOnly","in":"query","description":"Только действующие строки","required":false,"schema":{"type":"boolean","default":true},"example":true}],"responses":{"200":{"description":"Формы оценивания","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/AssessmentFormRefDto"}}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.academic.read"]}]}},"/academic/syllabus-references/ai-use-levels":{"get":{"tags":["ACADEMIC: Syllabus References"],"summary":"Уровни использования ИИ A0..A4","description":"Код, трёхъязычные заголовок и семантика, цвет светофора честности, режим ИИ-помощника. Без требования декларации.","operationId":"academic_aiUseLevels","responses":{"200":{"description":"Уровни A0..A4","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/AiUseLevelRefDto"}}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.academic.read"]}]}},"/academic/syllabus-references/ai-modes":{"get":{"tags":["ACADEMIC: Syllabus References"],"summary":"Режимы использования ИИ","description":"Значения режимов использования ИИ на курсе трёхъязычно.","operationId":"academic_aiModes","responses":{"200":{"description":"Режимы использования ИИ","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/SyllabusEnumLabelDto"}}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.academic.read"]}]}},"/academic/syllabus-admin/policy-defaults/{id}":{"get":{"tags":["ACADEMIC: Syllabus Admin: Policy Defaults"],"summary":"Ревизия правил по идентификатору","description":"Любая ревизия, включая снятые с действия — историю правил читают, чтобы понять, что стояло в подписанном силлабусе.","operationId":"academic_defaults","parameters":[{"name":"id","in":"path","description":"Идентификатор ревизии","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Ревизия правил","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PolicyDefaultsAdminDto"}}}},"404":{"description":"Ревизия не найдена","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PolicyDefaultsAdminDto"}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.academic.read"]}]}},"/academic/syllabus-admin/policy-defaults/active":{"get":{"tags":["ACADEMIC: Syllabus Admin: Policy Defaults"],"summary":"Действующая ревизия правил","description":"Действующая ревизия целиком: все тексты на трёх языках, числа и сокращения.","operationId":"academic_activeDefaults","responses":{"200":{"description":"Действующая ревизия","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PolicyDefaultsAdminDto"}}}},"404":{"description":"Действующая ревизия не найдена","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PolicyDefaultsAdminDto"}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.academic.read"]}]}},"/academic/syllabi/{sid}":{"get":{"tags":["ACADEMIC: Syllabus"],"summary":"Карточка силлабуса","description":"Полная карточка: корень + активная версия + все разделы (с содержимым JSON, порядком и признаком обязательности из шаблона) + языковые версии. sectionKey/currentStatus — с трёхъязычным лейблом. Экран «силлабус моего курса» обязан сверять курс по courseIds. Остальным читателям карточки поле пустое — это не ошибка и не признак отсутствия файла.","operationId":"academic_get_5","parameters":[{"name":"sid","in":"path","description":"ID силлабуса","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Силлабус","content":{"*/*":{"schema":{"$ref":"#/components/schemas/SyllabusDto"}}}},"404":{"description":"Силлабус / его версия не найдены","content":{"*/*":{"schema":{"$ref":"#/components/schemas/SyllabusDto"}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.academic.read"]}]}},"/academic/syllabi/{sid}/validate":{"get":{"tags":["ACADEMIC: Syllabus Content"],"summary":"Проверка силлабуса","description":"Детерминированная проверка: критические замечания (блокируют отправку) и существенные (не блокируют). Доступ: чтение сотрудника.","operationId":"academic_validate_1","parameters":[{"name":"sid","in":"path","description":"Идентификатор силлабуса","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Замечания проверки","content":{"*/*":{"schema":{"$ref":"#/components/schemas/SyllabusValidationDto"}}}},"404":{"description":"Силлабус не найден","content":{"*/*":{"schema":{"$ref":"#/components/schemas/SyllabusValidationDto"}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.academic.read"]}]}},"/academic/syllabi/{sid}/sign-payload":{"get":{"tags":["ACADEMIC: Syllabus Workflow"],"summary":"Данные для подписи силлабуса ЭЦП (sign-payload)","description":"Wave 6. Возвращает детерминированный замороженный канонический XML силлабуса и ожидаемый ИИН подписанта — то, что утверждающий подписывает через NCALayer перед APPROVE. Канон ЗАМОРАЖИВАЕТСЯ при первом запросе для активной версии и переиспользуется при повторных (подписывается ровно то, что заморожено). Статус силлабуса строго «На утверждении» (DEAN_APPROVAL), иначе 409. Под enforce-iin-match: у подписанта не указан ИИН → 400; в dev expectedIin пустой (подпись любым личным сертификатом).","operationId":"academic_signPayload","parameters":[{"name":"sid","in":"path","description":"ID силлабуса","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"canonicalXml (замороженный) + expectedIin","content":{"*/*":{"schema":{"$ref":"#/components/schemas/SyllabusSignPayloadDto"}}}},"400":{"description":"У подписанта не указан ИИН (enforce-iin-match) / утверждать некому (цепочка не даёт носителя)","content":{"*/*":{"schema":{"$ref":"#/components/schemas/SyllabusSignPayloadDto"}}}},"403":{"description":"Не носитель действующей функции для школы силлабуса","content":{"*/*":{"schema":{"$ref":"#/components/schemas/SyllabusSignPayloadDto"}}}},"404":{"description":"Силлабус / его версия не найдены","content":{"*/*":{"schema":{"$ref":"#/components/schemas/SyllabusSignPayloadDto"}}}},"409":{"description":"Силлабус не в статусе «На утверждении» — подписывать нечего","content":{"*/*":{"schema":{"$ref":"#/components/schemas/SyllabusSignPayloadDto"}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.academic.read"]}]}},"/academic/syllabi/{sid}/prompt-journal":{"get":{"tags":["ACADEMIC: Syllabus AI"],"summary":"Журнал промптов ИИ силлабуса","description":"Все записи журнала промптов активной версии (новые сверху, ВСЕ поля ТЗ §8.4): кто (userId), роль-снимок автора, когда (со смещением зоны), раздел, действие, промпт, модель ИИ, трасса ответа, решение преподавателя (userAction — null пока не зафиксировано), итоговый текст, конфиденциальность. Enum-поля — с трёхъязычным лейблом.","operationId":"academic_journal","parameters":[{"name":"sid","in":"path","description":"ID силлабуса","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Журнал промптов","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/AiPromptJournalEntryDto"}}}}},"404":{"description":"Силлабус / его версия не найдены","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/AiPromptJournalEntryDto"}}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.academic.read"]}]}},"/academic/syllabi/{sid}/program-outcomes":{"get":{"tags":["ACADEMIC: Syllabus Passport"],"summary":"Снимки результатов обучения программы","description":"Результаты обучения программы, скопированные в версию силлабуса. Именно снимок, а не ссылка: правка программы не должна менять уже подписанный документ.","operationId":"academic_listProgramOutcomeRefs","parameters":[{"name":"sid","in":"path","description":"Идентификатор силлабуса","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Снимки результатов обучения программы","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/ProgramOutcomeRefDto"}}}}},"404":{"description":"Силлабус не найден","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/ProgramOutcomeRefDto"}}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.academic.read"]}]}},"/academic/syllabi/{sid}/policies":{"get":{"tags":["ACADEMIC: Syllabus Policies"],"summary":"Правила курса","description":"Блоки правил на языке версии: текст вуза, дополнение преподавателя, номер действующей ревизии правил, числа вуза (ожидаемая посещаемость, сроки, опоздания) и расшифровка сокращений. Межъязыкового отката нет: версия печатает свой язык.","operationId":"academic_policies","parameters":[{"name":"sid","in":"path","description":"Идентификатор силлабуса","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Правила курса","content":{"*/*":{"schema":{"$ref":"#/components/schemas/SyllabusPolicyViewDto"}}}},"404":{"description":"Силлабус не найден","content":{"*/*":{"schema":{"$ref":"#/components/schemas/SyllabusPolicyViewDto"}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.academic.read"]}]}},"/academic/syllabi/{sid}/import/draft":{"get":{"tags":["ACADEMIC: Syllabus import from a file"],"summary":"Черновик разбора с решениями преподавателя","description":"Обогащённый черновик готового прогона: по каждому полю — подпись, вид контрола, статус (найдено / требует проверки / не найдено), значение, ДОСЛОВНАЯ цитата из файла со страницей, ЧТО СЕЙЧАС в силлабусе (currentValue) и будет ли оно затёрто (overwrites), а также сохранённое решение преподавателя.\nЧерновик живёт 24 часа от завершения прогона и стирается сразу после применения или отклонения: это цитаты чужого документа.\nДоступ: автор силлабуса либо учебный отдел.","operationId":"academic_draft","parameters":[{"name":"sid","in":"path","description":"Идентификатор силлабуса","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Черновик и сохранённые решения","content":{"*/*":{"schema":{"$ref":"#/components/schemas/SyllabusImportDraftDto"}}}},"403":{"description":"Не автор и не учебный отдел","content":{"*/*":{"schema":{"$ref":"#/components/schemas/SyllabusImportDraftDto"}}}},"404":{"description":"Готового разбора нет (не запускался, не завершился, отклонён или протух)","content":{"*/*":{"schema":{"$ref":"#/components/schemas/SyllabusImportDraftDto"}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.academic.read"]}]}},"/academic/syllabi/{sid}/export":{"get":{"tags":["ACADEMIC: Syllabus"],"summary":"Экспорт силлабуса в документ","description":"Рендерит силлабус в документ (шаблон SYLLABUS вуза, Times New Roman) через сервис шаблонов, сохраняет файл в хранилище и возвращает ИДЕНТИФИКАТОР файла (fileId) + метаданные. Собирает данные активной версии: общие сведения, часы, РОД, темы, методы, литературу, схему оценивания, политику ИИ по заданиям, шкалу оценок (лейблы — трёхъязычные с бэка). format (query) — формат экспорта, по умолчанию PDF (единственный поддержанный сегодня; иной формат → 400). Байты берутся по fileId через GET /api/files/{id}/download под токеном вызывающего (кабинет проксирует это маршрутом /api/storage/{fileId}). Владельцем файла в хранилище записывается запросивший экспорт — свой документ он читает всегда, отдельных прав никому не выдаётся, документ строится под конкретный запрос.","operationId":"academic_export","parameters":[{"name":"sid","in":"path","description":"ID силлабуса","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"format","in":"query","description":"Формат экспорта (PDF по умолчанию)","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"Идентификатор файла документа + метаданные","content":{"*/*":{"schema":{"$ref":"#/components/schemas/SyllabusExportDto"}}}},"400":{"description":"Неподдерживаемый формат экспорта","content":{"*/*":{"schema":{"$ref":"#/components/schemas/SyllabusExportDto"}}}},"404":{"description":"Силлабус / его версия / шаблон SYLLABUS не найдены","content":{"*/*":{"schema":{"$ref":"#/components/schemas/SyllabusExportDto"}}}},"503":{"description":"Сервис шаблонов или хранилище документов недоступны","content":{"*/*":{"schema":{"$ref":"#/components/schemas/SyllabusExportDto"}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.academic.read"]}]}},"/academic/syllabi/{sid}/changelog":{"get":{"tags":["ACADEMIC: Syllabus"],"summary":"Журнал изменений силлабуса","description":"Записи журнала активной версии (новые сверху): кто, когда (со смещением зоны), что сделал и почему (reason обязателен при создании версии).","operationId":"academic_changelog","parameters":[{"name":"sid","in":"path","description":"ID силлабуса","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Журнал изменений","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/ChangeLogEntryDto"}}}}},"404":{"description":"Силлабус / его версия не найдены","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/ChangeLogEntryDto"}}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.academic.read"]}]}},"/academic/syllabi/{sid}/assignment-rubrics":{"get":{"tags":["ACADEMIC: Syllabus Assignments"],"summary":"Рубрики всех заданий","description":"Рубрики всех заданий версии ОДНИМ запросом — экран заданий иначе делал бы по запросу на строку. Доступ: чтение сотрудника.","operationId":"academic_listAssignmentRubrics","parameters":[{"name":"sid","in":"path","description":"Идентификатор силлабуса","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Рубрики заданий","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/AssignmentRubricDto"}}}}},"404":{"description":"Силлабус не найден","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/AssignmentRubricDto"}}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.academic.read"]}]}},"/academic/syllabi/{sid}/approver":{"get":{"tags":["ACADEMIC: Syllabus Workflow"],"summary":"Кто утверждает этот силлабус сейчас","description":"Возвращает ФАКТИЧЕСКОГО утверждающего для школы этого силлабуса — первую функцию цепочки вуза, у которой есть живой носитель, — вместе с готовой трёхъязычной подписью: «Декан» либо «Проректор, декан не назначен». Питает подпись «На утверждении · …» на карточке силлабуса и в маршруте (константа «у ректора» врала при любой раскладке). acting=null — утверждать некому либо школа силлабуса не доказана академической; причина в explanation.code (NO_CARRIER / CHAIN_MISSING / SCHOOL_UNKNOWN / SCHOOL_NOT_ACADEMIC / DIRECTORY_UNAVAILABLE), текст — в explanation.nameRu/Kk/En.","operationId":"academic_approver","parameters":[{"name":"sid","in":"path","description":"ID силлабуса","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Действующий утверждающий + цепочка + объяснение","content":{"*/*":{"schema":{"$ref":"#/components/schemas/SyllabusApproverDto"}}}},"404":{"description":"Силлабус / его версия не найдены","content":{"*/*":{"schema":{"$ref":"#/components/schemas/SyllabusApproverDto"}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.academic.read"]}]}},"/academic/syllabi/{sid}/approvals":{"get":{"tags":["ACADEMIC: Syllabus Workflow"],"summary":"Решения инстанций по силлабусу (данные маршрута/approvals)","description":"Wave 6 (§4). Список решений утверждающих инстанций по силлабусу (все версии), старые первыми. У APPROVE-решения дополнено ФАКТОМ ПОДПИСИ: signerCommonName (ФИО из сертификата), signedAt (момент подписания), maskedIin (маска 1234•••••567). Поля подписи NULL для RETURN и старых (доподписных) строк. Питает деталь маршрута в faculty ([sid]/route) и portal.","operationId":"academic_approvals","parameters":[{"name":"sid","in":"path","description":"ID силлабуса","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Список решений с фактом подписи у APPROVE","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/SyllabusApprovalDto"}}}}},"404":{"description":"Силлабус не найден","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/SyllabusApprovalDto"}}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.academic.read"]}]}},"/academic/syllabi/{sid}/alignment":{"get":{"tags":["ACADEMIC: Syllabus Content"],"summary":"Матрица соответствия","description":"Связи РОП → РОД → неделя плана и разрывы: РОД без недели, неделя без РОД. Доступ: чтение сотрудника.","operationId":"academic_alignment","parameters":[{"name":"sid","in":"path","description":"Идентификатор силлабуса","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Матрица соответствия","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AlignmentMatrixDto"}}}},"404":{"description":"Силлабус не найден","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AlignmentMatrixDto"}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.academic.read"]}]}},"/academic/student/syllabus/by-course/{courseId}":{"get":{"tags":["ACADEMIC: Syllabus (student)"],"summary":"Силлабус моей дисциплины","description":"Урезанная проекция утверждённого силлабуса той дисциплины, на которую студент записан. Документ приходит на языке САМОГО силлабуса — язык интерфейса его не выбирает: студент читает ровно тот текст, который утвердил проректор. Незаполненные разделы не приходят вовсе: пустая карточка с заголовком это не информация. Экран печатает это как «силлабус пока не утверждён».","operationId":"academic_byCourse","parameters":[{"name":"courseId","in":"path","description":"Идентификатор дисциплины в системе обучения","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Силлабус дисциплины","content":{"*/*":{"schema":{"$ref":"#/components/schemas/StudentSyllabusDto"}}}},"401":{"description":"Нет или недействителен JWT","content":{"*/*":{"schema":{"$ref":"#/components/schemas/StudentSyllabusDto"}}}},"403":{"description":"Студент не записан на дисциплину; либо сервис обучения не подтвердил запись","content":{"*/*":{"schema":{"$ref":"#/components/schemas/StudentSyllabusDto"}}}},"404":{"description":"У дисциплины нет утверждённого силлабуса","content":{"*/*":{"schema":{"$ref":"#/components/schemas/StudentSyllabusDto"}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.academic.read"]}]}},"/academic/student/syllabus/by-course/{courseId}/export":{"get":{"tags":["ACADEMIC: Syllabus (student)"],"summary":"Скачать силлабус в PDF","description":"Отдаёт ГОТОВЫЕ БАЙТЫ документа (`application/pdf`), а не идентификатор файла и не подписанную ссылку. Байты живут ровно один ответ и в разметку не попадают. Файл при этом никуда не сохраняется — копия силлабуса под учёткой студента не нужна никому. Недоступный шаблонизатор отвечает честной 503, а не пустым PDF: пустой документ выглядит как исправный и обнаруживается уже на печати.","operationId":"academic_exportByCourse","parameters":[{"name":"courseId","in":"path","description":"Идентификатор дисциплины в системе обучения","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"format","in":"query","description":"Формат: поддержан только PDF","required":false,"schema":{"type":"string"},"example":"pdf"}],"responses":{"200":{"description":"PDF силлабуса","content":{"*/*":{"schema":{"type":"string","format":"binary"}}}},"400":{"description":"Формат экспорта не поддерживается","content":{"*/*":{"schema":{"type":"string","format":"binary"}}}},"401":{"description":"Нет или недействителен JWT","content":{"*/*":{"schema":{"type":"string","format":"binary"}}}},"403":{"description":"Студент не записан на дисциплину","content":{"*/*":{"schema":{"type":"string","format":"binary"}}}},"404":{"description":"У дисциплины нет утверждённого силлабуса","content":{"*/*":{"schema":{"type":"string","format":"binary"}}}},"503":{"description":"Шаблонизатор недоступен — документ не собран","content":{"*/*":{"schema":{"type":"string","format":"binary"}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.academic.read"]}]}},"/academic/references":{"get":{"tags":["ACADEMIC: Academic References"],"summary":"Все справочники одним снимком","description":"Единый снимок всех нормативных справочников для инициализации форм конструктора.","operationId":"academic_all","responses":{"200":{"description":"Снимок всех справочников","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ReferencesResponse"}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.academic.read"]}]}},"/academic/references/qualification-levels":{"get":{"tags":["ACADEMIC: Academic References"],"summary":"Уровни квалификации","description":"BACHELOR/MASTER/DOCTORATE и т.п. (ТЗ §6.2).","operationId":"academic_qualificationLevels","responses":{"200":{"description":"Список уровней квалификации","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/ReferenceItemDto"}}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.academic.read"]}]}},"/academic/references/program-groups":{"get":{"tags":["ACADEMIC: Academic References"],"summary":"Группы образовательных программ (ГОП)","operationId":"academic_programGroups","responses":{"200":{"description":"Список групп образовательных программ","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/ReferenceItemDto"}}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.academic.read"]}]}},"/academic/references/ork-levels":{"get":{"tags":["ACADEMIC: Academic References"],"summary":"Уровни ОРК РК","description":"Отраслевая рамка квалификаций.","operationId":"academic_orkLevels","responses":{"200":{"description":"Список уровней ОРК","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/ReferenceItemDto"}}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.academic.read"]}]}},"/academic/references/nrk-levels":{"get":{"tags":["ACADEMIC: Academic References"],"summary":"Уровни НРК РК","description":"Национальная рамка квалификаций, 8 уровней.","operationId":"academic_nrkLevels","responses":{"200":{"description":"Список уровней НРК","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/ReferenceItemDto"}}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.academic.read"]}]}},"/academic/references/msko-levels":{"get":{"tags":["ACADEMIC: Academic References"],"summary":"Уровни МСКО (ISCED 2011)","operationId":"academic_mskoLevels","responses":{"200":{"description":"Список уровней МСКО","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/ReferenceItemDto"}}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.academic.read"]}]}},"/academic/references/lesson-types":{"get":{"tags":["ACADEMIC: Academic References"],"summary":"Виды учебных занятий (F-E.2)","description":"LECTURE/PRACTICE/SEMINAR/LAB/SROP/SRO (терминология вуза: СРОП/СРО) — трёхъязычные лейблы для конструктора часов по видам занятий.","operationId":"academic_lessonTypes","responses":{"200":{"description":"Список видов занятий","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/LabelDto"}}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.academic.read"]}]}},"/academic/references/goso":{"get":{"tags":["ACADEMIC: Academic References"],"summary":"Справочник ГОСО","description":"Государственные общеобязательные стандарты образования. У элементов есть validUntil.","operationId":"academic_goso","responses":{"200":{"description":"Список ГОСО с датами действия","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/ReferenceItemDto"}}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.academic.read"]}]}},"/academic/references/dublin-descriptors":{"get":{"tags":["ACADEMIC: Academic References"],"summary":"Дублинские дескрипторы","description":"knowledge/skills/competence/autonomy/communication.","operationId":"academic_dublinDescriptors","responses":{"200":{"description":"Список Дублинских дескрипторов","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/ReferenceItemDto"}}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.academic.read"]}]}},"/academic/references/directions":{"get":{"tags":["ACADEMIC: Academic References"],"summary":"Направления образования","operationId":"academic_directionsOfStudy","responses":{"200":{"description":"Список направлений образования","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/ReferenceItemDto"}}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.academic.read"]}]}},"/academic/references/control-forms":{"get":{"tags":["ACADEMIC: Academic References"],"summary":"Формы итогового контроля (F-E.2)","description":"EXAM/CREDIT/DIFF_CREDIT/COURSE_WORK/COURSE_PROJECT/PRACTICE_REPORT — трёхъязычные лейблы для выбора формы контроля дисциплины.","operationId":"academic_controlForms","responses":{"200":{"description":"Список форм контроля","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/LabelDto"}}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.academic.read"]}]}},"/academic/references/bloom-verbs":{"get":{"tags":["ACADEMIC: Academic References"],"summary":"Глаголы Блума","description":"Активные глаголы таксономии Блума (remember..create) для формулировок РО.","operationId":"academic_bloomVerbs","responses":{"200":{"description":"Список глаголов Блума","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/ReferenceItemDto"}}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.academic.read"]}]}},"/academic/programs":{"get":{"tags":["ACADEMIC: Academic Programs"],"summary":"Список ОП","description":"Все образовательные программы (новые сверху). Каждая карточка несёт academicYearFrom (учебный год первого набора) и статус действующей редакции: currentVersionStatus (согласование, LabelDto с трёхъязычным лейблом) и currentPublicationStatus (публикация в граф) — оба null, если у ОП нет действующей редакции. draftVersionId — редакция «в доработке» (последняя созданная в любом статусе, кроме «Утверждено»/«Архивная версия»). Всё резолвится ОДНИМ запросом на весь список (без N+1).","operationId":"academic_list_7","responses":{"200":{"description":"Список ОП","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/ProgramDto"}}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.academic.read"]}]}},"/academic/programs/{id}":{"get":{"tags":["ACADEMIC: Academic Programs"],"summary":"Карточка ОП","description":"Одна ОП по id: нормативный профиль, школа-владелец, учебный год первого набора, статус согласования и публикации действующей редакции.","operationId":"academic_get_6","parameters":[{"name":"id","in":"path","description":"ID ОП","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"ОП","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ProgramDto"}}}},"404":{"description":"ОП не найдена","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ProgramDto"}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.academic.read"]}]}},"/academic/programs/{id}/versions/{vId}":{"get":{"tags":["ACADEMIC: Academic Programs"],"summary":"Паспорт редакции ОП","description":"Паспорт конкретной редакции: трёхъязычные цель и концепция, область применения, карьерные позиции, языки обучения (KZ/EN), учебный год редакции, статус согласования и статус публикации в учебный контур. По publicationStatus следят за исходом публикации. Редакция должна принадлежать указанной ОП.","operationId":"academic_getVersion","parameters":[{"name":"id","in":"path","description":"ID ОП","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"vId","in":"path","description":"ID редакции","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Паспорт редакции","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ProgramVersionDto"}}}},"404":{"description":"ОП/редакция не найдена или редакция не принадлежит ОП","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ProgramVersionDto"}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.academic.read"]}]}},"/academic/health":{"get":{"tags":["ACADEMIC: Health"],"summary":"Health ping (no auth)","operationId":"academic_health","responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"object","additionalProperties":{"type":"string"}}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.academic.read"]}]}},"/academic/committee-memberships/user/{keycloakUserId}":{"get":{"tags":["ACADEMIC: Academic Committee Memberships (Академ-функции)"],"summary":"Функции конкретного пользователя","description":"НАЗНАЧЕННЫЕ функции по keycloakId. Полный ответ — /effective (см. AcademicFunctionResolver).","operationId":"academic_listByUser","parameters":[{"name":"keycloakUserId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Список назначений пользователя","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/CommitteeMembershipDto"}}}}},"403":{"content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/CommitteeMembershipDto"}}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.academic.read"]}]}},"/academic/committee-memberships/user/{keycloakUserId}/effective":{"get":{"tags":["ACADEMIC: Academic Committee Memberships (Академ-функции)"],"summary":"Действующие права актора (свод обоих источников)","description":"Отвечает на вопрос «кто этот человек и что он вправе»: назначенные функции + оргфакты справочника (SCHOOL_DIRECTOR по каждому АКАДЕМИЧЕСКОМУ подразделению, где он руководитель — руководитель административного подразделения права двигать ОП не получает). Источники складываются. Прав оно не даёт; пусто = школа не подтверждена (нет карточки, карточка погашена, подразделение не академическое либо документооборот недоступен). global=true — функция действует для любой ШКОЛЫ (не для любого подразделения!); иначе только для schoolDepartmentId. Назначенные школьные функции на подразделении, переставшем быть академическим, здесь не появятся: они каскадно ОТЗЫВАЮТСЯ (с аудитом) — директор не-школы не директор школы. /authorize.","operationId":"academic_effective","parameters":[{"name":"keycloakUserId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Действующие функции актора","content":{"*/*":{"schema":{"$ref":"#/components/schemas/EffectiveFunctionsDto"}}}},"403":{"content":{"*/*":{"schema":{"$ref":"#/components/schemas/EffectiveFunctionsDto"}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.academic.read"]}]}},"/academic/committee-memberships/user/{keycloakUserId}/authorize":{"get":{"tags":["ACADEMIC: Academic Committee Memberships (Академ-функции)"],"summary":"Проверка права: действует ли функция для этой школы","description":"Отвечает ровно то, что получит движок согласования (E1.9-b) от AcademicFunctionResolver.hasFunctionForSchool. Read-only: ничего не решает и не меняет, делает правило проверяемым. allowed=true требует ТРЁХ доказательств: школа задана + подразделение ДОКАЗАНО академическим + область гранта покрывает цель. Поле reason разводит три разных отказа.","operationId":"academic_authorize","parameters":[{"name":"keycloakUserId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"function","in":"query","description":"Академ-функция","required":true,"schema":{"type":"string","enum":["METHODIST","SCHOOL_DIRECTOR","ACADEMIC_COMMITTEE","UMS_MEMBER","COMPLIANCE_OFFICER","VICE_RECTOR","ACADEMIC_COUNCIL","DEAN"]},"example":"SCHOOL_DIRECTOR"},{"name":"schoolDepartmentId","in":"query","description":"Подразделение-школа, для которого проверяется право; не задано = область неизвестна → allowed=false","required":false,"schema":{"type":"integer","format":"int64"},"example":27}],"responses":{"200":{"description":"Ответ авторизации (allowed + почему)","content":{"*/*":{"schema":{"$ref":"#/components/schemas/FunctionAuthorizationDto"}}}},"400":{"description":"Неизвестная функция","content":{"*/*":{"schema":{"$ref":"#/components/schemas/FunctionAuthorizationDto"}}}},"403":{"content":{"*/*":{"schema":{"$ref":"#/components/schemas/FunctionAuthorizationDto"}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.academic.read"]}]}},"/academic/committee-memberships/me":{"get":{"tags":["ACADEMIC: Academic Committee Memberships (Академ-функции)"],"summary":"Мои действующие академ-функции","description":"Действующие права ТЕКУЩЕГО актора (keycloakId берётся из токена, не из пути) — тот же свод обоих источников, что и /user/{id}/effective, но про себя.","operationId":"academic_me","responses":{"200":{"description":"Действующие функции текущего актора","content":{"*/*":{"schema":{"$ref":"#/components/schemas/EffectiveFunctionsDto"}}}},"401":{"description":"Не аутентифицирован","content":{"*/*":{"schema":{"$ref":"#/components/schemas/EffectiveFunctionsDto"}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.academic.read"]}]}},"/academic/catalog/disciplines/{id}/usage":{"get":{"tags":["ACADEMIC: Academic Catalog Disciplines"],"summary":"Где используется запись реестра","description":"Строки учебных планов (версий ОП), которые ссылаются на эту запись настоящим FK: редакция ОП, код и название её программы, id строки. rowCount — то же число, которое называет отказ 409 при попытке удалить запись. Пустой список означает, что запись можно удалять.","operationId":"academic_usage","parameters":[{"name":"id","in":"path","description":"ID дисциплины реестра","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Список использований (может быть пуст)","content":{"*/*":{"schema":{"$ref":"#/components/schemas/CatalogDisciplineUsageDto"}}}},"404":{"description":"Дисциплина не найдена","content":{"*/*":{"schema":{"$ref":"#/components/schemas/CatalogDisciplineUsageDto"}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.academic.read"]}]}},"/academic/catalog/disciplines/{id}/teachers":{"get":{"tags":["ACADEMIC: Academic Catalog Disciplines"],"summary":"Преподаватели дисциплины","description":"Кто закреплён за дисциплиной реестра: keycloak sub + момент закрепления (в порядке закрепления) + источник source: SCHEDULE — ведущий потока расписания, MANUAL — закреплён руками в портале. Имена резолвит клиент по общему реестру пользователей.","operationId":"academic_teachersOf","parameters":[{"name":"id","in":"path","description":"ID дисциплины реестра","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Список закреплений (может быть пуст)","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/CatalogDisciplineTeacherDto"}}}}},"404":{"description":"Дисциплина не найдена","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/CatalogDisciplineTeacherDto"}}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.academic.read"]}]}},"/academic/approval-routes":{"get":{"tags":["ACADEMIC: Approval routes settings"],"summary":"Настройки всех маршрутов согласования","description":"Три маршрута — образовательная программа, силлабус, кафедральная нагрузка. По каждому: действующее правило возврата, состав инстанций по шагам с признаком «есть ли у функции живой носитель» и кто согласует фактически. У силлабуса состав пуст, а заполнен stepsSettingPath: его цепочка утверждающих настраивается отдельным экраном, потому что имеет переопределения по школам.","operationId":"academic_list_8","responses":{"200":{"description":"Настройки маршрутов","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/ApprovalRouteDto"}}}}},"401":{"description":"Не аутентифицирован","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/ApprovalRouteDto"}}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.academic.read"]}]}},"/scheduling/my/availability":{"get":{"tags":["SCHEDULING: Teacher availability"],"summary":"Get my availability","description":"Returns the full grid of seeded timeslots (ordered by day then pair, each with day/classNumber/startTime/endTime) plus the caller's own three-state selection: availableTimeslotIds (Свободен), undesiredTimeslotIds (Нежелательно) and blockedTimeslotIds (Не могу). The three lists are pairwise disjoint.","operationId":"scheduling_get","responses":{"200":{"description":"The grid + the caller's selection","content":{"*/*":{"schema":{"$ref":"#/components/schemas/TeacherAvailabilityResponse"}}}},"401":{"description":"No/invalid JWT","content":{"*/*":{"schema":{"$ref":"#/components/schemas/TeacherAvailabilityResponse"}}}},"403":{"content":{"*/*":{"schema":{"$ref":"#/components/schemas/TeacherAvailabilityResponse"}}}},"404":{"description":"The caller's account is not linked to an instructor (also the answer for a token without a sub)","content":{"*/*":{"schema":{"$ref":"#/components/schemas/TeacherAvailabilityResponse"}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.scheduling.read"]}]}},"/scheduling/calendar/events/{id}":{"get":{"tags":["SCHEDULING: Calendar"],"summary":"Одно событие календаря","description":"Карточка события с conflictWith[] и canEdit — по ссылке колокольчика (?event=) и из календаря. Доступ: любая учётка сотрудника. Событие не найдено или это строка бывшей заявки (REJECTED, CANCELLED, EXPIRED) — 404.","operationId":"scheduling_getEvent","parameters":[{"name":"id","in":"path","description":"Событие (одна дата)","required":true,"schema":{"type":"string","format":"uuid"},"example":"7e21a4c2-1b3d-4f5e-8a9b-0c1d2e3f4a5b"}],"responses":{"200":{"description":"Событие","content":{"*/*":{"schema":{"$ref":"#/components/schemas/CalendarEventDto"}}}},"401":{"description":"Нет/невалидный JWT","content":{"*/*":{"schema":{"$ref":"#/components/schemas/CalendarEventDto"}}}},"403":{"description":"Не учётка сотрудника","content":{"*/*":{"schema":{"$ref":"#/components/schemas/CalendarEventDto"}}}},"404":{"description":"Событие не найдено","content":{"*/*":{"schema":{"$ref":"#/components/schemas/CalendarEventDto"}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.scheduling.read"]}]}},"/scheduling/timeslots":{"get":{"tags":["SCHEDULING: Timeslots"],"summary":"List the timeslot grid","description":"The whole bell grid: [{id, dayOfWeek, classNumber, startTime, endTime}] — same DTO as the admin endpoint.","operationId":"scheduling_list_5","responses":{"200":{"description":"Timeslot list","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/TimeslotDto"}}}}},"401":{"description":"No/invalid JWT","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/TimeslotDto"}}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.scheduling.read"]}]}},"/scheduling/teacher/students/{keycloakId}/classes":{"get":{"tags":["SCHEDULING: Teacher streams"],"summary":"Расписание студента","description":"Занятия ОДНОГО студента на диапазон дат — тем же форматом, что и собственные занятия преподавателя. Нужно карточке студента в кабинете факультета: преподаватель видит, когда у человека остальные пары. Доступ: студент учится на потоке, который ведёт вызывающий — главным преподавателем, ассистентом потока либо ведущим любой его практической группы; иначе 403. У секции без потока (наследие) правило прежнее: вызывающий ведёт само занятие. Аудитории видны (это сотрудник, а не студент). Видимость — только опубликованные триместры, как и у собственного расписания. Диапазон ОБЯЗАТЕЛЕН: без from/to — 400 (BUG-T5-TS-04); 92 дня и больше — 400.","operationId":"scheduling_studentClasses","parameters":[{"name":"keycloakId","in":"path","required":true,"schema":{"type":"string"}},{"name":"from","in":"query","description":"Начало диапазона (YYYY-MM-DD)","required":true,"schema":{"type":"string","format":"date"},"example":"2026-09-01"},{"name":"to","in":"query","description":"Конец диапазона включительно (YYYY-MM-DD)","required":true,"schema":{"type":"string","format":"date"},"example":"2026-09-07"}],"responses":{"200":{"description":"Занятия студента (может быть пустым)","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/TeacherClassDto"}}}}},"400":{"description":"Нет from/to, `to` раньше `from` либо диапазон 92 дня и больше","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/TeacherClassDto"}}}}},"401":{"description":"Нет/невалидный JWT","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/TeacherClassDto"}}}}},"403":{"description":"Этот студент не учится ни на одном потоке вызывающего","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/TeacherClassDto"}}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.scheduling.read"]}]}},"/scheduling/teacher/streams/{streamId}/summary":{"get":{"tags":["SCHEDULING: Teacher streams"],"summary":"Сводка потока","description":"Всё, что печатают шапка курса и его карточка: код и название дисциплины (ru/kk/en), триместр, учебный год, язык обучения КОДОМ (EN/KZ/RU — словом его называет кабинет), программы потока (код + названия, названия могут быть null — тогда печатается код), главный преподаватель, ассистенты, лекционные секции (lectureSectionIds — все, включая совместные с соседним потоком; lectureSectionId, lectureFormat и lectureRoom описывают первую из них), постоянная онлайн-комната, число РАЗНЫХ студентов потока и список практических групп. У каждой группы — хранимый номер («Практика 3»), её ведущий (null = вакансия), сколько в ней людей, сколько мест, формат и аудитория.","operationId":"scheduling_summary","parameters":[{"name":"streamId","in":"path","description":"Id потока (CourseStream)","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Сводка потока","content":{"*/*":{"schema":{"$ref":"#/components/schemas/StreamTeacherSummaryDto"}}}},"401":{"description":"Нет/невалидный JWT","content":{"*/*":{"schema":{"$ref":"#/components/schemas/StreamTeacherSummaryDto"}}}},"403":{"description":"Вызывающий не ведёт этот поток","content":{"*/*":{"schema":{"$ref":"#/components/schemas/StreamTeacherSummaryDto"}}}},"404":{"description":"Потока с таким id нет","content":{"*/*":{"schema":{"$ref":"#/components/schemas/StreamTeacherSummaryDto"}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.scheduling.read"]}]}},"/scheduling/teacher/streams/{streamId}/lessons":{"get":{"tags":["SCHEDULING: Teacher streams"],"summary":"Занятия потока на диапазон дат","description":"По строке на КОНКРЕТНУЮ дату: лекции потока (все, включая совместные — те же секции, что в lectureSectionIds сводки) и практики его групп. Занятия как строки в базе нет — даты разворачиваются из недельных пар по канону учебного времени (праздники исключены), поэтому правка календаря триместра видна здесь сразу. Ключ занятия — тройка (sectionId, meetingId, date); groupNo называет группу словами («Практика 3»), у лекции он null. Пустая аудитория у живого онлайн-занятия — не пробел, это отличает флаг online. Диапазон ОБЯЗАТЕЛЕН: без from/to — 400, как у такого же журнала в learning. Прежде пропуск отдавал весь триместр целиком, и один журнал вёл себя по-разному в зависимости от того, чей эндпоинт спросили (BUG-T5-TS-04). Диапазон в 92 дня и больше — 400.","operationId":"scheduling_lessons","parameters":[{"name":"streamId","in":"path","description":"Id потока (CourseStream)","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"from","in":"query","description":"Начало диапазона (YYYY-MM-DD)","required":true,"schema":{"type":"string","format":"date"},"example":"2026-09-01"},{"name":"to","in":"query","description":"Конец диапазона включительно (YYYY-MM-DD)","required":true,"schema":{"type":"string","format":"date"},"example":"2026-09-30"}],"responses":{"200":{"description":"Занятия по возрастанию даты и пары","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/StreamLessonDto"}}}}},"400":{"description":"Нет from/to, `to` раньше `from` либо диапазон 92 дня и больше","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/StreamLessonDto"}}}}},"401":{"description":"Нет/невалидный JWT","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/StreamLessonDto"}}}}},"403":{"description":"Вызывающий не ведёт этот поток","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/StreamLessonDto"}}}}},"404":{"description":"Потока с таким id нет","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/StreamLessonDto"}}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.scheduling.read"]}]}},"/scheduling/teacher/classes":{"get":{"tags":["SCHEDULING: Teacher classes"],"summary":"Мои занятия на диапазон дат","description":"Плоский хронологический список ЗАНЯТИЙ вызывающего преподавателя: каждая размещённая недельная пара его потоков развёрнута в конкретные даты по канону учебного времени (learning.AcademicTerm), ПРАЗДНИКИ ИСКЛЮЧЕНЫ. Занятия как строки в базе не существует — даты считаются на лету, поэтому правка календаря триместра видна здесь сразу. Дополнительно едут timeslotId, courseId и courseCode (единственный кросс-сервисный ключ дисциплины — у scheduling и learning РАЗНЫЕ внутренние id одной дисциплины). Поля строки: date, dayOfWeek, classNumber (пара), startTime/endTime (стенное время Asia/Almaty), startsAt (абсолютный момент начала), activityType (LECTURE/PRACTICE/LAB — вид занятия берётся у потока, у пары своего вида нет), room (null — аудитория не назначена), onlineMeetingUrl (постоянная онлайн-комната потока, null — не заведена; B5), названия дисциплины ru/kk/en и instructorNames. Карточка ЛЕКЦИИ показывает streamEnrolled, карточка ПРАКТИКИ/ЛАБЫ — currentEnrolled; у совместной лекции клиент складывает streamEnrolled соседей из jointSectionIds. Диапазон: `from` по умолчанию — сегодня (Asia/Almaty), `to` — +6 дней (неделя). `to` раньше `from` или диапазон в 92 дня и больше = 400. Преподаватель без привязанного профиля, преподаватель без пар и недоступный канон дают ПУСТОЙ список (200, fail-open), а не ошибку.","operationId":"scheduling_classes","parameters":[{"name":"from","in":"query","description":"Начало диапазона (YYYY-MM-DD); без него — сегодня","required":false,"schema":{"type":"string","format":"date"},"example":"2026-09-01"},{"name":"to","in":"query","description":"Конец диапазона включительно (YYYY-MM-DD); без него — from + 6 дней","required":false,"schema":{"type":"string","format":"date"},"example":"2026-09-07"}],"responses":{"200":{"description":"Занятия диапазона по возрастанию времени начала (может быть пустым)","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/TeacherClassDto"}}}}},"400":{"description":"`to` раньше `from` либо диапазон 92 дня и больше","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/TeacherClassDto"}}}}},"401":{"description":"Нет/невалидный JWT","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/TeacherClassDto"}}}}},"403":{"content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/TeacherClassDto"}}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.scheduling.read"]}]}},"/scheduling/sections":{"get":{"tags":["SCHEDULING: Sections"],"summary":"List sections (course/instructor/room cuts)","description":"Sections filtered by course/instructor/room/trimester (any subset; all null = all sections). courseId matches the section's course; instructorId matches an assigned instructor; roomId matches a placed meeting; trimester matches the section's course. The instructor cut (instructorId set) additionally returns totalWeeklyHours = the number of weekly meetings/pairs the instructor teaches across the returned sections, and instructorMaxWeeklyHours = that instructor's weekly load cap (null when no cap is set), so the same overload mark can be drawn next to it. A student whose card names neither gets an EMPTY list, and the reason is at GET /scheduling/enrollment-eligibility (PROGRAM_UNKNOWN | LANGUAGE_UNKNOWN); showing everything instead would offer a seat on a foreign programme or in a language they do not speak, and the product cannot take a student off a mandatory discipline afterwards. Карточка ЛЕКЦИИ показывает `streamEnrolled`, карточка ПРАКТИКИ/ЛАБЫ — `currentEnrolled` своей группы.","operationId":"scheduling_list_6","parameters":[{"name":"courseId","in":"query","description":"Course id","required":false,"schema":{"type":"string","format":"uuid"}},{"name":"instructorId","in":"query","description":"Assigned instructor id","required":false,"schema":{"type":"string","format":"uuid"}},{"name":"roomId","in":"query","description":"Placed room id","required":false,"schema":{"type":"string","format":"uuid"}},{"name":"trimester","in":"query","description":"Course trimester","required":false,"schema":{"type":"integer","format":"int32"}},{"name":"studyLevel","in":"query","description":"Omitted = every level (previous behaviour). A course whose level is not filled in yet answers as BACHELOR, the same reading the solver uses","required":false,"schema":{"type":"string"},"example":"MASTER"},{"name":"academicYear","in":"query","description":"2026-2027. Omitted = every year","required":false,"schema":{"type":"string"},"example":"2026-2027"}],"responses":{"200":{"description":"Matching sections (published-only for non-admins)","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/SectionViewDto"}}}}},"401":{"description":"No/invalid JWT","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/SectionViewDto"}}}}},"403":{"description":"Caller lacks an LMS role","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/SectionViewDto"}}}}},"503":{"content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/SectionViewDto"}}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.scheduling.read"]}]}},"/scheduling/sections/{id}/roster":{"get":{"tags":["SCHEDULING: Course streams"],"summary":"Student roster of a section (stream)","description":"The ENROLLED students of one section, in FIFO order (enrolledAt ascending).","operationId":"scheduling_roster","parameters":[{"name":"id","in":"path","description":"Section (stream) id","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"The section's ENROLLED roster (possibly empty)","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/RosterEntryDto"}}}}},"401":{"description":"No/invalid JWT","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/RosterEntryDto"}}}}},"403":{"content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/RosterEntryDto"}}}}},"404":{"description":"No section with that id","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/RosterEntryDto"}}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.scheduling.read"]}]}},"/scheduling/sections/{id}/class-dates":{"get":{"tags":["SCHEDULING: Sections"],"summary":"Section class dates","description":"The attendance roster of CONCRETE calendar dates for one section (Э1b, case 5.7), materialized on the fly from the academic-time canon. Each placed weekly meeting (weekday + pair) is expanded into the list of actual LocalDates it falls on across the trimester (start..end), SKIPPING holiday intervals — this feeds the teacher's attendance roster (AttendanceRecord.attendanceDate in learning) and deadline anchoring. Unplaced meetings and, when the canon is unavailable (`canonAvailable=false`, fail-open), all meetings carry an empty date list. Timezone is always Asia/Almaty. courseTitleKk/courseTitleEn (D015) carry the canon's kk/en discipline name, null when the imported plan carried none (fall back to courseTitle). `termStartDate` keeps its old meaning (the start of the academic period) and its old value; week numbering on the client is classesStartDate?? termStartDate. When the canon does not carry the field it is null and every date is identical to what this endpoint returned before.","operationId":"scheduling_classDates","parameters":[{"name":"id","in":"path","description":"Section id","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"The section's meetings with materialized dates","content":{"*/*":{"schema":{"$ref":"#/components/schemas/SectionClassDatesDto"}}}},"401":{"description":"No/invalid JWT","content":{"*/*":{"schema":{"$ref":"#/components/schemas/SectionClassDatesDto"}}}},"403":{"description":"Caller lacks an LMS role","content":{"*/*":{"schema":{"$ref":"#/components/schemas/SectionClassDatesDto"}}}},"404":{"content":{"*/*":{"schema":{"$ref":"#/components/schemas/SectionClassDatesDto"}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.scheduling.read"]}]}},"/scheduling/rooms/active":{"get":{"tags":["SCHEDULING: Rooms (directory)"],"summary":"List active rooms","description":"Every room of the fund with active=true, sorted by building, then number, then name. Returns [{id, number, building, name, capacity, roomType, displayName}] — equipment and the active flag are not exposed. `displayName` is how the room is named to a human: «101 · Библиотека», or just the number when the room has no name, or just the name when it has no number (the В2.2 coworking area) — never a dangling separator. Deactivated rooms are omitted with no way to ask for them: a room switched off for the timetable must not be offered as a venue either. bookable=true narrows the list to rooms that take a booking request (the picker of /scheduling/calendar): rooms of type OTHER (offices, medical point, dean's office) are dropped; the default keeps them for venue pickers. Access: any authenticated caller.","operationId":"scheduling_listActive","parameters":[{"name":"bookable","in":"query","description":"true — only rooms open to booking (no OTHER rooms); false — every active room","required":false,"schema":{"type":"boolean","default":false},"example":true}],"responses":{"200":{"description":"Active rooms","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/ActiveRoomDto"}}}}},"401":{"description":"No/invalid JWT","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/ActiveRoomDto"}}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.scheduling.read"]}]}},"/scheduling/registrar/students":{"get":{"tags":["SCHEDULING: Student schedule (registrar office)"],"summary":"Найти студента по фамилии","description":"Поиск без учёта регистра — подстрока в ФИО, коде или названии образовательной программы.","operationId":"scheduling_search","parameters":[{"name":"trimester","in":"query","description":"Номер триместра","required":true,"schema":{"type":"integer","format":"int32"},"example":1},{"name":"q","in":"query","description":"Фамилия или её часть, минимум две буквы","required":true,"schema":{"type":"string"},"example":"Ахметов"}],"responses":{"200":{"description":"Найденные студенты (возможно, пусто)","content":{"*/*":{"schema":{"$ref":"#/components/schemas/RegistrarStudentSearchDto"}}}},"400":{"description":"Запрос короче двух букв","content":{"*/*":{"schema":{"$ref":"#/components/schemas/RegistrarStudentSearchDto"}}}},"401":{"description":"Нет или невалидный JWT","content":{"*/*":{"schema":{"$ref":"#/components/schemas/RegistrarStudentSearchDto"}}}},"403":{"description":"Роль не читает расписание студентов","content":{"*/*":{"schema":{"$ref":"#/components/schemas/RegistrarStudentSearchDto"}}}},"503":{"content":{"*/*":{"schema":{"$ref":"#/components/schemas/RegistrarStudentSearchDto"}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.scheduling.read"]}]}},"/scheduling/registrar/students/{studentId}/schedule":{"get":{"tags":["SCHEDULING: Student schedule (registrar office)"],"summary":"Неделя одного студента","description":"Опубликованное расписание студента за триместр: `sections` — секции его ENROLLED-записей в дисциплинах этого триместра, у каждой `meetings` с днём, номером пары, часами и НОМЕРОМ АУДИТОРИИ. Рядом — кто это: `fullName`, `programCode`, `programTitle`, `instructionLanguage`.","operationId":"scheduling_schedule","parameters":[{"name":"studentId","in":"path","required":true,"schema":{"type":"string"},"example":"11111111-1111-1111-1111-111111111111"},{"name":"trimester","in":"query","description":"Номер триместра","required":true,"schema":{"type":"integer","format":"int32"},"example":1}],"responses":{"200":{"description":"Опубликованное расписание студента","content":{"*/*":{"schema":{"$ref":"#/components/schemas/RegistrarStudentScheduleDto"}}}},"401":{"description":"Нет или невалидный JWT","content":{"*/*":{"schema":{"$ref":"#/components/schemas/RegistrarStudentScheduleDto"}}}},"403":{"description":"Роль не читает расписание студентов","content":{"*/*":{"schema":{"$ref":"#/components/schemas/RegistrarStudentScheduleDto"}}}},"404":{"description":"Такого студента нет в реестре активных","content":{"*/*":{"schema":{"$ref":"#/components/schemas/RegistrarStudentScheduleDto"}}}},"503":{"content":{"*/*":{"schema":{"$ref":"#/components/schemas/RegistrarStudentScheduleDto"}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.scheduling.read"]}]}},"/scheduling/my":{"get":{"tags":["SCHEDULING: Sections"],"summary":"My schedule","description":"The caller's own schedule (case 5.7), from the JWT sub. Only PUBLISHED trimesters are included (same gating as GET /sections). They are invisible in `sections` yet STILL hold the student's timeslots in the enroll/reseat overlap check, so hiding them entirely reads as the system lying — an empty Monday plus a refusal to enroll into it. `groupNo` есть только у практики/лаборатории со своим потоком (у лекции и у секции без потока null), и он тот же, что печатают экран записи, карточка потока и кабинет преподавателя.","operationId":"scheduling_mySchedule","responses":{"200":{"description":"The caller's sections (possibly empty)","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MyScheduleDto"}}}},"401":{"description":"No/invalid JWT","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MyScheduleDto"}}}},"403":{"description":"Caller lacks an LMS role","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MyScheduleDto"}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.scheduling.read"]}]}},"/scheduling/my/schedule-proposal/{id}":{"get":{"tags":["SCHEDULING: Schedule proposal (student)"],"summary":"Read a proposal","description":"The stored proposal with its CURRENT status — what the chat restores when the student comes back to the conversation. A PROPOSED set whose `expiresAt` has passed reads as EXPIRED, and `expiresInSeconds` is recomputed on every read (0 once it is gone) rather than replayed from the stored copy.","operationId":"scheduling_get_5","parameters":[{"name":"id","in":"path","description":"Proposal id","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"The stored proposal","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ScheduleProposalDto"}}}},"401":{"description":"No/invalid JWT","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ScheduleProposalDto"}}}},"403":{"content":{"*/*":{"schema":{"$ref":"#/components/schemas/ScheduleProposalDto"}}}},"404":{"description":"Not the caller's proposal / not found","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ScheduleProposalDto"}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.scheduling.read"]}]}},"/scheduling/my/next-class":{"get":{"tags":["SCHEDULING: Sections"],"summary":"My next class","description":"The earliest concrete class occurrence (date + wall-clock start, Asia/Almaty) at or AFTER now, across the caller's PUBLISHED sections. Dates skip term holidays (from the canon). `startsAt` is the absolute Instant of the class start (for a countdown). courseTitleKk/courseTitleEn (D015) carry the canon's kk/en discipline name, null when the imported plan carried none (fall back to courseTitle). `found=false` (all other fields null) when there is no upcoming class — term over, no placed meetings, or the canon is unavailable (fail-open). Номера те же, что в недельной сетке и в кабинете преподавателя.","operationId":"scheduling_nextClass","responses":{"200":{"description":"The next class, or {found:false} when none","content":{"*/*":{"schema":{"$ref":"#/components/schemas/NextClassDto"}}}},"401":{"description":"No/invalid JWT","content":{"*/*":{"schema":{"$ref":"#/components/schemas/NextClassDto"}}}},"403":{"description":"Caller lacks an LMS role","content":{"*/*":{"schema":{"$ref":"#/components/schemas/NextClassDto"}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.scheduling.read"]}]}},"/scheduling/lesson-dates":{"get":{"tags":["SCHEDULING: Lesson dates"],"summary":"Lesson dates of a course (attendance date-strip)","description":"Each item carries date, dayOfWeek, classNumber (pair), start/end time, meetingType (the section's activityType LECTURE/PRACTICE/LAB), room (null when unplaced) and the ids (sectionId/courseId/meetingId/timeslotId). Default range (no from/to) = the whole trimester (term start..end). Sorted by date, then pair.","operationId":"scheduling_lessonDates","parameters":[{"name":"courseCode","in":"query","required":true,"schema":{"type":"string"},"example":"AI-ICT-101"},{"name":"from","in":"query","description":"Range start (YYYY-MM-DD); omitted -> term start","required":false,"schema":{"type":"string","format":"date"},"example":"2026-09-01"},{"name":"to","in":"query","description":"Range end (YYYY-MM-DD); omitted -> term end","required":false,"schema":{"type":"string","format":"date"},"example":"2026-11-30"}],"responses":{"200":{"description":"The course's lesson dates (possibly empty)","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/LessonDateDto"}}}}},"401":{"description":"No/invalid JWT","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/LessonDateDto"}}}}},"403":{"content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/LessonDateDto"}}}}},"404":{"description":"No course with that code","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/LessonDateDto"}}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.scheduling.read"]}]}},"/scheduling/health":{"get":{"tags":["SCHEDULING: Health"],"summary":"Health ping (no auth)","operationId":"scheduling_health","responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"object","additionalProperties":{"type":"string"}}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.scheduling.read"]}]}},"/scheduling/export":{"get":{"tags":["SCHEDULING: Schedule export"],"summary":"Export a schedule cut","description":"Exports the schedule for one cut. `view` = course|stream|instructor|room, `id` = that entity's id, `format` = xlsx|ical|pdf. `view=stream` exports ONE stream (its lecture plus its practice groups) — the course cut is by discipline CODE and returns the whole university grid for that discipline, so a single course book was not obtainable through it. Э1b: ical is anchored to the academic-time CANON (learning.AcademicTerm) — each event's DTSTART is the FIRST real class date of its weekday on/after the term start, RRULE FREQ=WEEKLY;UNTIL=<term end>, and term holidays become EXDATE lines (a break is not shown as a class). FAIL-OPEN: if the canon is unavailable the event degrades to DTSTART = next occurrence of the weekday from today + RRULE COUNT=trimesterWeeks. The.ics carries a VTIMEZONE block for Asia/Almaty (D139, RFC 5545 §3.6.5) — without it Outlook/Apple Calendar reject the import or shift every class by the local offset. The course/room cuts stay open to any LMS role (the public campus timetable) and remain publication-gated: a non-admin never gets a DRAFT trimester. `lang` = ru|kk|en (D015) selects the document language: the discipline name (ical SUMMARY, grid cell), the weekday headers and the room prefix. Absent/unknown -> ru, and a course whose canon carries no kk/en name falls back to its ru title (never an empty name).","operationId":"scheduling_export","parameters":[{"name":"view","in":"query","description":"Cut kind: course|stream|instructor|room","required":true,"schema":{"type":"string"}},{"name":"id","in":"query","description":"The course/stream/instructor/room id","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"format","in":"query","description":"Output format: xlsx|ical|pdf","required":true,"schema":{"type":"string"}},{"name":"lang","in":"query","description":"Document language: ru|kk|en (default ru; an unknown value falls back to ru instead of failing the download)","required":false,"schema":{"type":"string"},"example":"kk"}],"responses":{"200":{"description":"xlsx/ical bytes, or {fileId} for pdf","content":{"*/*":{"schema":{"type":"object"}}}},"400":{"description":"Unknown view/format, or missing id","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"No/invalid JWT","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Caller lacks an LMS role, or asked for another person's instructor cut","content":{"*/*":{"schema":{"type":"object"}}}},"503":{"content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.scheduling.read"]}]}},"/scheduling/enrollment-window":{"get":{"tags":["SCHEDULING: Enrollments"],"summary":"Enrollment window","description":"Whether enrollment is open right now for a trimester, with the window dates so the front can show the closing date ahead of time and gray out the enroll button once it passes (instead of only learning it is closed from a 400). Response: {trimester, programCode, open, code, opensAt, closesAt, addDropStart, addDropEnd, serverTime, source}. Dates come from the learning academic-time canon (source=\"canon\"); when learning is unreachable it falls back to the local termStartAt lock (source=\"fallback\", window dates null). serverTime is the server clock (never trust the device clock). The term is resolved WITHOUT requiring it to cover today: the NEAREST UPCOMING term of the caller's programme answers too, so on the eve of the first day the screen shows a countdown instead of nothing. Omit it and the server picks the NEAREST SIGNIFICANT window in the caller's programme calendar — the one open NOW, else the nearest UPCOMING one (by its opening date), else the last PAST one — and echoes the number it chose in `trimester`. This is the only way to ask the question before the academic year starts: no term covers today then, so the campus has no number to send (its own source, /learning/terms/current, answers 404). Passing the number keeps the previous behaviour byte for byte. `trimester` comes back null ONLY in the fallback answer (source=\"fallback\"), where no term was chosen at all. It used to answer ENROLLMENT_WINDOW_OPEN («not announced» read as «wide open»), inviting students to enroll into a trimester about which nothing had been announced; enroll/cancel/reseat refuse with that same code. There is deliberately NO request parameter for it: on the day enrollment opens nobody has a single enrollment yet, so the program cannot be derived from them, and accepting it from the client would let a bachelor read the Executive MBA window and the other way round. A program with no calendar of its own lives by the university-wide one.","operationId":"scheduling_enrollmentWindow","parameters":[{"name":"trimester","in":"query","description":"Trimester number (1/2/3). OPTIONAL — omit it and the server resolves the nearest significant window of the caller's programme itself and echoes the chosen number in the response.","required":false,"schema":{"type":"integer","format":"int32"},"example":1}],"responses":{"200":{"description":"Enrollment window state for the trimester","content":{"*/*":{"schema":{"$ref":"#/components/schemas/EnrollmentWindowDto"}}}},"401":{"description":"No/invalid JWT","content":{"*/*":{"schema":{"$ref":"#/components/schemas/EnrollmentWindowDto"}}}},"403":{"content":{"*/*":{"schema":{"$ref":"#/components/schemas/EnrollmentWindowDto"}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.scheduling.read"]}]}},"/scheduling/enrollment-eligibility":{"get":{"tags":["SCHEDULING: Enrollments"],"summary":"May I enroll at all","description":"An empty catalog on its own is indistinguishable from «everything is taken», so without this the student refreshes the page until the deadline. Response: {eligible, reasonCode, reason, programCode, instructionLanguage}. reasonCode is the stable machine key the screen renders its own text from: PROGRAM_UNKNOWN (the learner card names no educational programme) | LANGUAGE_UNKNOWN (it names no language of instruction); `reason` is the ready Russian sentence to show verbatim when the client has no text of its own. Both are null when eligible=true. programCode/instructionLanguage travel even on success — that is WHY the student sees three streams and not six. Fixing either is one field in the learner card, done by the registrar's office.","operationId":"scheduling_enrollmentEligibility","responses":{"200":{"description":"Eligibility verdict (+ reason when refused)","content":{"*/*":{"schema":{"$ref":"#/components/schemas/EnrollmentEligibilityDto"}}}},"401":{"description":"No/invalid JWT","content":{"*/*":{"schema":{"$ref":"#/components/schemas/EnrollmentEligibilityDto"}}}},"403":{"content":{"*/*":{"schema":{"$ref":"#/components/schemas/EnrollmentEligibilityDto"}}}},"503":{"description":"The learning contour is unreachable — the learner card could not be read","content":{"*/*":{"schema":{"$ref":"#/components/schemas/EnrollmentEligibilityDto"}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.scheduling.read"]}]}},"/scheduling/electives":{"get":{"tags":["SCHEDULING: Enrollments"],"summary":"Elective catalog","description":"The filter is NOT silently switched off — showing everything would offer a seat on a foreign programme or in a language the person does not speak, and the product cannot take a student off a mandatory discipline afterwards. The admin receives the list of such people BEFORE enrollment opens (GET /scheduling/admin/students/without-language). An online course has no room and no timeslot by nature — its empty `meetings` is not «не расставили», and it is offerable as is. imported after the trimester was published), or no meeting rows at all, leaves it out of the catalog entirely, because it has no time and would never appear in class-dates / next-class / the.ics. The catalog and the enroll guard use the SAME rule, so a card can never be shown and then refused on click. The single exception is a section the caller is already enrolled in — it stays listed (with empty meeting times) so they can see and cancel it. A discipline that belongs to a track NEVER appears in `sections` (the two lists are disjoint and together equal the catalog as it was), it counts in NEITHER chosenElectiveCourses NOR chosenCredits, and the credit cap does not gate it — those numbers keep describing the FREE electives only. Each group carries `chosenCourseCode` (the alternative already taken, null = not yet) and `chosenComplete` (the taken alternative is held WHOLE — an active enrollment on every kind of class it offers this student); both are computed on the SERVER, because the same number is printed by two different campus screens. A group left with no alternative after the filters is NOT returned at all. `studyPlanTerms[]` = {academicYear, termNo, mode, studyYear, trajectoryId, trajectoryTitleRu/Kk/En}, one per period among the published candidates; mode = UNKNOWN | NO_ELECTIVES | FALLBACK | PENDING | TRAJECTORY | FACT. PENDING: no elective of that period is offered (the student has not chosen a track yet). TRAJECTORY: only the track's disciplines are offered, ALL in `sections` (even those that belong to a track group) — the student chooses only the teacher and the time; `electiveGroups` of that period are empty. A section the caller already holds stays listed even when its discipline is outside the plan, so it can be cancelled. The gate is switched off by SCHEDULING_STUDY_PLAN_GATE_ENABLED=false (every period answers UNKNOWN).","operationId":"scheduling_electives","responses":{"200":{"description":"Elective catalog + quota indicators (count + credits) + the study plan of every period (studyPlanTerms)","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ElectiveCatalogDto"}}}},"401":{"description":"No/invalid JWT","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ElectiveCatalogDto"}}}},"403":{"content":{"*/*":{"schema":{"$ref":"#/components/schemas/ElectiveCatalogDto"}}}},"503":{"description":"The learning contour is unreachable — the learner card (programme + language) or the study plan of a period could not be read, and the catalog is not guessed","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ElectiveCatalogDto"}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.scheduling.read"]}]}},"/scheduling/courses/{courseCode}/summary":{"get":{"tags":["SCHEDULING: Course streams"],"summary":"Card-header summary of a discipline by course CODE","description":"The aggregated header of a faculty discipline card — 'N streams · M students · <weekday chips>' — computed server-side. sectionCountsByActivity maps ActivityType -> section count, zero entries omitted. weekdays are the distinct days of ALL these sections' PLACED meetings in stable MON..SAT order; totalWeeklyHours sums the sections' meeting counts.","operationId":"scheduling_summary_1","parameters":[{"name":"courseCode","in":"path","required":true,"schema":{"type":"string"},"example":"AI-PROG-101"},{"name":"mine","in":"query","description":"Aggregate only the streams the CALLER teaches (their own cabinet view); distinctStudentCount then counts the FILTERED sections only. Default false = the whole discipline.","required":false,"schema":{"type":"boolean","default":false},"example":false}],"responses":{"200":{"description":"The discipline's card summary (possibly all zeros)","content":{"*/*":{"schema":{"$ref":"#/components/schemas/CourseStreamSummaryDto"}}}},"401":{"description":"No/invalid JWT","content":{"*/*":{"schema":{"$ref":"#/components/schemas/CourseStreamSummaryDto"}}}},"403":{"content":{"*/*":{"schema":{"$ref":"#/components/schemas/CourseStreamSummaryDto"}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.scheduling.read"]}]}},"/scheduling/courses/{courseCode}/streams":{"get":{"tags":["SCHEDULING: Streams (student)"],"summary":"Streams of a discipline for the caller","description":"The streams of the CALLER'S OWN instruction language (from the learner card), sorted by streamNo. Each stream carries: teacherName (null = «Преподаватель не назначен», enrollment is still allowed — Т3-10), the lecture section + its placed slots (day/time/room), and every practice block with its `groupNo`, slots, currentEnrolled, maxStudents and freeSeats (capped by the room, B12). Блоки идут в порядке этого номера; null остаётся только у строк-наследия, которым номер ещё не проставлен. Room numbers are null while the campus hides them (SystemSettings.hideRoomNumbers). An unknown course code is an honest 404. A plan that is not known (UNKNOWN) behaves as before.","operationId":"scheduling_streams","parameters":[{"name":"courseCode","in":"path","description":"Course code","required":true,"schema":{"type":"string"},"example":"ICT1103"}],"responses":{"200":{"description":"The discipline's streams (possibly empty)","content":{"*/*":{"schema":{"$ref":"#/components/schemas/StudentStreamsDto"}}}},"401":{"description":"No/invalid JWT","content":{"*/*":{"schema":{"$ref":"#/components/schemas/StudentStreamsDto"}}}},"403":{"content":{"*/*":{"schema":{"$ref":"#/components/schemas/StudentStreamsDto"}}}},"404":{"description":"No course with that code","content":{"*/*":{"schema":{"$ref":"#/components/schemas/StudentStreamsDto"}}}},"409":{"description":"The discipline is outside the student's study plan of its period (coded NOT_IN_STUDY_PLAN / TRAJECTORY_NOT_CHOSEN)","content":{"*/*":{"schema":{"$ref":"#/components/schemas/StudentStreamsDto"}}}},"503":{"description":"The learning contour is unreachable — the study plan could not be read","content":{"*/*":{"schema":{"$ref":"#/components/schemas/StudentStreamsDto"}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.scheduling.read"]}]}},"/scheduling/courses/{courseCode}/sections":{"get":{"tags":["SCHEDULING: Course streams"],"summary":"Streams (sections/groups) of a discipline by course CODE","description":"Each item carries the sectionId, activityType (LECTURE/PRACTICE/LAB), the resolved instructors (ids + display names), the student counts (currentEnrolled / maxStudents, maxStudents null = uncapped), the weekday chips (distinct days of the section's PLACED meetings, in stable MON..SAT order) and weeklyHours (the section's weekly meeting count, one meeting = one 50-min pair).","operationId":"scheduling_streams_1","parameters":[{"name":"courseCode","in":"path","required":true,"schema":{"type":"string"},"example":"AI-ICT-101"},{"name":"mine","in":"query","description":"Keep only the streams the CALLER teaches (their own cabinet view). Default false = every stream of the discipline.","required":false,"schema":{"type":"boolean","default":false},"example":false}],"responses":{"200":{"description":"The discipline's streams (possibly empty)","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/CourseStreamDto"}}}}},"401":{"description":"No/invalid JWT","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/CourseStreamDto"}}}}},"403":{"content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/CourseStreamDto"}}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.scheduling.read"]}]}},"/scheduling/calendar/teacher":{"get":{"tags":["SCHEDULING: Calendar"],"summary":"Мои события по датам (сотрудник)","description":"Утверждённые события, где вызывающий — назначенный преподаватель или автор (любые виды, включая события «весь день» — у них startTime/endTime null), а также занятия (teaching = true) потоков, которые он ведёт, и их дисциплин без потока. Диапазон по умолчанию — неделя от сегодня; to раньше from или 92 дня и больше — 400. Доступ: любая учётка сотрудника.","operationId":"scheduling_teacherEvents","parameters":[{"name":"from","in":"query","description":"Начало диапазона (YYYY-MM-DD); без него — сегодня","required":false,"schema":{"type":"string","format":"date"},"example":"2026-09-21"},{"name":"to","in":"query","description":"Конец диапазона включительно; без него — from + 6 дней","required":false,"schema":{"type":"string","format":"date"},"example":"2026-09-27"}],"responses":{"200":{"description":"События диапазона (может быть пусто)","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/CalendarEventDto"}}}}},"400":{"description":"to раньше from либо диапазон 92 дня и больше","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/CalendarEventDto"}}}}},"401":{"description":"Нет/невалидный JWT","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/CalendarEventDto"}}}}},"403":{"description":"Не учётка сотрудника","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/CalendarEventDto"}}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.scheduling.read"]}]}},"/scheduling/calendar/occupancy":{"get":{"tags":["SCHEDULING: Calendar"],"summary":"Общий календарь событий за диапазон дат","description":"Утверждённые события любого вида в аудиториях под фильтр (и без аудитории, когда не заданы ни roomId, ни building). Исторические строки бывших заявок (REJECTED, CANCELLED, EXPIRED) не приходят. Доступ: любая учётка сотрудника. Любой сотрудник видит событие целиком: цель, участники, автор (authorName), ответственный и conflictWith[] — с какой парой недельной сетки (пары неопубликованных периодов тоже) или другим событием оно пересекается в своей аудитории. Фильтры: roomId (одна аудитория, 404 если её нет), building (корпус, без учёта регистра; только активные аудитории), kind — повторяемый вид события (EVENT, MEETING, ROOM_CLOSED, OTHER); пусто = все; удалённые 19.10 LESSON, CONSULTATION, EXAM читаются как OTHER (их события стали «Прочее»); иное неизвестное значение — 400 CALENDAR_KIND_UNKNOWN.","operationId":"scheduling_occupancy","parameters":[{"name":"from","in":"query","description":"Начало диапазона (YYYY-MM-DD), включительно","required":true,"schema":{"type":"string","format":"date"},"example":"2026-11-23"},{"name":"to","in":"query","description":"Конец диапазона (YYYY-MM-DD), включительно; меньше 92 дней от начала","required":true,"schema":{"type":"string","format":"date"},"example":"2026-11-29"},{"name":"roomId","in":"query","description":"Одна аудитория","required":false,"schema":{"type":"string","format":"uuid"},"example":"5b2f0c1e-8d6a-4f3e-9a51-0f1d2c3b4a59"},{"name":"building","in":"query","description":"Корпус (без учёта регистра)","required":false,"schema":{"type":"string"},"example":"В2.2"},{"name":"kind","in":"query","description":"Вид события; параметр повторяемый","required":false,"schema":{"type":"array","items":{"type":"string"}},"example":"MEETING"}],"responses":{"200":{"description":"Аудитории и события диапазона","content":{"*/*":{"schema":{"$ref":"#/components/schemas/OccupancyDto"}}}},"400":{"description":"Нет from/to, to раньше from, диапазон 92 дня и больше, неизвестный вид (code CALENDAR_KIND_UNKNOWN, field kind) либо roomId — не UUID","content":{"*/*":{"schema":{"$ref":"#/components/schemas/OccupancyDto"}}}},"401":{"description":"Нет/невалидный JWT","content":{"*/*":{"schema":{"$ref":"#/components/schemas/OccupancyDto"}}}},"403":{"description":"Не учётка сотрудника (студент, абитуриент, кандидат)","content":{"*/*":{"schema":{"$ref":"#/components/schemas/OccupancyDto"}}}},"404":{"description":"Аудитория roomId не найдена","content":{"*/*":{"schema":{"$ref":"#/components/schemas/OccupancyDto"}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.scheduling.read"]}]}},"/scheduling/calendar/my":{"get":{"tags":["SCHEDULING: Calendar"],"summary":"Мои занятия по датам (студент)","description":"Утверждённые события по датам, которые видит вызывающий студент: событие его потока, событие дисциплины без потока, на которую он записан, событие его программы по дисциплине без записи и событие его программы без дисциплины. Цель, число участников, автор и ответственный не отдаются, canEdit = false; аудитория скрыта, пока включена настройка скрытия номеров. teacherName — назначенный преподаватель, иначе главный преподаватель потока события; teacherInstructorId — только явное назначение. Диапазон по умолчанию — неделя от сегодня (Asia/Almaty); to раньше from или 92 дня и больше — 400.","operationId":"scheduling_myEvents","parameters":[{"name":"from","in":"query","description":"Начало диапазона (YYYY-MM-DD); без него — сегодня","required":false,"schema":{"type":"string","format":"date"},"example":"2026-09-21"},{"name":"to","in":"query","description":"Конец диапазона включительно; без него — from + 6 дней","required":false,"schema":{"type":"string","format":"date"},"example":"2026-09-27"}],"responses":{"200":{"description":"События диапазона (может быть пусто)","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/CalendarEventDto"}}}}},"400":{"description":"to раньше from либо диапазон 92 дня и больше","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/CalendarEventDto"}}}}},"401":{"description":"Нет/невалидный JWT","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/CalendarEventDto"}}}}},"403":{"description":"Вызывающий не студент","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/CalendarEventDto"}}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.scheduling.read"]}]}},"/scheduling/calendar/events/{id}/history":{"get":{"tags":["SCHEDULING: Calendar"],"summary":"История события","description":"Кто, когда и что сделал с событием: CREATED (все заполненные поля в after), UPDATED (только изменённые поля: before/after), DELETED (поля, какими они были, в before). Новые записи первыми. Коды полей: KIND, TITLE, ROOM, DATE, ALL_DAY, START, END, RESPONSIBLE, ATTENDEES, PURPOSE; значения готовы к показу (вид — код, интерфейс локализует; аудитория — подпись на момент записи; дата дд.мм.гггг; время чч:мм; ALL_DAY — true/false). Доступ: любая учётка сотрудника. Ни события, ни истории — 404.","operationId":"scheduling_eventHistory","parameters":[{"name":"id","in":"path","description":"Событие (одна дата)","required":true,"schema":{"type":"string","format":"uuid"},"example":"7e21a4c2-1b3d-4f5e-8a9b-0c1d2e3f4a5b"}],"responses":{"200":{"description":"История (может быть пусто)","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/CalendarEventHistoryDto"}}}}},"401":{"description":"Нет/невалидный JWT","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/CalendarEventHistoryDto"}}}}},"403":{"description":"Не учётка сотрудника","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/CalendarEventHistoryDto"}}}}},"404":{"description":"Нет ни события, ни его истории","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/CalendarEventHistoryDto"}}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.scheduling.read"]}]}},"/skillmatch/vacancies/latest":{"get":{"tags":["SKILLMATCH: SkillMatch"],"summary":"Latest market vacancies","description":"The plain market feed: ACTIVE vacancies ordered by publication date (undated ones last, then by id). NO matching happens here — the response carries no score, no matched[] and no missing[], because nothing was compared against anybody. It exists so a cabinet can show the labour market to a student who has not mastered any skill yet, without inventing a personal fit.","operationId":"skillmatch_latestVacancies","parameters":[{"name":"limit","in":"query","description":"Max items; omit for the default 20. Must be 1..100 when present — an out-of-range value is rejected, not clamped","required":false,"schema":{"type":"integer","format":"int32"},"example":20}],"responses":{"200":{"description":"Newest ACTIVE vacancies, newest first","content":{"*/*":{"schema":{"$ref":"#/components/schemas/VacancyListResponse"}}}},"400":{"description":"limit out of range (must be 1..100)","content":{"*/*":{"schema":{"$ref":"#/components/schemas/VacancyListResponse"}}}},"401":{"description":"No/invalid token","content":{"*/*":{"schema":{"$ref":"#/components/schemas/VacancyListResponse"}}}},"403":{"description":"Role not allowed","content":{"*/*":{"schema":{"$ref":"#/components/schemas/VacancyListResponse"}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.skillmatch.read"]}]}},"/skillmatch/vacancies/by-syllabus/{syllabusId}":{"get":{"tags":["SKILLMATCH: SkillMatch"],"summary":"Vacancies matching a syllabus","description":"Cache-first path over syllabus_vacancy_match: a fresh cache is served as-is; a stale/empty cache triggers a live recompute from the syllabus skill projection (weights from syllabus_skills). If the recompute is degraded (sidecar down) the existing cache is returned with stale=true and HTTP 200.","operationId":"skillmatch_vacanciesBySyllabus","parameters":[{"name":"syllabusId","in":"path","description":"Syllabus id (from a syllabus projection upserted via POST /admin/syllabi)","required":true,"schema":{"type":"integer","format":"int64"},"example":1}],"responses":{"200":{"description":"Top matches (possibly stale)","content":{"*/*":{"schema":{"$ref":"#/components/schemas/SyllabusMatchResponse"}}}},"401":{"description":"No/invalid token","content":{"*/*":{"schema":{"$ref":"#/components/schemas/SyllabusMatchResponse"}}}},"403":{"description":"Caller neither teaches nor studies this course","content":{"*/*":{"schema":{"$ref":"#/components/schemas/SyllabusMatchResponse"}}}},"404":{"content":{"*/*":{"schema":{"$ref":"#/components/schemas/SyllabusMatchResponse"}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.skillmatch.read"]}]}},"/skillmatch/vacancies/by-student/{studentId}":{"get":{"tags":["SKILLMATCH: SkillMatch"],"summary":"Vacancies for a student","description":"An explicit?skills= overrides that. No seed/demo fallback: when?skills= is absent and the student has no mastered skills yet, the result is honestly EMPTY (stale=false) — not the old AIML101 seed syllabus.","operationId":"skillmatch_vacanciesByStudent","parameters":[{"name":"studentId","in":"path","required":true,"schema":{"type":"string"}},{"name":"skills","in":"query","required":false,"schema":{"type":"array","items":{"type":"string"}}},{"name":"limit","in":"query","description":"Max items; omit for the default 20, must be 1..100 when present","required":false,"schema":{"type":"integer","format":"int32"}},{"name":"offset","in":"query","description":"Items to skip, default 0; must be 0 or greater","required":false,"schema":{"type":"integer","format":"int32"}},{"name":"minScore","in":"query","description":"Drop matches below this score; must be 0..100","required":false,"schema":{"type":"number","format":"double"}}],"responses":{"200":{"content":{"*/*":{"schema":{"$ref":"#/components/schemas/MatchListResponse"}}}},"400":{"description":"skills parameter present but empty, or limit/offset/minScore out of range","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MatchListResponse"}}}},"401":{"description":"No/invalid token","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MatchListResponse"}}}},"403":{"content":{"*/*":{"schema":{"$ref":"#/components/schemas/MatchListResponse"}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.skillmatch.read"]}]}},"/skillmatch/vacancies/by-skills":{"get":{"tags":["SKILLMATCH: SkillMatch"],"summary":"Vacancies matching a skill set","description":"Canonicalizes the passed skill names (aliases resolve, e.g. postgres -> postgresql; unknown names are matched semantically via a live embedding, they are NOT added to the dictionary), expands each via ANN top-5 pgvector neighbors and scores ACTIVE vacancies: score = sum(w_input * w_vacancy) / sum(w_vacancy) * 100. Each item carries matched[] (skill, similarity = raw cosine, via which input) and missing[] (vacancy skills not covered). A name that resolves to nothing and has no neighbor above the calibrated threshold is returned in unrecognizedSkills and contributes nothing — a misspelling or a non-standard skill name no longer produces confident but unrelated vacancies. Deterministic — no LLM.","operationId":"skillmatch_vacanciesBySkills","parameters":[{"name":"skills","in":"query","description":"Comma-separated skill names (any language/alias)","required":true,"schema":{"type":"array","items":{"type":"string"}},"example":"docker,postgresql,spring"},{"name":"limit","in":"query","description":"Max items; omit for the default 20. Must be 1..100 when present — an out-of-range value is rejected, not clamped","required":false,"schema":{"type":"integer","format":"int32"},"example":20},{"name":"offset","in":"query","description":"Items to skip, default 0; must be 0 or greater","required":false,"schema":{"type":"integer","format":"int32"},"example":0},{"name":"minScore","in":"query","description":"Drop matches below this score; must be 0..100","required":false,"schema":{"type":"number","format":"double"},"example":40}],"responses":{"200":{"description":"Top matches sorted by score desc; unrecognizedSkills lists the names we could not place","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MatchListResponse"}}}},"400":{"description":"skills parameter empty, or limit/offset/minScore out of range","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MatchListResponse"}}}},"401":{"description":"No/invalid token","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MatchListResponse"}}}},"403":{"description":"Role not allowed","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MatchListResponse"}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.skillmatch.read"]}]}},"/skillmatch/vacancies/by-course/{courseExternalId}":{"get":{"tags":["SKILLMATCH: SkillMatch"],"summary":"Vacancies matching a course syllabus (by course code)","description":"AIML101) instead of the internal syllabus id — the faculty frontend only knows the course code. Response carries skillsCount (syllabus projection size) for the market stats. limit truncates the cached top-K.","operationId":"skillmatch_vacanciesByCourse","parameters":[{"name":"courseExternalId","in":"path","required":true,"schema":{"type":"string"},"example":"AIML101"},{"name":"limit","in":"query","description":"Max items; omit for the full cached top-K (20). Must be 1..100 when present — an out-of-range value is rejected, not clamped","required":false,"schema":{"type":"integer","format":"int32"},"example":10}],"responses":{"200":{"description":"Top matches (possibly stale)","content":{"*/*":{"schema":{"$ref":"#/components/schemas/SyllabusMatchResponse"}}}},"400":{"description":"limit out of range (must be 1..100)","content":{"*/*":{"schema":{"$ref":"#/components/schemas/SyllabusMatchResponse"}}}},"401":{"description":"No/invalid token","content":{"*/*":{"schema":{"$ref":"#/components/schemas/SyllabusMatchResponse"}}}},"403":{"description":"Caller neither teaches nor studies this course","content":{"*/*":{"schema":{"$ref":"#/components/schemas/SyllabusMatchResponse"}}}},"404":{"description":"No syllabus projection for this course code","content":{"*/*":{"schema":{"$ref":"#/components/schemas/SyllabusMatchResponse"}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.skillmatch.read"]}]}},"/skillmatch/health":{"get":{"tags":["SKILLMATCH: Health"],"summary":"Health ping (no auth)","operationId":"skillmatch_health","responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"object","additionalProperties":{"type":"string"}}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.skillmatch.read"]}]}},"/skillmatch/companies/by-skills":{"get":{"tags":["SKILLMATCH: SkillMatch"],"summary":"Top companies for a skill set","description":"Aggregates the by-skills match result per company: vacanciesCount, avgMatchScore, up to 3 sample positions. Sorted by avgMatchScore desc, then by vacanciesCount. Skill names we cannot place are returned in unrecognizedSkills.","operationId":"skillmatch_companiesBySkills","parameters":[{"name":"skills","in":"query","description":"Comma-separated skill names","required":true,"schema":{"type":"array","items":{"type":"string"}},"example":"docker,postgresql"},{"name":"limit","in":"query","description":"Max companies; omit for the default 10, must be 1..50 when present","required":false,"schema":{"type":"integer","format":"int32"},"example":10}],"responses":{"200":{"description":"Company aggregates","content":{"*/*":{"schema":{"$ref":"#/components/schemas/CompaniesResponse"}}}},"400":{"description":"skills parameter empty, or limit out of range","content":{"*/*":{"schema":{"$ref":"#/components/schemas/CompaniesResponse"}}}},"401":{"description":"No/invalid token","content":{"*/*":{"schema":{"$ref":"#/components/schemas/CompaniesResponse"}}}},"403":{"description":"Role not allowed","content":{"*/*":{"schema":{"$ref":"#/components/schemas/CompaniesResponse"}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.skillmatch.read"]}]}},"/clubs/staff/events/{eventId}":{"get":{"tags":["CLUBS: Мероприятия — сотрудник"],"summary":"Карточка своего мероприятия","description":"Мероприятие целиком: записавшиеся (registrations), отметки с отзывами (attendance), сводка оценок и журнал. Доступ: PSYCHOLOGIST, только своё. campusUrl — адрес карточки мероприятия в кабинете студента ({CLUBS_CAMPUS_BASE_URL}/events/{id}): это ссылка на регистрацию, которую психолог копирует и рассылает сам.","operationId":"clubs_event","parameters":[{"name":"eventId","in":"path","description":"Идентификатор мероприятия","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Мероприятие","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminEventDetailDto"}}}},"401":{"description":"Нет аутентификации","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminEventDetailDto"}}}},"403":{"description":"Нет роли PSYCHOLOGIST либо мероприятие чужое","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminEventDetailDto"}}}},"404":{"description":"Мероприятие не найдено","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminEventDetailDto"}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.clubs.read"]}]}},"/clubs/staff/consultations/settings":{"get":{"tags":["CLUBS: Консультации — психолог"],"summary":"Настройки приёма","description":"Формат, место, ссылка, окно приёма, признак «принимать записи» и недельный шаблон (7 дней, пн..вс). Доступ: PSYCHOLOGIST.","operationId":"clubs_settings","responses":{"200":{"description":"Настройки","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ConsultationSettingsDto"}}}},"401":{"description":"Нет аутентификации","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ConsultationSettingsDto"}}}},"403":{"description":"Нет роли PSYCHOLOGIST","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ConsultationSettingsDto"}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.clubs.read"]}]}},"/clubs/my/events/{eventId}":{"get":{"tags":["CLUBS: Мероприятия — организатор"],"summary":"Мероприятие организатора","description":"Полная карточка со счётчиками записей и отметок. Поле siteStatus (NONE | PENDING_RECTOR | APPROVED | REJECTED) показывает отдельную ступень — вынос афиши на публичный сайт вуза, который утверждает ректор; siteComment несёт его решение, при отказе — причину.","operationId":"clubs_event_1","parameters":[{"name":"eventId","in":"path","description":"Идентификатор мероприятия","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Мероприятие","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MyEventDetailDto"}}}},"401":{"description":"Нет аутентификации","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MyEventDetailDto"}}}},"404":{"description":"Мероприятие не найдено","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MyEventDetailDto"}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.clubs.read"]}]}},"/clubs/my/elections/{electionId}/application":{"get":{"tags":["CLUBS: Выборы Президента СП — кабинет студента"],"summary":"Своя анкета кандидата","description":"Анкета целиком — для формы правки и карточки статуса: контакты, языки с уровнем, достижения, CV (имя и размер файла; null — не приложено), четыре текста мотивации и программы (whyMe, plans, goals, values), заявление-согласие consent {signed, signedAt} и canSignConsent — можно ли сейчас открыть лист на подпись. Телефон, Telegram и CV видны только самому автору и комиссии. languages и achievements — пустые массивы, если их нет; у анкеты, поданной до 30.09, values и languages пусты до следующей правки. Статус CONSENT_PENDING — анкета заполнена, но не подана: ждёт подписи заявления-согласия.","operationId":"clubs_myApplication","parameters":[{"name":"electionId","in":"path","description":"Идентификатор выборов","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Анкета","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MyApplicationDto"}}}},"401":{"description":"Нет аутентификации","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MyApplicationDto"}}}},"403":{"content":{"*/*":{"schema":{"$ref":"#/components/schemas/MyApplicationDto"}}}},"404":{"description":"Выборов нет или анкета не подавалась","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MyApplicationDto"}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.clubs.read"]}]}},"/clubs/my/clubs/{clubId}":{"get":{"tags":["CLUBS: Клубы — кабинет студента"],"summary":"Мой клуб","description":"Полная карточка клуба для его ДЕЙСТВУЮЩЕГО участника: описание, цель, план, состав с фотографиями, состояние заявки. Главе и заместителю приходят также заявки на вступление и пригласительная ссылка. У участника состава есть поле showcase — уровень и до трёх достижений, только если он сам включил показ; молчание learning — поля нет, карточка отдаётся как обычно.","operationId":"clubs_club","parameters":[{"name":"clubId","in":"path","description":"Идентификатор клуба","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Карточка клуба","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MyClubDetailDto"}}}},"401":{"description":"Нет аутентификации","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MyClubDetailDto"}}}},"403":{"description":"Роли студента нет","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MyClubDetailDto"}}}},"404":{"description":"Клуб не найден или вызывающий в нём уже не состоит","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MyClubDetailDto"}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.clubs.read"]}]}},"/clubs/my/achievements/{achievementId}":{"get":{"tags":["CLUBS: Внешние достижения"],"summary":"Моё достижение","description":"Чужая заявка отвечает 404.","operationId":"clubs_one","parameters":[{"name":"achievementId","in":"path","description":"Идентификатор достижения","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Заявка","content":{"*/*":{"schema":{"$ref":"#/components/schemas/CLUBS_AchievementDto"}}}},"401":{"description":"Нет аутентификации","content":{"*/*":{"schema":{"$ref":"#/components/schemas/CLUBS_AchievementDto"}}}},"404":{"description":"Достижение не найдено","content":{"*/*":{"schema":{"$ref":"#/components/schemas/CLUBS_AchievementDto"}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.clubs.read"]}]}},"/clubs/staff/events":{"get":{"tags":["CLUBS: Мероприятия — сотрудник"],"summary":"Мои мероприятия","description":"Мероприятия вуза, которые создал вызывающий, по дате начала от новых к старым. Доступ: PSYCHOLOGIST.","operationId":"clubs_events","parameters":[{"name":"status","in":"query","description":"Состояние мероприятия","required":false,"schema":{"type":"string"},"example":"PUBLISHED"},{"name":"from","in":"query","description":"Начало интервала по дате начала","required":false,"schema":{"type":"string","format":"date-time"}},{"name":"to","in":"query","description":"Конец интервала по дате начала","required":false,"schema":{"type":"string","format":"date-time"}},{"name":"q","in":"query","description":"Поиск по названию","required":false,"schema":{"type":"string"}},{"name":"page","in":"query","description":"Номер страницы с нуля","required":false,"schema":{"type":"integer","format":"int32"}},{"name":"size","in":"query","description":"Размер страницы, максимум 100","required":false,"schema":{"type":"integer","format":"int32"}}],"responses":{"200":{"description":"Страница списка","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PageDtoAdminEventSummaryDto"}}}},"401":{"description":"Нет аутентификации","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PageDtoAdminEventSummaryDto"}}}},"403":{"description":"Нет роли PSYCHOLOGIST","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PageDtoAdminEventSummaryDto"}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.clubs.read"]}]}},"/clubs/staff/consultations/exceptions":{"get":{"tags":["CLUBS: Консультации — психолог"],"summary":"Исключения из графика","description":"Исключения, пересекающиеся с периодом; без параметров — с сегодняшнего дня. Доступ: PSYCHOLOGIST.","operationId":"clubs_exceptions","parameters":[{"name":"from","in":"query","description":"Начало периода (ISO date)","required":false,"schema":{"type":"string","format":"date"}},{"name":"to","in":"query","description":"Конец периода (ISO date)","required":false,"schema":{"type":"string","format":"date"}}],"responses":{"200":{"description":"Исключения","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/ConsultationExceptionDto"}}}}},"401":{"description":"Нет аутентификации","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/ConsultationExceptionDto"}}}}},"403":{"description":"Нет роли PSYCHOLOGIST","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/ConsultationExceptionDto"}}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.clubs.read"]}]}},"/clubs/my/consultations":{"get":{"tags":["CLUBS: Психологическая служба — студент"],"summary":"Мои записи","description":"Активная предстоящая запись (active, не больше одной) и история (до 20 записей, от новых к старым). Формат, место и ссылка — текущие настройки психолога. canChange — запись можно перенести или отменить.","operationId":"clubs_mine","responses":{"200":{"description":"Записи","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MyConsultationsDto"}}}},"401":{"description":"Нет аутентификации","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MyConsultationsDto"}}}},"403":{"content":{"*/*":{"schema":{"$ref":"#/components/schemas/MyConsultationsDto"}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.clubs.read"]}]}},"/clubs/my/clubs":{"get":{"tags":["CLUBS: Клубы — кабинет студента"],"summary":"Мои клубы","description":"Все клубы вызывающего, включая те, из которых он вышел, и архивные — с его ролью и состоянием клуба.","operationId":"clubs_myClubs","responses":{"200":{"description":"Список клубов","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/MyClubSummaryDto"}}}}},"401":{"description":"Нет аутентификации","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/MyClubSummaryDto"}}}}},"403":{"description":"Роли студента нет","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/MyClubSummaryDto"}}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.clubs.read"]}]}},"/clubs/my/checkin/{token}":{"get":{"tags":["CLUBS: Мероприятия — участие"],"summary":"Что показывает код отметки","description":"Мероприятие и состояние: можно ли отметиться сейчас и почему нет. Ничего не записывает.","operationId":"clubs_checkinPreview","parameters":[{"name":"token","in":"path","description":"Токен из QR","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Состояние отметки","content":{"*/*":{"schema":{"$ref":"#/components/schemas/CheckinPreviewDto"}}}},"401":{"description":"Нет аутентификации","content":{"*/*":{"schema":{"$ref":"#/components/schemas/CheckinPreviewDto"}}}},"404":{"description":"Ссылка недействительна","content":{"*/*":{"schema":{"$ref":"#/components/schemas/CheckinPreviewDto"}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.clubs.read"]}]}},"/clubs/my/achievements":{"get":{"tags":["CLUBS: Внешние достижения"],"summary":"Мои достижения","description":"Все мои заявки, новые сверху.","operationId":"clubs_mine_1","responses":{"200":{"description":"Список заявок","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/CLUBS_AchievementDto"}}}}},"401":{"description":"Нет аутентификации","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/CLUBS_AchievementDto"}}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.clubs.read"]}]}},"/clubs/staff/events/{eventId}/poster":{"get":{"tags":["CLUBS: Мероприятия — сотрудник"],"summary":"Афиша своего мероприятия","description":"Картинка афиши. Доступ: PSYCHOLOGIST, только своё.","operationId":"clubs_poster","parameters":[{"name":"eventId","in":"path","description":"Идентификатор мероприятия","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Картинка","content":{"*/*":{"schema":{"$ref":"#/components/schemas/StreamingResponseBody"}}}},"401":{"description":"Нет аутентификации","content":{"*/*":{"schema":{"$ref":"#/components/schemas/StreamingResponseBody"}}}},"403":{"description":"Нет роли PSYCHOLOGIST либо мероприятие чужое","content":{"*/*":{"schema":{"$ref":"#/components/schemas/StreamingResponseBody"}}}},"404":{"description":"Мероприятие или афиша не найдены","content":{"*/*":{"schema":{"$ref":"#/components/schemas/StreamingResponseBody"}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.clubs.read"]}]}},"/clubs/staff/events/{eventId}/checkin-materials":{"get":{"tags":["CLUBS: Мероприятия — сотрудник"],"summary":"Материалы для входа","description":"Ссылка отметки и её QR для печати. Доступ: PSYCHOLOGIST, только своё мероприятие. Токен выдаётся один раз и не меняется — напечатанный QR продолжает работать. Отмечается студент: он открывает ссылку своим телефоном в кабинете.","operationId":"clubs_checkinMaterials","parameters":[{"name":"eventId","in":"path","description":"Идентификатор мероприятия","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Ссылка и QR","content":{"*/*":{"schema":{"$ref":"#/components/schemas/CheckinMaterialsDto"}}}},"400":{"description":"На мероприятии отмечают только живым кодом","content":{"*/*":{"schema":{"$ref":"#/components/schemas/CheckinMaterialsDto"}}}},"401":{"description":"Нет аутентификации","content":{"*/*":{"schema":{"$ref":"#/components/schemas/CheckinMaterialsDto"}}}},"403":{"description":"Нет роли PSYCHOLOGIST либо мероприятие чужое","content":{"*/*":{"schema":{"$ref":"#/components/schemas/CheckinMaterialsDto"}}}},"404":{"description":"Мероприятие не найдено","content":{"*/*":{"schema":{"$ref":"#/components/schemas/CheckinMaterialsDto"}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.clubs.read"]}]}},"/clubs/staff/events/{eventId}/attendance/{keycloakId}/report-photo":{"get":{"tags":["CLUBS: Мероприятия — сотрудник"],"summary":"Фото из отзыва участника","description":"Фото, приложенное участником к отзыву. Доступ: PSYCHOLOGIST, только своё мероприятие.","operationId":"clubs_reportPhoto","parameters":[{"name":"eventId","in":"path","description":"Идентификатор мероприятия","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"keycloakId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Картинка","content":{"*/*":{"schema":{"$ref":"#/components/schemas/StreamingResponseBody"}}}},"401":{"description":"Нет аутентификации","content":{"*/*":{"schema":{"$ref":"#/components/schemas/StreamingResponseBody"}}}},"403":{"description":"Нет роли PSYCHOLOGIST либо мероприятие чужое","content":{"*/*":{"schema":{"$ref":"#/components/schemas/StreamingResponseBody"}}}},"404":{"description":"Мероприятие или фото не найдены","content":{"*/*":{"schema":{"$ref":"#/components/schemas/StreamingResponseBody"}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.clubs.read"]}]}},"/clubs/staff/consultations/stats":{"get":{"tags":["CLUBS: Консультации — психолог"],"summary":"Статистика приёма","description":"Записи за период по дате консультации: всего, предстоящих, проведено, отменено, неявок. Период обязателен и не длиннее года. Доступ: PSYCHOLOGIST, только свои числа.","operationId":"clubs_stats","parameters":[{"name":"from","in":"query","description":"Начало периода (ISO date)","required":true,"schema":{"type":"string","format":"date"}},{"name":"to","in":"query","description":"Конец периода (ISO date)","required":true,"schema":{"type":"string","format":"date"}}],"responses":{"200":{"description":"Числа","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ConsultationStatsDto"}}}},"400":{"description":"Период не задан, перевёрнут или длиннее года","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ConsultationStatsDto"}}}},"401":{"description":"Нет аутентификации","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ConsultationStatsDto"}}}},"403":{"description":"Нет роли PSYCHOLOGIST","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ConsultationStatsDto"}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.clubs.read"]}]}},"/clubs/staff/consultations/calendar":{"get":{"tags":["CLUBS: Консультации — психолог"],"summary":"Календарь","description":"Слоты каждого дня периода (FREE | BOOKED | CLOSED, причина закрытия, разовый слот, запись) и записи дня всех статусов с ФИО — без причины обращения. Период обязателен и не длиннее 6 недель. Доступ: PSYCHOLOGIST.","operationId":"clubs_calendar","parameters":[{"name":"from","in":"query","description":"Первый день (ISO date)","required":true,"schema":{"type":"string","format":"date"},"example":"2026-10-19"},{"name":"to","in":"query","description":"Последний день (ISO date)","required":true,"schema":{"type":"string","format":"date"},"example":"2026-10-25"}],"responses":{"200":{"description":"Календарь","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ConsultationCalendarDto"}}}},"400":{"description":"Период не задан, перевёрнут или длиннее 6 недель","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ConsultationCalendarDto"}}}},"401":{"description":"Нет аутентификации","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ConsultationCalendarDto"}}}},"403":{"description":"Нет роли PSYCHOLOGIST","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ConsultationCalendarDto"}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.clubs.read"]}]}},"/clubs/staff/consultations/bookings":{"get":{"tags":["CLUBS: Консультации — психолог"],"summary":"Записи","description":"Записи психолога от новых к старым: дата, время, ФИО, программа и курс студента на момент записи, статус. Пустой период — все записи. Доступ: PSYCHOLOGIST.","operationId":"clubs_bookings","parameters":[{"name":"from","in":"query","description":"Начало периода по дате консультации","required":false,"schema":{"type":"string","format":"date"}},{"name":"to","in":"query","description":"Конец периода по дате консультации","required":false,"schema":{"type":"string","format":"date"}},{"name":"status","in":"query","description":"BOOKED | CANCELLED | COMPLETED | NO_SHOW","required":false,"schema":{"type":"string"},"example":"BOOKED"},{"name":"page","in":"query","description":"Номер страницы с нуля","required":false,"schema":{"type":"integer","format":"int32"}},{"name":"size","in":"query","description":"Размер страницы, максимум 100","required":false,"schema":{"type":"integer","format":"int32"}}],"responses":{"200":{"description":"Страница записей","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PageDtoConsultationBookingRowDto"}}}},"401":{"description":"Нет аутентификации","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PageDtoConsultationBookingRowDto"}}}},"403":{"description":"Нет роли PSYCHOLOGIST","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PageDtoConsultationBookingRowDto"}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.clubs.read"]}]}},"/clubs/staff/consultations/bookings/{bookingId}":{"get":{"tags":["CLUBS: Консультации — психолог"],"summary":"Карточка записи","description":"Студент, причина обращения, отмена, перенос и журнал действий. Доступ: PSYCHOLOGIST, только своя запись. reasonErased=true — причина стёрта по сроку хранения (30 дней).","operationId":"clubs_booking","parameters":[{"name":"bookingId","in":"path","description":"Идентификатор записи","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Карточка","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ConsultationBookingDetailDto"}}}},"401":{"description":"Нет аутентификации","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ConsultationBookingDetailDto"}}}},"403":{"description":"Нет роли PSYCHOLOGIST","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ConsultationBookingDetailDto"}}}},"404":{"description":"Запись не найдена","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ConsultationBookingDetailDto"}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.clubs.read"]}]}},"/clubs/public/invite/{token}":{"get":{"tags":["CLUBS: Клубы — витрина сайта"],"summary":"Предпросмотр приглашения","description":"Что видит человек, открывший ссылку-приглашение до входа: логотип, название, направление, описание и число участников. Неизвестная и архивная ссылка отвечают ОДИНАКОВО: иначе перебор ссылок стал бы способом узнать, какие клубы существуют.","operationId":"clubs_invite","parameters":[{"name":"token","in":"path","description":"Токен пригласительной ссылки, 32 знака","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Предпросмотр клуба","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PublicInvitePreviewDto"}}}},"404":{"description":"Ссылка недействительна","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PublicInvitePreviewDto"}}}},"429":{"description":"Слишком много запросов с одного адреса","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PublicInvitePreviewDto"}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.clubs.read"]}]}},"/clubs/public/invite/{token}/logo":{"get":{"tags":["CLUBS: Клубы — витрина сайта"],"summary":"Логотип клуба на странице приглашения","description":"Байты логотипа клуба, на который указывает ссылка, при любом его состоянии — в наборе участников, на рассмотрении, отклонённом, приостановленном и утверждённом. Архивная и неизвестная ссылка отвечают ОДИНАКОВО.","operationId":"clubs_inviteLogo","parameters":[{"name":"token","in":"path","description":"Токен пригласительной ссылки, 32 знака","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Байты картинки","content":{"*/*":{"schema":{"$ref":"#/components/schemas/StreamingResponseBody"}}}},"404":{"description":"Ссылка недействительна или логотипа нет","content":{"*/*":{"schema":{"$ref":"#/components/schemas/StreamingResponseBody"}}}},"429":{"description":"Слишком много запросов с одного адреса","content":{"*/*":{"schema":{"$ref":"#/components/schemas/StreamingResponseBody"}}}},"502":{"description":"Файловое хранилище не ответило","content":{"*/*":{"schema":{"$ref":"#/components/schemas/StreamingResponseBody"}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.clubs.read"]}]}},"/clubs/public/events":{"get":{"tags":["CLUBS: Мероприятия — сайт вуза"],"summary":"Афиша сайта","description":"Мероприятия с уровнем видимости «публично», опубликованные и ещё не закончившиеся, по возрастанию даты начала.","operationId":"clubs_events_2","parameters":[{"name":"page","in":"query","description":"Номер страницы с нуля","required":false,"schema":{"type":"integer","format":"int32"},"example":0},{"name":"size","in":"query","description":"Размер страницы, максимум 100","required":false,"schema":{"type":"integer","format":"int32"},"example":20}],"responses":{"200":{"description":"Страница афиши","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PageDtoPublicEventDto"}}}},"429":{"description":"Слишком много запросов с этого адреса","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PageDtoPublicEventDto"}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.clubs.read"]}]}},"/clubs/public/events/{eventId}":{"get":{"tags":["CLUBS: Мероприятия — сайт вуза"],"summary":"Мероприятие на сайте","description":"Карточка публичного мероприятия. Непубличное, неопубликованное и мероприятие клуба, который больше не действует, отвечает 404 тем же текстом, что и несуществующее.","operationId":"clubs_event_3","parameters":[{"name":"eventId","in":"path","description":"Идентификатор мероприятия","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Мероприятие","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PublicEventDto"}}}},"404":{"description":"Мероприятие не найдено","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PublicEventDto"}}}},"429":{"description":"Слишком много запросов с этого адреса","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PublicEventDto"}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.clubs.read"]}]}},"/clubs/public/events/{eventId}/poster":{"get":{"tags":["CLUBS: Мероприятия — сайт вуза"],"summary":"Афиша мероприятия","description":"Байты картинки. Кэшируется на сутки: афиша публичного мероприятия видна всем и меняется редко.","operationId":"clubs_poster_1","parameters":[{"name":"eventId","in":"path","description":"Идентификатор мероприятия","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Картинка","content":{"*/*":{"schema":{"$ref":"#/components/schemas/StreamingResponseBody"}}}},"404":{"description":"Мероприятие или афиша не найдены","content":{"*/*":{"schema":{"$ref":"#/components/schemas/StreamingResponseBody"}}}},"429":{"description":"Слишком много запросов с этого адреса","content":{"*/*":{"schema":{"$ref":"#/components/schemas/StreamingResponseBody"}}}},"502":{"description":"Файловое хранилище недоступно","content":{"*/*":{"schema":{"$ref":"#/components/schemas/StreamingResponseBody"}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.clubs.read"]}]}},"/clubs/public/event-directions":{"get":{"tags":["CLUBS: Клубы — витрина сайта"],"summary":"Справочник направлений мероприятий","description":"Действующие направления МЕРОПРИЯТИЙ на трёх языках, с разделом (`block`), признаком «ценностное» (`valueBased`) и расшифровкой. Названия пяти государственных инициатив одинаковы во всех трёх локалях: в переводе они перестают опознаваться, поэтому объясняет их расшифровка.","operationId":"clubs_eventDirections","responses":{"200":{"description":"Список направлений мероприятий","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/EventDirectionDto"}}}}},"429":{"description":"Слишком много запросов с одного адреса","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/EventDirectionDto"}}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.clubs.read"]}]}},"/clubs/public/directions":{"get":{"tags":["CLUBS: Клубы — витрина сайта"],"summary":"Справочник направлений","description":"Действующие направления клубов на трёх языках — ими фильтруется список на сайте.","operationId":"clubs_directions","responses":{"200":{"description":"Список направлений","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/DirectionDto"}}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.clubs.read"]}]}},"/clubs/public/clubs":{"get":{"tags":["CLUBS: Клубы — витрина сайта"],"summary":"Список клубов вуза","description":"Утверждённые клубы с логотипом, направлением и описанием. Поиск идёт по названию и описанию.","operationId":"clubs_clubs","parameters":[{"name":"direction","in":"query","description":"Код направления из справочника","required":false,"schema":{"type":"string"},"example":"SPORT"},{"name":"q","in":"query","description":"Строка поиска по названию и описанию","required":false,"schema":{"type":"string"}},{"name":"page","in":"query","description":"Номер страницы с нуля","required":false,"schema":{"type":"integer","format":"int32"},"example":0},{"name":"size","in":"query","description":"Размер страницы, максимум 100","required":false,"schema":{"type":"integer","format":"int32"},"example":20}],"responses":{"200":{"description":"Страница списка","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PageDtoPublicClubDto"}}}},"429":{"description":"Слишком много запросов с одного адреса","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PageDtoPublicClubDto"}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.clubs.read"]}]}},"/clubs/public/clubs/{slug}":{"get":{"tags":["CLUBS: Клубы — витрина сайта"],"summary":"Карточка клуба на сайте","description":"Клуб по короткому имени из адреса. Отдаёт описание и цель клуба.","operationId":"clubs_club_1","parameters":[{"name":"slug","in":"path","description":"Короткое имя клуба из адреса","required":true,"schema":{"type":"string"},"example":"volleyball"}],"responses":{"200":{"description":"Карточка клуба","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PublicClubDetailDto"}}}},"404":{"description":"Клуб не найден или ещё не утверждён","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PublicClubDetailDto"}}}},"429":{"description":"Слишком много запросов с одного адреса","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PublicClubDetailDto"}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.clubs.read"]}]}},"/clubs/public/clubs/{clubId}/logo":{"get":{"tags":["CLUBS: Клубы — витрина сайта"],"summary":"Логотип клуба","description":"Байты логотипа утверждённого клуба. Отдаются потоком со своего домена: подписанная ссылка хранилища наружу не выходит. Кэшируется на сутки.","operationId":"clubs_logo","parameters":[{"name":"clubId","in":"path","description":"Идентификатор клуба","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Байты картинки","content":{"*/*":{"schema":{"$ref":"#/components/schemas/StreamingResponseBody"}}}},"404":{"description":"Клуб не найден, не утверждён или без логотипа","content":{"*/*":{"schema":{"$ref":"#/components/schemas/StreamingResponseBody"}}}},"502":{"description":"Файловое хранилище не ответило","content":{"*/*":{"schema":{"$ref":"#/components/schemas/StreamingResponseBody"}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.clubs.read"]}]}},"/clubs/my/invite/{token}":{"get":{"tags":["CLUBS: Клубы — участие"],"summary":"Предпросмотр приглашения для вошедшего","description":"Клуб по пригласительной ссылке вместе с главой и состоянием кнопки вступления: вступить сразу, отправить заявку или уже участник.","operationId":"clubs_invitePreview","parameters":[{"name":"token","in":"path","description":"Токен пригласительной ссылки","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Предпросмотр клуба","content":{"*/*":{"schema":{"$ref":"#/components/schemas/InvitePreviewDto"}}}},"401":{"description":"Нет аутентификации","content":{"*/*":{"schema":{"$ref":"#/components/schemas/InvitePreviewDto"}}}},"403":{"description":"Вступать в клубы могут студенты","content":{"*/*":{"schema":{"$ref":"#/components/schemas/InvitePreviewDto"}}}},"404":{"description":"Ссылка недействительна","content":{"*/*":{"schema":{"$ref":"#/components/schemas/InvitePreviewDto"}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.clubs.read"]}]}},"/clubs/my/invite/{token}/head-photo":{"get":{"tags":["CLUBS: Клубы — участие"],"summary":"Фотография главы на странице приглашения","description":"Портрет главы клуба, в который приглашают.","operationId":"clubs_inviteHeadPhoto","parameters":[{"name":"token","in":"path","description":"Токен пригласительной ссылки","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Байты картинки","content":{"*/*":{"schema":{"$ref":"#/components/schemas/StreamingResponseBody"}}}},"401":{"description":"Нет аутентификации","content":{"*/*":{"schema":{"$ref":"#/components/schemas/StreamingResponseBody"}}}},"404":{"description":"Ссылка недействительна или портрета нет","content":{"*/*":{"schema":{"$ref":"#/components/schemas/StreamingResponseBody"}}}},"502":{"description":"Файловое хранилище не ответило","content":{"*/*":{"schema":{"$ref":"#/components/schemas/StreamingResponseBody"}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.clubs.read"]}]}},"/clubs/my/events":{"get":{"tags":["CLUBS: Мероприятия — участие"],"summary":"Мои мероприятия","description":"Куда записан, где отмечался и что веду сам. scope=past отдаёт прошедшие, по умолчанию — предстоящие. `hasPoster` говорит, есть ли у мероприятия афиша: байты берутся по адресу `catalog/events/{id}/poster`, и спрашивать их вслепую нельзя — без афиши дверь отвечает 404.","operationId":"clubs_myEvents","parameters":[{"name":"scope","in":"query","description":"upcoming или past","required":false,"schema":{"type":"string"},"example":"upcoming"},{"name":"page","in":"query","description":"Номер страницы с нуля","required":false,"schema":{"type":"integer","format":"int32"}},{"name":"size","in":"query","description":"Размер страницы, максимум 100","required":false,"schema":{"type":"integer","format":"int32"}}],"responses":{"200":{"description":"Страница мероприятий","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PageDtoMyEventSummaryDto"}}}},"401":{"description":"Нет аутентификации","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PageDtoMyEventSummaryDto"}}}},"403":{"description":"Раздел доступен студентам","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PageDtoMyEventSummaryDto"}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.clubs.read"]}]}},"/clubs/my/events/{eventId}/registrations":{"get":{"tags":["CLUBS: Мероприятия — организатор"],"summary":"Кто записался","description":"Список записей с признаком неявки и отметки.","operationId":"clubs_registrations","parameters":[{"name":"eventId","in":"path","description":"Идентификатор мероприятия","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Список записей","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/EventRegistrationDto"}}}}},"401":{"description":"Нет аутентификации","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/EventRegistrationDto"}}}}},"404":{"description":"Мероприятие не найдено","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/EventRegistrationDto"}}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.clubs.read"]}]}},"/clubs/my/events/{eventId}/ratings":{"get":{"tags":["CLUBS: Мероприятия — организатор"],"summary":"Оценки участников","description":"Сводно: сколько оценок, средняя и распределение по пяти баллам. Кто какую поставил, не показывается.","operationId":"clubs_ratings","parameters":[{"name":"eventId","in":"path","description":"Идентификатор мероприятия","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Сводка оценок","content":{"*/*":{"schema":{"$ref":"#/components/schemas/RatingsSummaryDto"}}}},"401":{"description":"Нет аутентификации","content":{"*/*":{"schema":{"$ref":"#/components/schemas/RatingsSummaryDto"}}}},"404":{"description":"Мероприятие не найдено","content":{"*/*":{"schema":{"$ref":"#/components/schemas/RatingsSummaryDto"}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.clubs.read"]}]}},"/clubs/my/events/{eventId}/checkin-materials":{"get":{"tags":["CLUBS: Мероприятия — организатор"],"summary":"Материалы для входа","description":"Ссылка отметки и её QR для печати. Токен выдаётся один раз при публикации и не меняется — напечатанная афиша продолжает работать.","operationId":"clubs_materials","parameters":[{"name":"eventId","in":"path","description":"Идентификатор мероприятия","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Ссылка и QR","content":{"*/*":{"schema":{"$ref":"#/components/schemas/CheckinMaterialsDto"}}}},"400":{"description":"На мероприятии отмечают живым кодом","content":{"*/*":{"schema":{"$ref":"#/components/schemas/CheckinMaterialsDto"}}}},"401":{"description":"Нет аутентификации","content":{"*/*":{"schema":{"$ref":"#/components/schemas/CheckinMaterialsDto"}}}},"404":{"description":"Мероприятие не найдено","content":{"*/*":{"schema":{"$ref":"#/components/schemas/CheckinMaterialsDto"}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.clubs.read"]}]}},"/clubs/my/events/{eventId}/attendance":{"get":{"tags":["CLUBS: Мероприятия — организатор"],"summary":"Кто отметился","description":"Строки присутствия: способ отметки, роль и отчёт участника.","operationId":"clubs_attendance","parameters":[{"name":"eventId","in":"path","description":"Идентификатор мероприятия","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Список отметок","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/EventAttendanceDto"}}}}},"401":{"description":"Нет аутентификации","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/EventAttendanceDto"}}}}},"404":{"description":"Мероприятие не найдено","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/EventAttendanceDto"}}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.clubs.read"]}]}},"/clubs/my/events/{eventId}/attendance/{keycloakId}/report-photo":{"get":{"tags":["CLUBS: Мероприятия — организатор"],"summary":"Фото из отчёта участника","description":"Байты картинки; без кэширования.","operationId":"clubs_reportPhoto_1","parameters":[{"name":"eventId","in":"path","description":"Идентификатор мероприятия","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"keycloakId","in":"path","description":"Идентификатор человека","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Картинка","content":{"*/*":{"schema":{"$ref":"#/components/schemas/StreamingResponseBody"}}}},"401":{"description":"Нет аутентификации","content":{"*/*":{"schema":{"$ref":"#/components/schemas/StreamingResponseBody"}}}},"404":{"description":"Мероприятие, отметка или фото не найдены","content":{"*/*":{"schema":{"$ref":"#/components/schemas/StreamingResponseBody"}}}},"502":{"description":"Файловое хранилище недоступно","content":{"*/*":{"schema":{"$ref":"#/components/schemas/StreamingResponseBody"}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.clubs.read"]}]}},"/clubs/my/elections/{electionId}/candidates":{"get":{"tags":["CLUBS: Выборы Президента СП — кабинет студента"],"summary":"Кандидаты","description":"Допущенные кандидаты по ФИО: фото, имя, программа и курс. Видны с первого дня агитации и только по утверждённому ректором списку. Контактов кандидата здесь нет.","operationId":"clubs_candidates","parameters":[{"name":"electionId","in":"path","description":"Идентификатор выборов","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Карточки кандидатов","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/CandidateCardDto"}}}}},"401":{"description":"Нет аутентификации","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/CandidateCardDto"}}}}},"403":{"description":"Раздел доступен студентам бакалавриата и магистратуры","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/CandidateCardDto"}}}}},"404":{"description":"Выборы не найдены или профили ещё не видны","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/CandidateCardDto"}}}}},"503":{"description":"Справочник людей или учебный контур не ответил","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/CandidateCardDto"}}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.clubs.read"]}]}},"/clubs/my/elections/{electionId}/candidates/{candidateId}":{"get":{"tags":["CLUBS: Выборы Президента СП — кабинет студента"],"summary":"Профиль кандидата","description":"Программа и курс, ссылка на соцсеть, языки с уровнем, достижения и четыре текста анкеты (Е-8, редакция 30.09).","operationId":"clubs_candidate","parameters":[{"name":"electionId","in":"path","description":"Идентификатор выборов","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"candidateId","in":"path","description":"Идентификатор кандидата","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Профиль","content":{"*/*":{"schema":{"$ref":"#/components/schemas/CandidateProfileDto"}}}},"401":{"description":"Нет аутентификации","content":{"*/*":{"schema":{"$ref":"#/components/schemas/CandidateProfileDto"}}}},"403":{"description":"Раздел доступен студентам бакалавриата и магистратуры","content":{"*/*":{"schema":{"$ref":"#/components/schemas/CandidateProfileDto"}}}},"404":{"description":"Профили не видны или кандидата нет в списке","content":{"*/*":{"schema":{"$ref":"#/components/schemas/CandidateProfileDto"}}}},"503":{"description":"Справочник людей или учебный контур не ответил","content":{"*/*":{"schema":{"$ref":"#/components/schemas/CandidateProfileDto"}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.clubs.read"]}]}},"/clubs/my/elections/{electionId}/candidates/{candidateId}/photo":{"get":{"tags":["CLUBS: Выборы Президента СП — кабинет студента"],"summary":"Фото кандидата","description":"Байты фото допущенного кандидата — при той же видимости, что и профиль. Cache-Control: no-store.","operationId":"clubs_candidatePhoto","parameters":[{"name":"electionId","in":"path","description":"Идентификатор выборов","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"candidateId","in":"path","description":"Идентификатор кандидата","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Байты изображения","content":{"*/*":{"schema":{"$ref":"#/components/schemas/StreamingResponseBody"}}}},"401":{"description":"Нет аутентификации","content":{"*/*":{"schema":{"$ref":"#/components/schemas/StreamingResponseBody"}}}},"403":{"description":"Раздел доступен студентам бакалавриата и магистратуры","content":{"*/*":{"schema":{"$ref":"#/components/schemas/StreamingResponseBody"}}}},"404":{"description":"Профили не видны, кандидата или файла нет","content":{"*/*":{"schema":{"$ref":"#/components/schemas/StreamingResponseBody"}}}},"502":{"description":"Хранилище не ответило","content":{"*/*":{"schema":{"$ref":"#/components/schemas/StreamingResponseBody"}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.clubs.read"]}]}},"/clubs/my/elections/{electionId}/application/photo":{"get":{"tags":["CLUBS: Выборы Президента СП — кабинет студента"],"summary":"Своё фото кандидата","description":"Байты фото из своей анкеты — для превью в форме правки. Автору своё фото доступно всегда. Cache-Control: no-store.","operationId":"clubs_myPhoto","parameters":[{"name":"electionId","in":"path","description":"Идентификатор выборов","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Байты изображения","content":{"*/*":{"schema":{"$ref":"#/components/schemas/StreamingResponseBody"}}}},"401":{"description":"Нет аутентификации","content":{"*/*":{"schema":{"$ref":"#/components/schemas/StreamingResponseBody"}}}},"403":{"content":{"*/*":{"schema":{"$ref":"#/components/schemas/StreamingResponseBody"}}}},"404":{"description":"Анкеты или файла нет","content":{"*/*":{"schema":{"$ref":"#/components/schemas/StreamingResponseBody"}}}},"502":{"description":"Хранилище не ответило","content":{"*/*":{"schema":{"$ref":"#/components/schemas/StreamingResponseBody"}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.clubs.read"]}]}},"/clubs/my/elections/{electionId}/application/cv":{"get":{"tags":["CLUBS: Выборы Президента СП — кабинет студента"],"summary":"Своё CV","description":"Байты PDF из своей анкеты — автору, в любом состоянии анкеты. Content-Type: application/pdf, Content-Disposition: inline; filename*=UTF-8''<имя файла>, X-Content-Type-Options: nosniff, Cache-Control: private, no-store.","operationId":"clubs_myCv","parameters":[{"name":"electionId","in":"path","description":"Идентификатор выборов","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Байты PDF","content":{"*/*":{"schema":{"$ref":"#/components/schemas/StreamingResponseBody"}}}},"401":{"description":"Нет аутентификации","content":{"*/*":{"schema":{"$ref":"#/components/schemas/StreamingResponseBody"}}}},"403":{"content":{"*/*":{"schema":{"$ref":"#/components/schemas/StreamingResponseBody"}}}},"404":{"description":"Выборов или анкеты нет, CV не приложено или файла нет в хранилище","content":{"*/*":{"schema":{"$ref":"#/components/schemas/StreamingResponseBody"}}}},"502":{"description":"Хранилище не ответило","content":{"*/*":{"schema":{"$ref":"#/components/schemas/StreamingResponseBody"}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.clubs.read"]}]}},"/clubs/my/elections/{electionId}/application/consent":{"get":{"tags":["CLUBS: Выборы Президента СП — кабинет студента"],"summary":"Своё заявление-согласие (PDF)","description":"Байты подписанного замороженного листа из ЭДО — автору. Content-Type: application/pdf, Content-Disposition: inline; filename*=UTF-8''<имя>, X-Content-Type-Options: nosniff, Cache-Control: private, no-store. Избирателям не отдаётся никогда.","operationId":"clubs_myConsent","parameters":[{"name":"electionId","in":"path","description":"Идентификатор выборов","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Байты PDF","content":{"*/*":{"schema":{"$ref":"#/components/schemas/StreamingResponseBody"}}}},"401":{"description":"Нет аутентификации","content":{"*/*":{"schema":{"$ref":"#/components/schemas/StreamingResponseBody"}}}},"403":{"content":{"*/*":{"schema":{"$ref":"#/components/schemas/StreamingResponseBody"}}}},"404":{"description":"Выборов или анкеты нет; согласие не найдено (не подписано)","content":{"*/*":{"schema":{"$ref":"#/components/schemas/StreamingResponseBody"}}}},"502":{"description":"Документооборот или хранилище не ответили","content":{"*/*":{"schema":{"$ref":"#/components/schemas/StreamingResponseBody"}}}},"504":{"description":"Документооборот не ответил вовремя","content":{"*/*":{"schema":{"$ref":"#/components/schemas/StreamingResponseBody"}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.clubs.read"]}]}},"/clubs/my/elections/{electionId}/application/consent/sign-payload":{"get":{"tags":["CLUBS: Выборы Президента СП — кабинет студента"],"summary":"Нагрузка подписи заявления-согласия","description":"Готовит лист «Заявление-согласие кандидата» в ЭДО по сегодняшним данным (ФИО «Фамилия Имя», программа, курс, ИИН, телефон WhatsApp, корпоративная почта, ссылка на соцсеть, дата подготовки) и отдаёт нагрузку для @qairu/ecp.signDocumentPair: pdfBase64 — замороженный лист, expectedIin — ИИН самого кандидата для фильтра сертификатов (пусто — не фильтровать), currentCmsBase64 / signableXmlBase64 / currentContentCmsBase64 — null, если нет. Можно, если анкета CONSENT_PENDING в окне приёма и список у отдела, или анкета SUBMITTED / ADMITTED / REJECTED без согласия (поданная до Е-28), пока список у отдела. Право участия проверяется свежим. Повторный вызов до подписи перерисовывает лист. Cache-Control: no-store.","operationId":"clubs_consentSignPayload","parameters":[{"name":"electionId","in":"path","description":"Идентификатор выборов","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Нагрузка подписи","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ConsentSignPayloadDto"}}}},"400":{"description":"Подписать согласие сейчас нельзя; в профиле нет ИИН или имени — обратитесь в офис регистратора; документооборот отклонил лист","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ConsentSignPayloadDto"}}}},"401":{"description":"Нет аутентификации","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ConsentSignPayloadDto"}}}},"403":{"description":"Раздел доступен студентам бакалавриата и магистратуры","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ConsentSignPayloadDto"}}}},"404":{"description":"Выборы не найдены или заявка не найдена","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ConsentSignPayloadDto"}}}},"409":{"description":"Согласие уже подписано","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ConsentSignPayloadDto"}}}},"502":{"description":"Документооборот не ответил","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ConsentSignPayloadDto"}}}},"503":{"description":"Справочник людей или учебный контур не ответил","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ConsentSignPayloadDto"}}}},"504":{"description":"Документооборот или справочник не ответили вовремя","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ConsentSignPayloadDto"}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.clubs.read"]}]}},"/clubs/my/elections/current":{"get":{"tags":["CLUBS: Выборы Президента СП — кабинет студента"],"summary":"Текущие выборы","description":"Опубликованные выборы с самой поздней датой голосования: фаза, сегодняшний день Астаны, шесть этапов, право участия, своя анкета, проголосовал ли (hasVoted), аннулирован ли СВОЙ голос отделом и почему (voteAnnulled, voteAnnulReason — hasVoted при этом остаётся true, повторно голосовать нельзя; кандидат не раскрывается) и итоги (только в фазе RESULTS). Выборов нет — {\"election\": null}. Не участвующий в выборах получает eligible=false без анкеты, профиля и итогов.","operationId":"clubs_current","responses":{"200":{"description":"Выборы или пустой ответ","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MyElectionResponse"}}}},"401":{"description":"Нет аутентификации","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MyElectionResponse"}}}},"403":{"content":{"*/*":{"schema":{"$ref":"#/components/schemas/MyElectionResponse"}}}},"503":{"description":"Справочник людей или учебный контур не ответил","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MyElectionResponse"}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.clubs.read"]}]}},"/clubs/my/consultations/slots":{"get":{"tags":["CLUBS: Психологическая служба — студент"],"summary":"Свободное время психолога","description":"Дни запрошенного периода внутри горизонта записи [сегодня, сегодня + 13] со свободным временем; available=false — в этот день записаться нельзя. Время — строки \"HH:mm\" по Астане.","operationId":"clubs_slots","parameters":[{"name":"psychologistId","in":"query","required":true,"schema":{"type":"string"}},{"name":"from","in":"query","description":"Первый день (ISO date)","required":false,"schema":{"type":"string","format":"date"},"example":"2026-10-23"},{"name":"to","in":"query","description":"Последний день (ISO date)","required":false,"schema":{"type":"string","format":"date"},"example":"2026-11-03"}],"responses":{"200":{"description":"Свободное время","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ConsultationSlotsDto"}}}},"401":{"description":"Нет аутентификации","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ConsultationSlotsDto"}}}},"403":{"content":{"*/*":{"schema":{"$ref":"#/components/schemas/ConsultationSlotsDto"}}}},"404":{"description":"Психолог не найден, не принимает записи или у него больше нет роли PSYCHOLOGIST","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ConsultationSlotsDto"}}}},"503":{"description":"Справочник пользователей временно недоступен","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ConsultationSlotsDto"}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.clubs.read"]}]}},"/clubs/my/consultations/psychologists":{"get":{"tags":["CLUBS: Психологическая служба — студент"],"summary":"Психологи","description":"Психологи, у которых открыт приём, по имени: формат и место очной консультации. Пустой список — запись сейчас недоступна.","operationId":"clubs_psychologists","responses":{"200":{"description":"Список психологов","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/ConsultationPsychologistDto"}}}}},"401":{"description":"Нет аутентификации","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/ConsultationPsychologistDto"}}}}},"403":{"content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/ConsultationPsychologistDto"}}}}},"503":{"description":"Справочник пользователей временно недоступен","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/ConsultationPsychologistDto"}}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.clubs.read"]}]}},"/clubs/my/clubs/{clubId}/members/{keycloakId}/photo":{"get":{"tags":["CLUBS: Клубы — кабинет студента"],"summary":"Фотография участника","description":"Портрет участника клуба. Доступен только участникам ТОГО ЖЕ клуба: состав наружу не выносится.","operationId":"clubs_memberPhoto","parameters":[{"name":"clubId","in":"path","description":"Идентификатор клуба","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"keycloakId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Байты картинки","content":{"*/*":{"schema":{"$ref":"#/components/schemas/StreamingResponseBody"}}}},"401":{"description":"Нет аутентификации","content":{"*/*":{"schema":{"$ref":"#/components/schemas/StreamingResponseBody"}}}},"403":{"description":"Роли студента нет","content":{"*/*":{"schema":{"$ref":"#/components/schemas/StreamingResponseBody"}}}},"404":{"description":"Клуб не найден, вызывающий в нём не состоит или у участника нет портрета","content":{"*/*":{"schema":{"$ref":"#/components/schemas/StreamingResponseBody"}}}},"502":{"description":"Файловое хранилище не ответило","content":{"*/*":{"schema":{"$ref":"#/components/schemas/StreamingResponseBody"}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.clubs.read"]}]}},"/clubs/my/clubs/{clubId}/join-requests":{"get":{"tags":["CLUBS: Клубы — участие"],"summary":"Заявки на вступление","description":"Ожидающие решения заявки клуба. Доступно главе и заместителю.","operationId":"clubs_joinRequests","parameters":[{"name":"clubId","in":"path","description":"Идентификатор клуба","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Список заявок","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/JoinRequestDto"}}}}},"401":{"description":"Нет аутентификации","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/JoinRequestDto"}}}}},"403":{"description":"Действие доступно главе или заместителю","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/JoinRequestDto"}}}}},"404":{"description":"Клуб не найден","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/JoinRequestDto"}}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.clubs.read"]}]}},"/clubs/my/clubs/{clubId}/invite":{"get":{"tags":["CLUBS: Клубы — кабинет студента"],"summary":"Пригласительная ссылка","description":"Ссылка на страницу вступления и её QR картинкой. Доступно главе и заместителю. Ссылка ведёт в кабинет студента — адрес кабинета задан переменной окружения.","operationId":"clubs_invite_1","parameters":[{"name":"clubId","in":"path","description":"Идентификатор клуба","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Ссылка и QR","content":{"*/*":{"schema":{"$ref":"#/components/schemas/InviteDto"}}}},"400":{"description":"Клуб в архиве","content":{"*/*":{"schema":{"$ref":"#/components/schemas/InviteDto"}}}},"401":{"description":"Нет аутентификации","content":{"*/*":{"schema":{"$ref":"#/components/schemas/InviteDto"}}}},"403":{"description":"Действие доступно главе или заместителю","content":{"*/*":{"schema":{"$ref":"#/components/schemas/InviteDto"}}}},"404":{"description":"Клуб не найден","content":{"*/*":{"schema":{"$ref":"#/components/schemas/InviteDto"}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.clubs.read"]}]}},"/clubs/my/club-creation":{"get":{"tags":["CLUBS: Клубы — кабинет студента"],"summary":"Можно ли создать клуб","description":"Один ответ на два правила сразу, чтобы кабинет не собирал их сам: открыт ли приём заявок на создание клубов и не возглавляет ли вызывающий живой клуб. `reason`: `INTAKE_CLOSED` — приём закрыт студенческим отделом; `ALREADY_HEAD` — вызывающий уже глава живого клуба; пусто — создавать можно.","operationId":"clubs_clubCreation","responses":{"200":{"description":"Можно или нельзя, с причиной","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ClubCreationAccessDto"}}}},"401":{"description":"Нет аутентификации","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ClubCreationAccessDto"}}}},"403":{"description":"Роли студента нет","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ClubCreationAccessDto"}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.clubs.read"]}]}},"/clubs/my/activity":{"get":{"tags":["CLUBS: Социальная активность"],"summary":"Моя активность","description":"Записи реестра за выбранный учебный год и показатели: SSCI, его перевод в GPA, накопленный GPA и предварительный интегральный показатель. Интегральный показатель считается, только когда известны обе его части. Год по умолчанию — текущий, граница учебного года — сентябрь.","operationId":"clubs_activity","parameters":[{"name":"academicYear","in":"query","description":"Учебный год «2026-2027»; пусто — текущий","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"Активность за год","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ActivityDto"}}}},"401":{"description":"Нет аутентификации","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ActivityDto"}}}},"403":{"description":"Раздел доступен студентам","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ActivityDto"}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.clubs.read"]}]}},"/clubs/my/achievements/{achievementId}/files/{fileId}":{"get":{"tags":["CLUBS: Внешние достижения"],"summary":"Файл заявки","description":"Байты приложенного документа; без кэширования.","operationId":"clubs_file","parameters":[{"name":"achievementId","in":"path","description":"Идентификатор достижения","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"fileId","in":"path","description":"Идентификатор файла","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Файл","content":{"*/*":{"schema":{"$ref":"#/components/schemas/StreamingResponseBody"}}}},"401":{"description":"Нет аутентификации","content":{"*/*":{"schema":{"$ref":"#/components/schemas/StreamingResponseBody"}}}},"404":{"description":"Достижение или файл не найдены","content":{"*/*":{"schema":{"$ref":"#/components/schemas/StreamingResponseBody"}}}},"502":{"description":"Файловое хранилище недоступно","content":{"*/*":{"schema":{"$ref":"#/components/schemas/StreamingResponseBody"}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.clubs.read"]}]}},"/clubs/health":{"get":{"tags":["CLUBS: Клубы — живость"],"summary":"Живость сервиса","description":"Отвечает UP и числом действующих клубов. Публичная точка: страница клубов на сайте вуза рисуется до всякого входа. Персональных данных не отдаёт.","operationId":"clubs_health","responses":{"200":{"description":"Сервис жив","content":{"*/*":{"schema":{"$ref":"#/components/schemas/HealthDto"}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.clubs.read"]}]}},"/clubs/catalog/posts/{postId}/images/{fileId}":{"get":{"tags":["CLUBS: Клубы — каталог кабинета"],"summary":"Картинка записи","description":"Байты одной картинки мини-галереи записи. Показывается тому же, кому видна сама запись: запись «участникам клуба» отдаёт картинку только участнику, скрытая запись — никому. Файл обязан принадлежать этой записи. Идентификаторы приходят в поле images самой записи, в порядке показа.","operationId":"clubs_postImage","parameters":[{"name":"postId","in":"path","description":"Идентификатор записи","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"fileId","in":"path","description":"Идентификатор файла из поля images","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Байты картинки","content":{"*/*":{"schema":{"$ref":"#/components/schemas/StreamingResponseBody"}}}},"401":{"description":"Нет аутентификации","content":{"*/*":{"schema":{"$ref":"#/components/schemas/StreamingResponseBody"}}}},"404":{"description":"Запись или картинка не найдены","content":{"*/*":{"schema":{"$ref":"#/components/schemas/StreamingResponseBody"}}}},"502":{"description":"Файловое хранилище не ответило","content":{"*/*":{"schema":{"$ref":"#/components/schemas/StreamingResponseBody"}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.clubs.read"]}]}},"/clubs/catalog/plan-rules":{"get":{"tags":["CLUBS: Клубы — каталог кабинета"],"summary":"Правила полноты плана мероприятий","description":"Окно учебного года и два порога, по которым считается полнота плана клуба: сколько мероприятий нужно в каждом месяце окна и сколько из них должны быть из ценностных направлений. Доступно любому вошедшему — форма создания клуба рисует по ним живую сводку «месяцев N из M, ценностных K из L». `months` — готовый список месяцев окна.","operationId":"clubs_planRules","responses":{"200":{"description":"Окно и пороги","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ClubPlanRulesDto"}}}},"401":{"description":"Нет аутентификации","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ClubPlanRulesDto"}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.clubs.read"]}]}},"/clubs/catalog/feed":{"get":{"tags":["CLUBS: Клубы — каталог кабинета"],"summary":"Общая лента","description":"Записи «всем студентам» всех действующих клубов плюс любые записи клубов, в которых состоит вызывающий, по убыванию даты.","operationId":"clubs_feed","parameters":[{"name":"page","in":"query","description":"Номер страницы с нуля","required":false,"schema":{"type":"integer","format":"int32"},"example":0},{"name":"size","in":"query","description":"Размер страницы, максимум 100","required":false,"schema":{"type":"integer","format":"int32"},"example":20}],"responses":{"200":{"description":"Страница записей","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PageDtoClubPostDto"}}}},"401":{"description":"Нет аутентификации","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PageDtoClubPostDto"}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.clubs.read"]}]}},"/clubs/catalog/events":{"get":{"tags":["CLUBS: Мероприятия — афиша кабинета"],"summary":"Афиша","description":"Мероприятия вуза и публичные плюс мероприятия клубов, где состоит вызывающий: опубликованные, закрытые и подтверждённые, а отменённые — пока не прошла их дата. scope=mine оставляет только то, где вызывающий записан, отмечался или сам ведёт мероприятие. format=OFFLINE|ONLINE отбирает по формату. listState каждой строки — OPEN | FULL | CLOSED | NONE | CANCELLED | FINISHED.","operationId":"clubs_events_3","parameters":[{"name":"from","in":"query","description":"Начало интервала (ISO date-time)","required":false,"schema":{"type":"string","format":"date-time"},"example":"2026-10-23T00:00:00+05:00"},{"name":"to","in":"query","description":"Конец интервала (ISO date-time)","required":false,"schema":{"type":"string","format":"date-time"},"example":"2026-10-30T23:59:59+05:00"},{"name":"scope","in":"query","description":"all или mine","required":false,"schema":{"type":"string"},"example":"all"},{"name":"format","in":"query","description":"OFFLINE или ONLINE; пусто и неизвестное значение — все форматы","required":false,"schema":{"type":"string"},"example":"ONLINE"},{"name":"page","in":"query","description":"Номер страницы с нуля","required":false,"schema":{"type":"integer","format":"int32"}},{"name":"size","in":"query","description":"Размер страницы, максимум 100","required":false,"schema":{"type":"integer","format":"int32"}}],"responses":{"200":{"description":"Страница афиши","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PageDtoCatalogEventDto"}}}},"401":{"description":"Нет аутентификации","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PageDtoCatalogEventDto"}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.clubs.read"]}]}},"/clubs/catalog/events/{eventId}":{"get":{"tags":["CLUBS: Мероприятия — афиша кабинета"],"summary":"Мероприятие","description":"Карточка мероприятия и состояние вызывающего по нему: запись, отметка, отчёт и срок отчёта. ОТМЕНЁННОЕ мероприятие открывают те, кто был на него записан или отмечен присутствовавшим, — причина отмены приходит в поле cancelReason; действий на отменённом не появляется. Отменённое, но ещё не прошедшее мероприятие открывает и любой, кому оно видно в афише. contactInfo и listState — как в строке афиши.","operationId":"clubs_event_4","parameters":[{"name":"eventId","in":"path","description":"Идентификатор мероприятия","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Мероприятие","content":{"*/*":{"schema":{"$ref":"#/components/schemas/CatalogEventDetailDto"}}}},"401":{"description":"Нет аутентификации","content":{"*/*":{"schema":{"$ref":"#/components/schemas/CatalogEventDetailDto"}}}},"404":{"description":"Мероприятие не найдено","content":{"*/*":{"schema":{"$ref":"#/components/schemas/CatalogEventDetailDto"}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.clubs.read"]}]}},"/clubs/catalog/events/{eventId}/poster":{"get":{"tags":["CLUBS: Мероприятия — афиша кабинета"],"summary":"Афиша мероприятия","description":"Байты картинки; без кэширования.","operationId":"clubs_poster_2","parameters":[{"name":"eventId","in":"path","description":"Идентификатор мероприятия","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Картинка","content":{"*/*":{"schema":{"$ref":"#/components/schemas/StreamingResponseBody"}}}},"401":{"description":"Нет аутентификации","content":{"*/*":{"schema":{"$ref":"#/components/schemas/StreamingResponseBody"}}}},"404":{"description":"Мероприятие или афиша не найдены","content":{"*/*":{"schema":{"$ref":"#/components/schemas/StreamingResponseBody"}}}},"502":{"description":"Файловое хранилище недоступно","content":{"*/*":{"schema":{"$ref":"#/components/schemas/StreamingResponseBody"}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.clubs.read"]}]}},"/clubs/catalog/event-directions":{"get":{"tags":["CLUBS: Клубы — каталог кабинета"],"summary":"Справочник направлений мероприятий","description":"Действующие направления МЕРОПРИЯТИЙ на трёх языках, с разделом (`block`), признаком «ценностное» (`valueBased`) и расшифровкой — ими заполняется план мероприятий и форма мероприятия.","operationId":"clubs_eventDirections_1","responses":{"200":{"description":"Список направлений мероприятий","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/EventDirectionDto"}}}}},"401":{"description":"Нет аутентификации","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/EventDirectionDto"}}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.clubs.read"]}]}},"/clubs/catalog/directions":{"get":{"tags":["CLUBS: Клубы — каталог кабинета"],"summary":"Справочник направлений","description":"Действующие направления на трёх языках — ими фильтруется список и заполняется форма создания клуба.","operationId":"clubs_directions_1","responses":{"200":{"description":"Список направлений","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/DirectionDto"}}}}},"401":{"description":"Нет аутентификации","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/DirectionDto"}}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.clubs.read"]}]}},"/clubs/catalog/clubs":{"get":{"tags":["CLUBS: Клубы — каталог кабинета"],"summary":"Список клубов","description":"Утверждённые клубы. У каждого клуба, в котором состоит вызывающий, приходит его роль — по ней кабинет отделяет вкладку «Мои клубы» от общего списка.","operationId":"clubs_clubs_1","parameters":[{"name":"direction","in":"query","description":"Код направления","required":false,"schema":{"type":"string"},"example":"AI_TECH"},{"name":"q","in":"query","description":"Строка поиска по названию и описанию","required":false,"schema":{"type":"string"}},{"name":"page","in":"query","description":"Номер страницы с нуля","required":false,"schema":{"type":"integer","format":"int32"},"example":0},{"name":"size","in":"query","description":"Размер страницы, максимум 100","required":false,"schema":{"type":"integer","format":"int32"},"example":20}],"responses":{"200":{"description":"Страница списка","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PageDtoCatalogClubDto"}}}},"401":{"description":"Нет аутентификации","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PageDtoCatalogClubDto"}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.clubs.read"]}]}},"/clubs/catalog/clubs/{clubId}":{"get":{"tags":["CLUBS: Клубы — каталог кабинета"],"summary":"Карточка клуба","description":"Описание, цель, глава с фотографией, куратор, почта клуба и состояние кнопки вступления для вызывающего (поле my).","operationId":"clubs_club_2","parameters":[{"name":"clubId","in":"path","description":"Идентификатор клуба","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Карточка клуба","content":{"*/*":{"schema":{"$ref":"#/components/schemas/CatalogClubDetailDto"}}}},"401":{"description":"Нет аутентификации","content":{"*/*":{"schema":{"$ref":"#/components/schemas/CatalogClubDetailDto"}}}},"404":{"description":"Клуб не найден","content":{"*/*":{"schema":{"$ref":"#/components/schemas/CatalogClubDetailDto"}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.clubs.read"]}]}},"/clubs/catalog/clubs/{clubId}/posts":{"get":{"tags":["CLUBS: Клубы — каталог кабинета"],"summary":"Лента клуба","description":"Записи клуба по убыванию даты. Посторонний видит только записи, адресованные всем студентам; участник — все записи своего клуба. Скрытые записи не отдаются никому.","operationId":"clubs_posts","parameters":[{"name":"clubId","in":"path","description":"Идентификатор клуба","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"page","in":"query","description":"Номер страницы с нуля","required":false,"schema":{"type":"integer","format":"int32"},"example":0},{"name":"size","in":"query","description":"Размер страницы, максимум 100","required":false,"schema":{"type":"integer","format":"int32"},"example":20}],"responses":{"200":{"description":"Страница записей","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PageDtoClubPostDto"}}}},"401":{"description":"Нет аутентификации","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PageDtoClubPostDto"}}}},"404":{"description":"Клуб не найден","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PageDtoClubPostDto"}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.clubs.read"]}]}},"/clubs/catalog/clubs/{clubId}/logo":{"get":{"tags":["CLUBS: Клубы — каталог кабинета"],"summary":"Логотип клуба","description":"Байты логотипа. Отдаются потоком со своего домена, без кэша: видимость клуба может измениться решением студенческого отдела.","operationId":"clubs_logo_1","parameters":[{"name":"clubId","in":"path","description":"Идентификатор клуба","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Байты картинки","content":{"*/*":{"schema":{"$ref":"#/components/schemas/StreamingResponseBody"}}}},"401":{"description":"Нет аутентификации","content":{"*/*":{"schema":{"$ref":"#/components/schemas/StreamingResponseBody"}}}},"404":{"description":"Клуб не найден или без логотипа","content":{"*/*":{"schema":{"$ref":"#/components/schemas/StreamingResponseBody"}}}},"502":{"description":"Файловое хранилище не ответило","content":{"*/*":{"schema":{"$ref":"#/components/schemas/StreamingResponseBody"}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.clubs.read"]}]}},"/clubs/catalog/clubs/{clubId}/head-photo":{"get":{"tags":["CLUBS: Клубы — каталог кабинета"],"summary":"Фотография главы клуба","description":"Портрет главы: он представляет клуб, и его видит любой вошедший. Портреты остальных участников отдаются только участникам того же клуба.","operationId":"clubs_headPhoto","parameters":[{"name":"clubId","in":"path","description":"Идентификатор клуба","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Байты картинки","content":{"*/*":{"schema":{"$ref":"#/components/schemas/StreamingResponseBody"}}}},"401":{"description":"Нет аутентификации","content":{"*/*":{"schema":{"$ref":"#/components/schemas/StreamingResponseBody"}}}},"404":{"description":"Клуб без главы или у главы нет портрета","content":{"*/*":{"schema":{"$ref":"#/components/schemas/StreamingResponseBody"}}}},"502":{"description":"Файловое хранилище не ответило","content":{"*/*":{"schema":{"$ref":"#/components/schemas/StreamingResponseBody"}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.clubs.read"]}]}},"/clubs/catalog/clubs/{clubId}/events":{"get":{"tags":["CLUBS: Мероприятия — афиша кабинета"],"summary":"Мероприятия клуба","description":"Лента мероприятий одного клуба. past=true отдаёт прошедшие (включая закрытые и подтверждённые), по умолчанию — предстоящие. Участник клуба видит и внутренние, и продолжает видеть ленту, пока клуб приостановлен.","operationId":"clubs_clubEvents","parameters":[{"name":"clubId","in":"path","description":"Идентификатор клуба","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"past","in":"query","description":"Показать прошедшие","required":false,"schema":{"type":"boolean"}},{"name":"page","in":"query","description":"Номер страницы с нуля","required":false,"schema":{"type":"integer","format":"int32"}},{"name":"size","in":"query","description":"Размер страницы, максимум 100","required":false,"schema":{"type":"integer","format":"int32"}}],"responses":{"200":{"description":"Страница мероприятий","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PageDtoCatalogEventDto"}}}},"401":{"description":"Нет аутентификации","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PageDtoCatalogEventDto"}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.clubs.read"]}]}},"/projects/supervisor/opportunities/{id}":{"get":{"tags":["PROJECTS: Supervisor: recruiting"],"summary":"One opportunity","description":"The staff view of a single opportunity: the budget is present, and so are the author, the named supervisor and the decision trail. Anything else answers 404, never 403.","operationId":"projects_detail","parameters":[{"name":"id","in":"path","description":"Opportunity id","required":true,"schema":{"type":"string"}},{"name":"Accept-Language","in":"header","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"The card","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminOpportunityDto"}}}},"401":{"description":"No token","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminOpportunityDto"}}}},"403":{"description":"Neither a teacher nor a portal admin","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminOpportunityDto"}}}},"404":{"description":"No such opportunity, or not yours","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AdminOpportunityDto"}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.projects.read"]}]}},"/projects/supervisor/projects/{id}/tasks":{"get":{"tags":["PROJECTS: Supervisor: projects"],"summary":"Tasks of the project","description":"Access: the supervisor of this project.","operationId":"projects_tasks","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Tasks","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/TaskDto"}}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.projects.read"]}]}},"/projects/supervisor/projects/{id}/milestones":{"get":{"tags":["PROJECTS: Supervisor: projects"],"summary":"Milestones of the project","description":"Access: the supervisor of this project.","operationId":"projects_milestones","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Milestones in order","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/MilestoneDto"}}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.projects.read"]}]}},"/projects/supervisor/opportunities":{"get":{"tags":["PROJECTS: Supervisor: recruiting"],"summary":"My opportunities","description":"Opportunities authored by the caller, in any state. The staff view: the budget is always present here, unlike the student one. applicationsCount counts every application staff may open, decided ones included; pendingApplicationsCount only the ones waiting for a decision (SUBMITTED, UNDER_REVIEW).","operationId":"projects_mine","parameters":[{"name":"Accept-Language","in":"header","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"Own opportunities","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/AdminOpportunityDto"}}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.projects.read"]}]}},"/projects/my/resource-requests":{"get":{"tags":["PROJECTS: Student: resources"],"summary":"My resource requests","description":"Own requests with the stage of the two-step approval: REQUEST, REVIEW, ALLOCATION.","operationId":"projects_myRequests","parameters":[{"name":"status","in":"query","required":false,"schema":{"type":"string"}},{"name":"Accept-Language","in":"header","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"Own requests","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/ResourceRequestDto"}}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.projects.read"]}]}},"/projects/my/proposals":{"get":{"tags":["PROJECTS: Student: opportunities"],"summary":"My proposals","description":"Own proposals with their moderation status and the moderator comment.","operationId":"projects_myProposals","parameters":[{"name":"Accept-Language","in":"header","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"Own proposals, newest first","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/MyProposalDto"}}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.projects.read"]}]}},"/projects/my/projects/{id}/deliverables":{"get":{"tags":["PROJECTS: Student: my projects"],"summary":"Results of a project","description":"Every result of the project with its versions and attachments.","operationId":"projects_deliverables","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Results","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/DeliverableDto"}}}}},"404":{"description":"Not your project","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/DeliverableDto"}}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.projects.read"]}]}},"/projects/my/projects/{id}/contributions":{"get":{"tags":["PROJECTS: Student: my projects"],"summary":"My contributions on a project","description":"Only the caller's own contributions.","operationId":"projects_contributions","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Accept-Language","in":"header","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"Own contributions","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/ContributionDto"}}}}},"404":{"description":"Not your project","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/ContributionDto"}}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.projects.read"]}]}},"/projects/supervisor/resource-requests":{"get":{"tags":["PROJECTS: Supervisor: decisions"],"summary":"Resource requests of my projects","description":"Everything filed on the projects the caller leads, so the endorsement queue is one list.","operationId":"projects_resourceRequests","parameters":[{"name":"Accept-Language","in":"header","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"Requests","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/ResourceRequestDto"}}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.projects.read"]}]}},"/projects/supervisor/projects":{"get":{"tags":["PROJECTS: Supervisor: projects"],"summary":"My projects","description":"Projects where the caller is the supervisor, with the counters of what waits for his decision. pendingApplications counts only the applications to the project's own recruitment that are sent and not yet decided (SUBMITTED, UNDER_REVIEW); an accepted, rejected, withdrawn or expired one is not counted.","operationId":"projects_projects","parameters":[{"name":"status","in":"query","description":"active | completed | all","required":false,"schema":{"type":"string"}},{"name":"Accept-Language","in":"header","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"Own projects","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/SupervisorProjectCardDto"}}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.projects.read"]}]}},"/projects/supervisor/projects/{id}":{"get":{"tags":["PROJECTS: Supervisor: projects"],"summary":"One project","description":"The whole supervisor page in one request: the team, the milestones, every task, the results, the contributions awaiting confirmation, the granted resources and the request queue.","operationId":"projects_project","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Accept-Language","in":"header","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"The project","content":{"*/*":{"schema":{"$ref":"#/components/schemas/SupervisorProjectDto"}}}},"404":{"description":"Not your project","content":{"*/*":{"schema":{"$ref":"#/components/schemas/SupervisorProjectDto"}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.projects.read"]}]}},"/projects/supervisor/projects/{id}/contributions":{"get":{"tags":["PROJECTS: Supervisor: decisions"],"summary":"Contributions awaiting confirmation","description":"The queue of a project, with the claimed skills and the tasks each contribution stands on. Access: the supervisor of the project.","operationId":"projects_contributions_1","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"status","in":"query","required":false,"schema":{"type":"string"}},{"name":"Accept-Language","in":"header","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"Contributions","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/ContributionDto"}}}}},"404":{"description":"Not your project","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/ContributionDto"}}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.projects.read"]}]}},"/projects/supervisor/opportunities/{id}/applications":{"get":{"tags":["PROJECTS: Supervisor: recruiting"],"summary":"Applications to my opportunity","description":"Every application to THIS opportunity, with the motivation, the skills the author had confirmed when applying and the team composition. There is no match percentage. confirmedSkills[].name is in the language of THIS request (Accept-Language), whatever language the author applied in: the stored snapshot keeps skill ids only. WARNING: a skill the directory no longer knows and that has no name stored from before 26.09 is left out of the list.","operationId":"projects_applications","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"status","in":"query","required":false,"schema":{"type":"string"}},{"name":"Accept-Language","in":"header","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"Applications","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/ApplicationDto"}}}}},"404":{"description":"Not your opportunity","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/ApplicationDto"}}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.projects.read"]}]}},"/projects/my/resources":{"get":{"tags":["PROJECTS: Student: resources"],"summary":"Resources that can be asked for","description":"The catalogue a request form is filled from: only resources in service. A sensitive dataset is marked requiresApproval so the form can say so before the person writes anything.","operationId":"projects_resources_1","parameters":[{"name":"kind","in":"query","required":false,"schema":{"type":"string"}},{"name":"Accept-Language","in":"header","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"Catalogue","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/ResourceDto"}}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.projects.read"]}]}},"/projects/my/projects":{"get":{"tags":["PROJECTS: Student: my projects"],"summary":"My projects","description":"Cards of the projects where the caller is an ACTIVE member, with the team, the supervisor and the nearest own task. status=active hides the finished ones, status=completed shows only those.","operationId":"projects_myProjects","parameters":[{"name":"status","in":"query","description":"active | completed | all","required":false,"schema":{"type":"string"},"example":"active"},{"name":"Accept-Language","in":"header","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"Own projects","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/MyProjectCardDto"}}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.projects.read"]}]}},"/projects/my/projects/{id}":{"get":{"tags":["PROJECTS: Student: my projects"],"summary":"One project","description":"The whole project page in ONE request: milestones, own tasks, the team, the results, own contributions, granted resources and pending requests. WARNING: allocations carry the LIMIT and the access period and nothing about consumption -- nobody enters actual usage in this version.","operationId":"projects_myProject","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Accept-Language","in":"header","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"The project page","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MyProjectDto"}}}},"404":{"description":"Not your project","content":{"*/*":{"schema":{"$ref":"#/components/schemas/MyProjectDto"}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.projects.read"]}]}},"/projects/my/projects/{id}/tasks":{"get":{"tags":["PROJECTS: Student: my projects"],"summary":"Tasks of a project","description":"scope=mine returns the caller's tasks, scope=all the whole board.","operationId":"projects_tasks_1","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"scope","in":"query","description":"mine | all","required":false,"schema":{"type":"string"},"example":"mine"}],"responses":{"200":{"description":"Tasks","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/TaskDto"}}}}},"404":{"description":"Not your project","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/TaskDto"}}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.projects.read"]}]}},"/projects/my/overview/opportunities":{"get":{"tags":["PROJECTS: Student: opportunities"],"summary":"Open opportunities for the overview tab","description":"Published opportunities with the nearest application deadline first; those without a deadline come last, newer publications first among equals. There is no match percentage and no personal ranking. WARNING: the budget of an order is present ONLY when a member of staff switched it on -- otherwise the field is absent from the JSON, not null.","operationId":"projects_overview","parameters":[{"name":"limit","in":"query","description":"How many cards, default 5","required":false,"schema":{"type":"integer","format":"int32","default":5},"example":5},{"name":"Accept-Language","in":"header","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"Up to `limit` cards","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/OpportunityCardDto"}}}}},"401":{"description":"No token","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/OpportunityCardDto"}}}}},"403":{"description":"Not a student","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/OpportunityCardDto"}}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.projects.read"]}]}},"/projects/my/opportunities":{"get":{"tags":["PROJECTS: Student: opportunities"],"summary":"Catalogue of opportunities","description":"The full feed with the filters of the screen: text, kind, paid/unpaid, role, skills, 'no project experience needed', 'recruiting into a team'. The order is ONE: the nearest application deadline first, opportunities without a deadline last, newer publications first among equals. A `sort` parameter from an old client is ignored.","operationId":"projects_catalog","parameters":[{"name":"q","in":"query","required":false,"schema":{"type":"string"}},{"name":"kind","in":"query","required":false,"schema":{"type":"array","items":{"type":"string"}}},{"name":"paid","in":"query","required":false,"schema":{"type":"boolean"}},{"name":"roleCode","in":"query","required":false,"schema":{"type":"string"}},{"name":"skillIds","in":"query","required":false,"schema":{"type":"array","items":{"type":"string"}}},{"name":"beginnerFriendly","in":"query","required":false,"schema":{"type":"boolean"}},{"name":"recruiting","in":"query","required":false,"schema":{"type":"boolean"}},{"name":"page","in":"query","required":false,"schema":{"type":"integer","format":"int32"}},{"name":"size","in":"query","required":false,"schema":{"type":"integer","format":"int32"}},{"name":"Accept-Language","in":"header","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"A page of cards","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PageDtoOpportunityCardDto"}}}},"400":{"description":"page below zero","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PageDtoOpportunityCardDto"}}}},"401":{"description":"No token","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PageDtoOpportunityCardDto"}}}},"403":{"description":"Not a student","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PageDtoOpportunityCardDto"}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.projects.read"]}]}},"/projects/my/opportunities/{id}":{"get":{"tags":["PROJECTS: Student: opportunities"],"summary":"One opportunity","description":"Everything the detail page draws in ONE request: the description, the skills, the roles, the resources of its lab, the required skills the caller has already confirmed (myConfirmedSkills; empty when learning is silent) and whether applying is possible at all. applyBlockedCode is the machine reason the button is replaced by a line (ALREADY_MEMBER / OPPORTUNITY_CLOSED / DEADLINE_PASSED / ALREADY_APPLIED). A caller who is an ACTIVE member of the project this opportunity recruits into gets myMembership = {projectId} and applyBlockedCode = ALREADY_MEMBER -- membership wins over every other reason, including a closed recruitment; for anybody else myMembership is absent from the JSON. Each read increments the view counter that feeds the funnel metric. An opportunity that is neither published nor closed answers 404.","operationId":"projects_detail_2","parameters":[{"name":"id","in":"path","description":"Opportunity id","required":true,"schema":{"type":"string"}},{"name":"Accept-Language","in":"header","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"The card","content":{"*/*":{"schema":{"$ref":"#/components/schemas/OpportunityDetailDto"}}}},"401":{"description":"No token","content":{"*/*":{"schema":{"$ref":"#/components/schemas/OpportunityDetailDto"}}}},"403":{"description":"Not a student","content":{"*/*":{"schema":{"$ref":"#/components/schemas/OpportunityDetailDto"}}}},"404":{"description":"No such opportunity, or it is not published","content":{"*/*":{"schema":{"$ref":"#/components/schemas/OpportunityDetailDto"}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.projects.read"]}]}},"/projects/my/invite-candidates":{"get":{"tags":["PROJECTS: Student: opportunities"],"summary":"Search a student to invite into a team","description":"Minimal disclosure by contract: a name, and the programme and year only to tell namesakes apart. No IIN, no phone, no mail. Fewer than 3 characters returns an empty list.","operationId":"projects_inviteCandidates","parameters":[{"name":"q","in":"query","description":"At least 3 characters","required":false,"schema":{"type":"string"},"example":"Айдар"},{"name":"limit","in":"query","description":"1..20, default 10","required":false,"schema":{"type":"integer","format":"int32"}}],"responses":{"200":{"description":"Candidates","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/InviteCandidateDto"}}}}},"502":{"description":"The people directory did not answer","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/InviteCandidateDto"}}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.projects.read"]}]}},"/projects/my/invitations":{"get":{"tags":["PROJECTS: Student: my applications"],"summary":"Invitations addressed to me","description":"Pending invitations into somebody's team application, with the author, the role and the reply deadline.","operationId":"projects_invitations","parameters":[{"name":"Accept-Language","in":"header","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"Pending invitations","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/TeamInvitationDto"}}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.projects.read"]}]}},"/projects/my/applications":{"get":{"tags":["PROJECTS: Student: my applications"],"summary":"My applications","description":"Own applications, newest first, with the state of every team invitation inside them.","operationId":"projects_mine_1","parameters":[{"name":"status","in":"query","description":"Filter by status","required":false,"schema":{"type":"string"},"example":"SUBMITTED"},{"name":"Accept-Language","in":"header","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"Own applications","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/ApplicationDto"}}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.projects.read"]}]}},"/projects/my/allocations":{"get":{"tags":["PROJECTS: Student: resources"],"summary":"Granted resources","description":"Allocations of the projects the caller is an ACTIVE member of. Carries the limit, the access period and, when an address was given, the workspace link -- when it was not, there is no link field at all rather than a dead button.","operationId":"projects_allocations","parameters":[{"name":"projectId","in":"query","required":false,"schema":{"type":"string"}},{"name":"kind","in":"query","required":false,"schema":{"type":"string"}},{"name":"Accept-Language","in":"header","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"Allocations","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/AllocationDto"}}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.projects.read"]}]}},"/projects/health":{"get":{"tags":["PROJECTS: Projects health"],"summary":"Module liveness","description":"Answers that the service is up and how many projects are currently in work. Access: anonymous. Carries no personal data and no business content.","operationId":"projects_health","responses":{"200":{"description":"The service is up","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PROJECTS_HealthDto"}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.projects.read"]}]}},"/projects/catalog/skills":{"get":{"tags":["PROJECTS: Projects catalogue"],"summary":"Search the competency graph","description":"Skills for every picker of the module. Free text is accepted NOWHERE in this module: an opportunity, a task and a contribution all reference a skill by its graph identifier. Access: any logged-in caller. Fewer than 2 characters returns an empty list rather than the whole graph. WARNING: a silent learning contour answers 502 and not an empty list -- an empty list would read as 'there is no such skill'.","operationId":"projects_skills","parameters":[{"name":"q","in":"query","description":"Search string, at least 2 characters","required":false,"schema":{"type":"string"},"example":"python"},{"name":"limit","in":"query","description":"Ceiling of the answer, 1..30","required":false,"schema":{"type":"integer","format":"int32"},"example":20},{"name":"Accept-Language","in":"header","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"Up to `limit` rows of the graph","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/PROJECTS_SkillOptionDto"}}}}},"401":{"description":"No token","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/PROJECTS_SkillOptionDto"}}}}},"502":{"description":"The competency graph did not answer","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/PROJECTS_SkillOptionDto"}}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.projects.read"]}]}},"/projects/catalog/roles":{"get":{"tags":["PROJECTS: Projects catalogue"],"summary":"Roles of a project participant","description":"The catalogue a desired role in an application and a role on the roster are picked from. Access: any logged-in caller.","operationId":"projects_roles_1","parameters":[{"name":"Accept-Language","in":"header","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"Active rows, in display order","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/RoleOptionDto"}}}}},"401":{"description":"No token","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/RoleOptionDto"}}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.projects.read"]}]}},"/projects/catalog/labs":{"get":{"tags":["PROJECTS: Projects catalogue"],"summary":"Labs","description":"Active labs, for the lab picker of an opportunity and of a resource card. Access: any logged-in caller.","operationId":"projects_labs_1","parameters":[{"name":"Accept-Language","in":"header","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"Active labs by name","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/LabOptionDto"}}}}},"401":{"description":"No token","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/LabOptionDto"}}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.projects.read"]}]}},"/ideas/my":{"get":{"tags":["IDEAS: Student Ideas (my)"],"summary":"Мои идеи","description":"Все идеи вызывающего студента, новые сверху. Чужие идеи в выдачу не попадают никогда.","operationId":"ideas_listMine","responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/IdeaResponse"}}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.ideas.read"]}]}},"/complaints/my":{"get":{"tags":["IDEAS: Complaints (my)"],"summary":"Мои сообщения","description":"Все сообщения вызывающего, новые сверху. Чужие в выдачу не попадают никогда.","operationId":"ideas_listMine_1","responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/ComplaintResponse"}}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.ideas.read"]}]}},"/ideas":{"get":{"tags":["IDEAS: Student Ideas (staff)"],"summary":"Список идей","description":"Страница идей, новые сверху. Поиск q идёт по названию, тексту, ФИО и почте автора без учёта регистра. Размер страницы — от 1 до 100, по умолчанию 20.","operationId":"ideas_search","parameters":[{"name":"status","in":"query","description":"Статус: NEW, IN_REVIEW, ACCEPTED, DECLINED, WITHDRAWN. Пусто — все, кроме отозванных","required":false,"schema":{"type":"string"}},{"name":"q","in":"query","description":"Строка поиска по названию, тексту, ФИО и почте автора","required":false,"schema":{"type":"string"}},{"name":"page","in":"query","description":"Номер страницы с нуля","required":false,"schema":{"type":"integer","format":"int32","default":0}},{"name":"size","in":"query","description":"Размер страницы, 1..100","required":false,"schema":{"type":"integer","format":"int32","default":20}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/IdeaPageResponse"}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.ideas.read"]}]}},"/ideas/{id}":{"get":{"tags":["IDEAS: Student Ideas (staff)"],"summary":"Идея","description":"Карточка идеи со снимком автора, файлами и разбором ИИ.","operationId":"ideas_get_13","parameters":[{"name":"id","in":"path","description":"id идеи","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/IdeaResponse"}}}},"404":{"description":"Идея не найдена","content":{"*/*":{"schema":{"$ref":"#/components/schemas/IdeaResponse"}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.ideas.read"]}]}},"/ideas/my/{id}":{"get":{"tags":["IDEAS: Student Ideas (my)"],"summary":"Моя идея","description":"Карточка собственной идеи: статус, текст, файлы и ответ университета, если он есть.","operationId":"ideas_getMine","parameters":[{"name":"id","in":"path","description":"id идеи","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/IdeaResponse"}}}},"404":{"description":"Идея не найдена или принадлежит другому человеку","content":{"*/*":{"schema":{"$ref":"#/components/schemas/IdeaResponse"}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.ideas.read"]}]}},"/complaints":{"get":{"tags":["IDEAS: Complaints (admin)"],"summary":"Список жалоб","description":"Страница сообщений о проблемах, новые сверху. Без фильтров выдаются ВСЕ статусы, включая решённые и отклонённые. Фильтры status и app приводятся к верхнему регистру. Поиск q идёт по тезису, тексту, ФИО и почте автора и по адресу страницы без учёта регистра. Размер страницы — от 1 до 100, по умолчанию 20.","operationId":"ideas_search_2","parameters":[{"name":"status","in":"query","description":"Статус: NEW, IN_REVIEW, RESOLVED, REJECTED. Пусто — все","required":false,"schema":{"type":"string"}},{"name":"app","in":"query","description":"Кабинет: CAMPUS, FACULTY, ADMISSION, MBA, PORTAL, OTHER. Пусто — все","required":false,"schema":{"type":"string"}},{"name":"q","in":"query","description":"Строка поиска по тезису, тексту, автору и адресу страницы","required":false,"schema":{"type":"string"}},{"name":"page","in":"query","description":"Номер страницы с нуля","required":false,"schema":{"type":"integer","format":"int32","default":0}},{"name":"size","in":"query","description":"Размер страницы, 1..100","required":false,"schema":{"type":"integer","format":"int32","default":20}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ComplaintPageResponse"}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.ideas.read"]}]}},"/complaints/{id}":{"get":{"tags":["IDEAS: Complaints (admin)"],"summary":"Жалоба","description":"Карточка сообщения: снимок обстановки (адрес, заголовок страницы, язык, браузер, окно, экран, часовой пояс, время на устройстве), снимок автора, текст и файлы.","operationId":"ideas_get_16","parameters":[{"name":"id","in":"path","description":"id жалобы","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ComplaintResponse"}}}},"404":{"description":"Жалоба не найдена","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ComplaintResponse"}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.ideas.read"]}]}},"/complaints/my/{id}":{"get":{"tags":["IDEAS: Complaints (my)"],"summary":"Моё сообщение","description":"Карточка собственного сообщения: статус, текст, снимок страницы, файлы и ответ администратора, если он есть.","operationId":"ideas_getMine_1","parameters":[{"name":"id","in":"path","description":"id жалобы","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ComplaintResponse"}}}},"404":{"description":"Сообщение не найдено или принадлежит другому человеку","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ComplaintResponse"}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.ideas.read"]}]}},"/me":{"get":{"operationId":"os_me","tags":["OS API"],"summary":"Describe the credentials in use","description":"With an API key: the name, display prefix, modules, request rate limit and expiry of the key, and its usage in the current month. With an access token of Sign in with QAIRU: the application, the student (subject, name, e-mail, student identifier), the modules the token may use now and the expiry of the token.","responses":{"200":{"description":"The credentials in use.","content":{"application/json":{"schema":{"type":"object"}}}}}}},"/alem/models":{"get":{"operationId":"alem_models","tags":["ALEM"],"summary":"List the available Alem.Cloud models","description":"Returns the models currently available to the API key, in the OpenAI list format with an additional kind field (CHAT, EMBEDDINGS, RERANK, AUDIO, OCR, OTHER).","responses":{"200":{"description":"The list of models.","content":{"application/json":{"schema":{"type":"object"}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.alem.read"]}]}},"/alem/completions":{"post":{"operationId":"alem_completions","tags":["ALEM"],"summary":"Alem.Cloud /v1/completions","description":"Forwarded unchanged to Alem.Cloud /v1/completions in the OpenAI or Anthropic format; streaming responses are delivered as server-sent events. The model field is required.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"description":"The answer of the model.","content":{"application/json":{"schema":{"type":"object"}},"text/event-stream":{"schema":{"type":"string"}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.alem.read"]}]}},"/alem/audio/transcriptions":{"post":{"operationId":"alem_audio_transcriptions","tags":["ALEM"],"summary":"Alem.Cloud /v1/audio/transcriptions","description":"Forwarded unchanged to Alem.Cloud /v1/audio/transcriptions in the OpenAI or Anthropic format; streaming responses are delivered as server-sent events. The model field is required.","requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"type":"object"}}}},"responses":{"200":{"description":"The answer of the model.","content":{"application/json":{"schema":{"type":"object"}},"text/event-stream":{"schema":{"type":"string"}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.alem.read"]}]}},"/alem/messages":{"post":{"operationId":"alem_messages","tags":["ALEM"],"summary":"Alem.Cloud /v1/messages","description":"Forwarded unchanged to Alem.Cloud /v1/messages in the OpenAI or Anthropic format; streaming responses are delivered as server-sent events. The model field is required.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"description":"The answer of the model.","content":{"application/json":{"schema":{"type":"object"}},"text/event-stream":{"schema":{"type":"string"}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.alem.read"]}]}},"/alem/embeddings":{"post":{"operationId":"alem_embeddings","tags":["ALEM"],"summary":"Alem.Cloud /v1/embeddings","description":"Forwarded unchanged to Alem.Cloud /v1/embeddings in the OpenAI or Anthropic format; streaming responses are delivered as server-sent events. The model field is required.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"description":"The answer of the model.","content":{"application/json":{"schema":{"type":"object"}},"text/event-stream":{"schema":{"type":"string"}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.alem.read"]}]}},"/alem/messages/count_tokens":{"post":{"operationId":"alem_messages_count_tokens","tags":["ALEM"],"summary":"Alem.Cloud /v1/messages/count_tokens","description":"Forwarded unchanged to Alem.Cloud /v1/messages/count_tokens in the OpenAI or Anthropic format; streaming responses are delivered as server-sent events. The model field is required.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"description":"The answer of the model.","content":{"application/json":{"schema":{"type":"object"}},"text/event-stream":{"schema":{"type":"string"}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.alem.read"]}]}},"/alem/chat/completions":{"post":{"operationId":"alem_chat_completions","tags":["ALEM"],"summary":"Alem.Cloud /v1/chat/completions","description":"Forwarded unchanged to Alem.Cloud /v1/chat/completions in the OpenAI or Anthropic format; streaming responses are delivered as server-sent events. The model field is required.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"description":"The answer of the model.","content":{"application/json":{"schema":{"type":"object"}},"text/event-stream":{"schema":{"type":"string"}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.alem.read"]}]}},"/alem/rerank":{"post":{"operationId":"alem_rerank","tags":["ALEM"],"summary":"Alem.Cloud /v1/rerank","description":"Forwarded unchanged to Alem.Cloud /v1/rerank in the OpenAI or Anthropic format; streaming responses are delivered as server-sent events. The model field is required.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"description":"The answer of the model.","content":{"application/json":{"schema":{"type":"object"}},"text/event-stream":{"schema":{"type":"string"}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.alem.read"]}]}},"/alem/responses":{"post":{"operationId":"alem_responses","tags":["ALEM"],"summary":"Alem.Cloud /v1/responses","description":"Forwarded unchanged to Alem.Cloud /v1/responses in the OpenAI or Anthropic format; streaming responses are delivered as server-sent events. The model field is required.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"description":"The answer of the model.","content":{"application/json":{"schema":{"type":"object"}},"text/event-stream":{"schema":{"type":"string"}}}}},"security":[{"apiToken":[]},{"oauth2":["qairu.alem.read"]}]}}},"components":{"securitySchemes":{"apiToken":{"type":"http","scheme":"bearer","bearerFormat":"qos_...","description":"An API key issued by the university administration, sent as Authorization: Bearer qos_... or in the x-api-key header. The key gives access to the modules selected when it was issued."},"oauth2":{"type":"oauth2","description":"Sign in with QAIRU: the OAuth 2.0 authorization code flow with PKCE (S256). A student signs in on the university page and grants the requested modules; the access token then acts on behalf of that student, with the student's own rights, for read operations only. Only students may grant access.","flows":{"authorizationCode":{"authorizationUrl":"https://auth.bbx.kz/realms/qairu/protocol/openid-connect/auth","tokenUrl":"https://auth.bbx.kz/realms/qairu/protocol/openid-connect/token","refreshUrl":"https://auth.bbx.kz/realms/qairu/protocol/openid-connect/token","x-usePkce":"SHA-256","scopes":{"openid":"Sign in and receive an ID token.","profile":"The name of the student.","email":"The e-mail address of the student.","qairu.alem.read":"Read access to the Alem.Cloud: language models module on behalf of the student.","qairu.users.read":"Read access to the Users and roles module on behalf of the student.","qairu.files.read":"Read access to the Files module on behalf of the student.","qairu.learning.read":"Read access to the Learning module on behalf of the student.","qairu.academic.read":"Read access to the Academic programmes module on behalf of the student.","qairu.scheduling.read":"Read access to the Class scheduling module on behalf of the student.","qairu.skillmatch.read":"Read access to the Skill matching module on behalf of the student.","qairu.clubs.read":"Read access to the Student clubs module on behalf of the student.","qairu.projects.read":"Read access to the Projects and laboratories module on behalf of the student.","qairu.ideas.read":"Read access to the Student ideas and complaints module on behalf of the student."}}}}},"schemas":{"TeacherProfileDto":{"type":"object","properties":{"userId":{"type":"string","format":"uuid"},"degree":{"type":"string"},"position":{"type":"string"},"academicTitle":{"type":"string","description":"Учёное звание. Не путать с учёной степенью (degree).","maxLength":160,"minLength":0},"office":{"type":"string","description":"Корпус и кабинет преподавателя одной строкой.","maxLength":160,"minLength":0},"rate":{"type":"number","description":"Доля ставки преподавателя: 1.0 = полная ставка, 0.5 = полставки. НЕ оклад. Используется КРН как основа ёмкости педнагрузки (1584 × ставка × доля периода).","example":1.0,"maximum":2.0,"minimum":0.0},"bio":{"type":"string","description":"Рассказ преподавателя о себе — то, что читает студент на карточке при записи на дисциплину. Пусто = рассказа нет.","maxLength":4000,"minLength":0},"expertise":{"type":"array","description":"Области экспертизы. Хранятся строкой через запятую, наружу отдаются списком.","items":{"type":"string"}},"photoFileId":{"type":"string","format":"uuid","description":"Портрет преподавателя: id файла из POST /api/files."},"teachingLanguages":{"type":"array","description":"Языки, на которых преподаватель ведёт занятия: KZ, EN. Пустой список — языки ещё не заполнены (правило подбора в расписании такого человека пропускает, а не отклоняет).","example":["KZ","EN"],"items":{"type":"string","enum":["KZ","EN"]},"uniqueItems":true}}},"StudentProfileDto":{"type":"object","properties":{"userId":{"type":"string","format":"uuid"},"enrollmentForm":{"type":"string","enum":["GRANT","CONTRACT"]},"instructionLanguage":{"type":"string","enum":["KZ","EN"]},"courseYear":{"type":"integer","format":"int32","maximum":10,"minimum":1},"programName":{"type":"string"},"programNameKk":{"type":"string"},"programNameEn":{"type":"string"},"photoFileId":{"type":"string","format":"uuid"},"personalEmail":{"type":"string"},"about":{"type":"string"}},"required":["courseYear","enrollmentForm"]},"StaffProfileDto":{"type":"object","properties":{"userId":{"type":"string","format":"uuid"},"department":{"type":"string"},"position":{"type":"string"}}},"InterestTagDto":{"type":"object","properties":{"code":{"type":"string"},"name":{"type":"string"},"custom":{"type":"boolean"},"kind":{"type":"string","enum":["ACADEMIC","LIFE"]}}},"MyInterestsDto":{"type":"object","properties":{"selected":{"type":"array","items":{"$ref":"#/components/schemas/InterestTagDto"}},"life":{"type":"array","items":{"$ref":"#/components/schemas/InterestTagDto"}},"recommendedMin":{"type":"integer","format":"int32"},"maxTags":{"type":"integer","format":"int32"},"maxLifeTags":{"type":"integer","format":"int32"},"maxCustom":{"type":"integer","format":"int32"},"completed":{"type":"boolean"}}},"OrgDepartmentResponse":{"type":"object","properties":{"id":{"type":"integer","format":"int64"},"code":{"type":"string"},"nameRu":{"type":"string"},"nameKk":{"type":"string"},"nameEn":{"type":"string"},"type":{"type":"string","enum":["ACADEMIC","ADMINISTRATIVE"]},"parentId":{"type":"integer","format":"int64"},"headKeycloakId":{"type":"string"},"curatorKeycloakId":{"type":"string"},"sortOrder":{"type":"integer","format":"int32"},"createdAt":{"type":"string","format":"date-time"}}},"OnboardingFactDto":{"type":"object","properties":{"value":{"type":"string"},"label":{"type":"string"}}},"MentorCardDto":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"userId":{"type":"string"},"fullName":{"type":"string"},"position":{"type":"string"},"degree":{"type":"string"},"bio":{"type":"string"},"expertise":{"type":"array","items":{"type":"string"}},"contactEmail":{"type":"string"},"contactPhone":{"type":"string"},"photoFileId":{"type":"string","format":"uuid"},"capacity":{"type":"integer","format":"int32"},"taken":{"type":"integer","format":"int32"},"free":{"type":"integer","format":"int32"},"available":{"type":"boolean"},"interestTags":{"type":"array","items":{"$ref":"#/components/schemas/InterestTagDto"}},"matchedInterests":{"type":"array","items":{"$ref":"#/components/schemas/InterestTagDto"}},"matchScore":{"type":"integer","format":"int32"}}},"RepresentativeSection":{"type":"object","properties":{"fullName":{"type":"string","maxLength":255,"minLength":0},"phone":{"type":"string","maxLength":32,"minLength":0}}},"AddressesSection":{"type":"object","properties":{"residenceCountry":{"type":"string","maxLength":100,"minLength":0},"residenceRegion":{"type":"string","maxLength":150,"minLength":0},"residenceCity":{"type":"string","maxLength":150,"minLength":0},"residenceAddress":{"type":"string","maxLength":500,"minLength":0},"registrationAddress":{"type":"string","maxLength":500,"minLength":0}}},"EducationItem":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"institutionType":{"type":"string","maxLength":30,"minLength":0},"institutionName":{"type":"string","maxLength":500,"minLength":0},"region":{"type":"string","maxLength":150,"minLength":0},"city":{"type":"string","maxLength":150,"minLength":0},"instructionLanguage":{"type":"string","maxLength":10,"minLength":0},"graduationYear":{"type":"integer","format":"int32","maximum":2100,"minimum":1900},"educationLevel":{"type":"string","maxLength":30,"minLength":0},"specialtyName":{"type":"string","maxLength":500,"minLength":0},"gpa":{"type":"string","maxLength":32,"minLength":0}}},"ExamItem":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"examKind":{"type":"string","maxLength":20,"minLength":0},"testingKind":{"type":"string","maxLength":30,"minLength":0},"totalScore":{"type":"integer","format":"int32","maximum":1000,"minimum":0},"highestScore":{"type":"integer","format":"int32","maximum":1000,"minimum":0},"iktScore":{"type":"integer","format":"int32","maximum":1000,"minimum":0},"subjects":{"type":"array","items":{"type":"string","maxLength":30,"minLength":0},"maxItems":10,"minItems":0},"examYear":{"type":"integer","format":"int32","maximum":2100,"minimum":1900},"certificateNumber":{"type":"string","maxLength":100,"minLength":0},"certificateIssueDate":{"type":"string","format":"date"},"opGroupCode":{"type":"string","maxLength":20,"minLength":0},"opGroupName":{"type":"string","maxLength":255,"minLength":0},"trainingDirection":{"type":"string","maxLength":30,"minLength":0},"certificateFileId":{"type":"string","format":"uuid"},"certificateFileName":{"type":"string","maxLength":255,"minLength":0}}},"IdentitySection":{"type":"object","properties":{"documentType":{"type":"string","maxLength":20,"minLength":0},"documentNumber":{"type":"string","maxLength":50,"minLength":0},"issueDate":{"type":"string","format":"date"},"expiryDate":{"type":"string","format":"date"},"issuingAuthority":{"type":"string","maxLength":255,"minLength":0},"fileId":{"type":"string","format":"uuid"},"fileName":{"type":"string","maxLength":255,"minLength":0}}},"PersonalSection":{"type":"object","properties":{"birthDate":{"type":"string","format":"date"},"gender":{"type":"string","maxLength":10,"minLength":0},"citizenship":{"type":"string","maxLength":100,"minLength":0},"nationality":{"type":"string","maxLength":100,"minLength":0}}},"PrivilegeItem":{"type":"object","properties":{"code":{"type":"string","maxLength":50,"minLength":0},"nameRu":{"type":"string","maxLength":255,"minLength":0},"nameKk":{"type":"string","maxLength":255,"minLength":0},"nameEn":{"type":"string","maxLength":255,"minLength":0}},"required":["code"]},"StudentRecordDto":{"type":"object","properties":{"personal":{"$ref":"#/components/schemas/PersonalSection"},"identity":{"$ref":"#/components/schemas/IdentitySection"},"addresses":{"$ref":"#/components/schemas/AddressesSection"},"representative":{"$ref":"#/components/schemas/RepresentativeSection"},"education":{"type":"array","items":{"$ref":"#/components/schemas/EducationItem"}},"exams":{"type":"array","items":{"$ref":"#/components/schemas/ExamItem"}},"privileges":{"type":"array","items":{"$ref":"#/components/schemas/PrivilegeItem"}},"transferredAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}},"UserProfileDto":{"type":"object","properties":{"keycloakId":{"type":"string"},"username":{"type":"string"},"email":{"type":"string"},"firstName":{"type":"string"},"lastName":{"type":"string"},"phone":{"type":"string"},"realmRoles":{"type":"array","items":{"type":"string"}},"createdAt":{"type":"string","format":"date-time"},"isActive":{"type":"boolean"},"iin":{"type":"string"},"program":{"type":"string"},"programForCertificate":{"type":"string"},"courseYear":{"type":"integer","format":"int32"},"enrollmentForm":{"type":"string","enum":["GRANT","CONTRACT"]},"instructionLanguage":{"type":"string","enum":["KZ","EN"]},"photoFileId":{"type":"string","format":"uuid"},"personalEmail":{"type":"string"},"latinLastName":{"type":"string"},"latinFirstName":{"type":"string"},"preferredLanguage":{"type":"string"},"passwordChangedAt":{"type":"string","format":"date-time"}}},"OnboardingStateDto":{"type":"object","properties":{"completed":{"type":"boolean"},"completedAt":{"type":"string","format":"date-time"},"currentStep":{"type":"string","enum":["ABOUT","VIDEOS","INTRO","MENTOR","DIAGNOSTIC","DONE"]},"aboutCompletedAt":{"type":"string","format":"date-time"},"videosCompletedAt":{"type":"string","format":"date-time"},"mentorResolvedAt":{"type":"string","format":"date-time"},"introCompletedAt":{"type":"string","format":"date-time"},"mentorChoiceDeferred":{"type":"boolean"},"mentorAssigned":{"type":"boolean"},"viewedVideoIds":{"type":"array","items":{"type":"string","format":"uuid"}},"aboutBlockCount":{"type":"integer","format":"int32"},"videoCount":{"type":"integer","format":"int32"},"mentorCount":{"type":"integer","format":"int32"},"interestCount":{"type":"integer","format":"int32"},"status":{"type":"string","enum":["NOT_STARTED","IN_PROGRESS","COMPLETED"]},"steps":{"type":"array","items":{"$ref":"#/components/schemas/OnboardingStepStateDto"}},"nextStep":{"type":"string","enum":["ABOUT","VIDEOS","INTRO","MENTOR","DIAGNOSTIC","DONE"]},"progressPercent":{"type":"integer","format":"int32"},"stepsDone":{"type":"integer","format":"int32"},"stepsTotal":{"type":"integer","format":"int32"}}},"OnboardingStepStateDto":{"type":"object","properties":{"step":{"type":"string","enum":["ABOUT","VIDEOS","INTRO","MENTOR","DIAGNOSTIC","DONE"]},"status":{"type":"string","enum":["DONE","PENDING","SKIPPED","UNKNOWN"]},"blocking":{"type":"boolean"},"countsToProgress":{"type":"boolean"},"source":{"type":"string","enum":["USER_SERVICE","LEARNING_SERVICE"]},"checkPath":{"type":"string"},"completedAt":{"type":"string","format":"date-time"}}},"MyMentorDto":{"type":"object","properties":{"assigned":{"type":"boolean"},"deferred":{"type":"boolean"},"assignedAt":{"type":"string","format":"date-time"},"assignedBy":{"type":"string"},"mentor":{"$ref":"#/components/schemas/MentorCardDto"}}},"StudentDocumentDto":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"category":{"type":"string"},"typeCode":{"type":"string"},"titleRu":{"type":"string"},"titleKk":{"type":"string"},"titleEn":{"type":"string"},"privilegeCode":{"type":"string"},"fileId":{"type":"string","format":"uuid"},"fileName":{"type":"string"},"receivedAt":{"type":"string","format":"date-time"},"source":{"type":"string"},"createdAt":{"type":"string","format":"date-time"}}},"ListPaginationUserDto":{"type":"object","properties":{"content":{"type":"array","items":{"$ref":"#/components/schemas/UserDto"}},"page":{"type":"integer","format":"int32"},"size":{"type":"integer","format":"int32"},"totalElements":{"type":"integer","format":"int64"},"totalPages":{"type":"integer","format":"int32"}}},"UserDto":{"type":"object","properties":{"username":{"type":"string"},"roles":{"type":"array","items":{"type":"string"}}}},"TeacherPublicCardDto":{"type":"object","properties":{"keycloakId":{"type":"string"},"fullName":{"type":"string","description":"Имя и фамилия. Совпадает с подписью преподавателя в каталоге расписания."},"position":{"type":"string"},"degree":{"type":"string"},"bio":{"type":"string"},"expertise":{"type":"array","items":{"type":"string"}},"photoFileId":{"type":"string","format":"uuid","description":"Портрет: id файла, забирается через прокси кабинета (файловая служба отдаёт его студентам по выданному праву)."}}},"OrgDepartmentTreeResponse":{"type":"object","properties":{"id":{"type":"integer","format":"int64"},"code":{"type":"string"},"nameRu":{"type":"string"},"nameKk":{"type":"string"},"nameEn":{"type":"string"},"type":{"type":"string","enum":["ACADEMIC","ADMINISTRATIVE"]},"headKeycloakId":{"type":"string"},"curatorKeycloakId":{"type":"string"},"sortOrder":{"type":"integer","format":"int32"}}},"OnboardingBlockDto":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"code":{"type":"string"},"orderIndex":{"type":"integer","format":"int32"},"eyebrow":{"type":"string"},"title":{"type":"string"},"body":{"type":"string"},"facts":{"type":"array","items":{"$ref":"#/components/schemas/OnboardingFactDto"}},"points":{"type":"array","items":{"type":"string"}},"chips":{"type":"array","items":{"type":"string"}},"imageFileId":{"type":"string","format":"uuid"},"scene":{"type":"string","enum":["LICENSE","CAMPUS","AI","STUDY","PARTNERS","SCIENCE"]}}},"OnboardingContentDto":{"type":"object","properties":{"locale":{"type":"string"},"blocks":{"type":"array","items":{"$ref":"#/components/schemas/OnboardingBlockDto"}},"videos":{"type":"array","items":{"$ref":"#/components/schemas/OnboardingVideoDto"}}}},"OnboardingVideoDto":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"orderIndex":{"type":"integer","format":"int32"},"audience":{"type":"string","enum":["STUDENT","TEACHER"]},"personName":{"type":"string"},"personPosition":{"type":"string"},"topic":{"type":"string"},"videoFileId":{"type":"string","format":"uuid"},"posterFileId":{"type":"string","format":"uuid"},"durationSeconds":{"type":"integer","format":"int32"},"viewed":{"type":"boolean"}}},"MentorListDto":{"type":"object","properties":{"mentors":{"type":"array","items":{"$ref":"#/components/schemas/MentorCardDto"}},"myMentorId":{"type":"string","format":"uuid"},"deferred":{"type":"boolean"},"anySlotsAvailable":{"type":"boolean"},"sort":{"type":"string"},"myInterests":{"type":"array","items":{"type":"string"}},"filteredByInterests":{"type":"boolean"},"hiddenByFilter":{"type":"integer","format":"int32"}}},"MenteeDto":{"type":"object","properties":{"studentUserId":{"type":"string"},"fullName":{"type":"string"},"email":{"type":"string"},"programName":{"type":"string"},"courseYear":{"type":"integer","format":"int32"},"photoFileId":{"type":"string","format":"uuid"},"assignedAt":{"type":"string","format":"date-time"}}},"MyMenteesDto":{"type":"object","properties":{"isMentor":{"type":"boolean"},"capacity":{"type":"integer","format":"int32"},"taken":{"type":"integer","format":"int32"},"mentees":{"type":"array","items":{"$ref":"#/components/schemas/MenteeDto"}}}},"DirectoryEntryDto":{"type":"object","properties":{"keycloakId":{"type":"string"},"fullName":{"type":"string"},"active":{"type":"boolean"}}},"FileRecordDto":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"originalFilename":{"type":"string"},"mimeType":{"type":"string"},"fileSizeBytes":{"type":"integer","format":"int64"},"uploadedByUsername":{"type":"string"},"downloadUrl":{"type":"string"},"createdAt":{"type":"string","format":"date-time"},"available":{"type":"boolean"},"expiresAt":{"type":"string","format":"date-time"},"purgedAt":{"type":"string","format":"date-time"}}},"StreamingResponseBody":{},"SubmissionDto":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"assignmentId":{"type":"string","format":"uuid"},"learnerId":{"type":"string","format":"uuid"},"version":{"type":"integer","format":"int32"},"status":{"type":"string","enum":["SUBMITTED","RETURNED","GRADED","WITHDRAWN"]},"late":{"type":"boolean"},"submittedAt":{"type":"string","format":"date-time"},"s3FileId":{"type":"string","format":"uuid"},"textBody":{"type":"string"},"linkUrl":{"type":"string"},"returnComment":{"type":"string"},"grade":{"$ref":"#/components/schemas/SubmissionGradeDto"},"teacherEntered":{"type":"boolean"},"files":{"type":"array","items":{"$ref":"#/components/schemas/SubmissionFileDto"}},"lastModifiedAt":{"type":"string","format":"date-time"},"canEdit":{"type":"boolean"},"canWithdraw":{"type":"boolean"},"lateBySeconds":{"type":"integer","format":"int64"},"effectiveDeadline":{"type":"string","format":"date-time"},"modifiedAfterGradeAt":{"type":"string","format":"date-time"}}},"SubmissionFileDto":{"type":"object","properties":{"s3FileId":{"type":"string"},"originalFilename":{"type":"string"},"mimeType":{"type":"string"},"sizeBytes":{"type":"integer","format":"int64"},"orderIndex":{"type":"integer","format":"int32"}}},"SubmissionGradeDto":{"type":"object","properties":{"totalScore":{"type":"integer","format":"int32"},"maxScore":{"type":"integer","format":"int32"},"feedback":{"type":"string"}}},"SourceGuideDto":{"type":"object","properties":{"state":{"type":"string"},"summary":{"type":"string"},"topics":{"type":"array","items":{"type":"string"}},"locale":{"type":"string"}}},"StudySourceDto":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"spaceId":{"type":"string","format":"uuid"},"title":{"type":"string"},"kind":{"type":"string","enum":["FILE","TEXT","LINK","RECORDING","BOOK"]},"displayKind":{"type":"string"},"materialId":{"type":"string","format":"uuid"},"url":{"type":"string"},"s3FileId":{"type":"string","format":"uuid"},"selected":{"type":"boolean"},"readyForAi":{"type":"boolean"},"extractStatus":{"type":"string","enum":["PENDING","EXTRACTING","INDEXED","FAILED"]},"failReason":{"type":"string"},"failReasonCode":{"type":"string"},"transcriptUnavailableReason":{"type":"string"},"pageCount":{"type":"integer","format":"int32"},"textLength":{"type":"integer","format":"int32"},"guide":{"$ref":"#/components/schemas/SourceGuideDto"},"autoKitState":{"type":"string"},"createdAt":{"type":"string","format":"date-time"},"sizeBytes":{"type":"integer","format":"int64"},"updatedAt":{"type":"string","format":"date-time"}}},"Contribution":{"type":"object","properties":{"contributionId":{"type":"string","format":"uuid"},"title":{"type":"string"},"confirmedAt":{"type":"string","format":"date-time"},"confirmedByName":{"type":"string"},"revoked":{"type":"boolean"},"resumeVisible":{"type":"boolean"}}},"MyResumeProjectDto":{"type":"object","properties":{"projectId":{"type":"string","format":"uuid"},"title":{"type":"string"},"status":{"type":"string"},"projectKind":{"type":"string"},"roleCode":{"type":"string"},"roleNameRu":{"type":"string"},"roleNameKk":{"type":"string"},"roleNameEn":{"type":"string"},"teamSize":{"type":"integer","format":"int32"},"description":{"type":"string"},"stack":{"type":"array","items":{"$ref":"#/components/schemas/SkillName"}},"contributions":{"type":"array","items":{"$ref":"#/components/schemas/Contribution"}},"resumeVisible":{"type":"boolean"},"startedOn":{"type":"string","format":"date"},"finishedOn":{"type":"string","format":"date"},"link":{"type":"string"}}},"SkillName":{"type":"object","properties":{"code":{"type":"string"},"nameRu":{"type":"string"},"nameKk":{"type":"string"},"nameEn":{"type":"string"}}},"CertificateSkillDto":{"type":"object","properties":{"skillId":{"type":"string","format":"uuid"},"code":{"type":"string"},"nameRu":{"type":"string"},"nameKk":{"type":"string"},"nameEn":{"type":"string"},"accepted":{"type":"boolean"}}},"MyCertificateDto":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"title":{"type":"string"},"issuer":{"type":"string"},"issuedOn":{"type":"string","format":"date"},"credentialUrl":{"type":"string"},"fileId":{"type":"string","format":"uuid"},"fileName":{"type":"string"},"status":{"type":"string"},"rejectReason":{"type":"string"},"skills":{"type":"array","items":{"$ref":"#/components/schemas/CertificateSkillDto"}},"submittedAt":{"type":"string","format":"date-time"},"reviewedAt":{"type":"string","format":"date-time"}}},"LocalizedTextDto":{"type":"object","properties":{"ru":{"type":"string"},"kk":{"type":"string"},"en":{"type":"string"}}},"ResumeBadgeOptionDto":{"type":"object","properties":{"code":{"type":"string"},"name":{"$ref":"#/components/schemas/LocalizedTextDto"},"fact":{"$ref":"#/components/schemas/LocalizedTextDto"},"selected":{"type":"boolean"}}},"ResumeBadgesDto":{"type":"object","properties":{"enabled":{"type":"boolean"},"options":{"type":"array","items":{"$ref":"#/components/schemas/ResumeBadgeOptionDto"}}}},"ResumeAchievementDto":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"kind":{"type":"string","enum":["PROJECT","RESEARCH","CERTIFICATE","OTHER"]},"title":{"type":"string"},"role":{"type":"string"},"startedOn":{"type":"string","format":"date"},"achievedOn":{"type":"string","format":"date"},"description":{"type":"string"},"link":{"type":"string"},"files":{"type":"array","items":{"$ref":"#/components/schemas/ResumeAchievementFileDto"}},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}},"ResumeAchievementFileDto":{"type":"object","properties":{"fileId":{"type":"string","format":"uuid"},"fileName":{"type":"string"}}},"ResumeAboutDto":{"type":"object","properties":{"searchStatus":{"type":"string"},"about":{"type":"string"},"contacts":{"type":"string"}}},"Alternative":{"type":"object","properties":{"code":{"type":"string"},"titleRu":{"type":"string"},"titleKk":{"type":"string"},"titleEn":{"type":"string"},"credits":{"type":"integer","format":"int32"}}},"Choice":{"type":"object","properties":{"open":{"type":"boolean"},"state":{"type":"string"},"closesAt":{"type":"string","format":"date-time"},"opensAt":{"type":"string","format":"date-time"},"serverTime":{"type":"string","format":"date-time"},"zone":{"type":"string"}}},"Credits":{"type":"object","properties":{"planned":{"type":"integer","format":"int32"},"earned":{"type":"integer","format":"int32"},"inProgress":{"type":"integer","format":"int32"},"debt":{"type":"integer","format":"int32"}}},"Debt":{"type":"object","properties":{"code":{"type":"string"},"titleRu":{"type":"string"},"titleKk":{"type":"string"},"titleEn":{"type":"string"},"academicYear":{"type":"string"},"termNo":{"type":"integer","format":"int32"},"credits":{"type":"integer","format":"int32"},"gradeLetter":{"type":"string"}}},"DisciplineRef":{"type":"object","properties":{"code":{"type":"string"},"titleRu":{"type":"string"},"titleKk":{"type":"string"},"titleEn":{"type":"string"}}},"Header":{"type":"object","properties":{"learnerId":{"type":"string","format":"uuid"},"studentKeycloakId":{"type":"string"},"fullName":{"type":"string"},"programCode":{"type":"string"},"programTitle":{"type":"string"},"programTitleKk":{"type":"string"},"programTitleEn":{"type":"string"},"studyLevel":{"type":"string"},"instructionLanguage":{"type":"string"},"admissionYear":{"type":"integer","format":"int32"},"admissionYearSource":{"type":"string"},"academicYear":{"type":"string"},"studyYear":{"type":"integer","format":"int32"},"editionYear":{"type":"string"}}},"HistoryEntry":{"type":"object","properties":{"at":{"type":"string","format":"date-time"},"action":{"type":"string"},"fromTitleRu":{"type":"string"},"fromTitleKk":{"type":"string"},"fromTitleEn":{"type":"string"},"toTitleRu":{"type":"string"},"toTitleKk":{"type":"string"},"toTitleEn":{"type":"string"},"actorName":{"type":"string"},"actorRole":{"type":"string"},"reason":{"type":"string"}}},"Selection":{"type":"object","properties":{"trajectoryId":{"type":"string","format":"uuid"},"titleRu":{"type":"string"},"titleKk":{"type":"string"},"titleEn":{"type":"string"},"chosenAt":{"type":"string","format":"date-time"},"chosenByRole":{"type":"string"},"lockAt":{"type":"string","format":"date-time"},"effectiveFromTerm":{"type":"integer","format":"int32"},"locked":{"type":"boolean"},"unavailable":{"type":"boolean"},"version":{"type":"integer","format":"int64"}}},"StudyPlanDto":{"type":"object","properties":{"header":{"$ref":"#/components/schemas/Header"},"availableYears":{"type":"array","items":{"type":"string"}},"mode":{"type":"string"},"choice":{"$ref":"#/components/schemas/Choice"},"selection":{"$ref":"#/components/schemas/Selection"},"terms":{"type":"array","items":{"$ref":"#/components/schemas/Term"}},"totals":{"$ref":"#/components/schemas/Credits"},"previousDebts":{"type":"array","items":{"$ref":"#/components/schemas/Debt"}},"history":{"type":"array","items":{"$ref":"#/components/schemas/HistoryEntry"}},"generatedAt":{"type":"string","format":"date-time"}}},"StudyPlanRowDto":{"type":"object","properties":{"rowKey":{"type":"string"},"programDisciplineId":{"type":"string","format":"uuid"},"courseId":{"type":"string","format":"uuid"},"code":{"type":"string"},"titleRu":{"type":"string"},"titleKk":{"type":"string"},"titleEn":{"type":"string"},"category":{"type":"string"},"credits":{"type":"integer","format":"int32"},"partNo":{"type":"integer","format":"int32"},"partsTotal":{"type":"integer","format":"int32"},"groupCode":{"type":"string"},"groupTitleRu":{"type":"string"},"groupTitleKk":{"type":"string"},"groupTitleEn":{"type":"string"},"status":{"type":"string"},"retake":{"type":"boolean"},"restudy":{"type":"boolean"},"gradeLetter":{"type":"string"},"source":{"type":"string"},"prerequisiteCourse":{"type":"boolean"},"electiveSlot":{"type":"boolean"},"alternatives":{"type":"array","items":{"$ref":"#/components/schemas/Alternative"}},"missingPrerequisites":{"type":"array","items":{"$ref":"#/components/schemas/DisciplineRef"}}}},"Term":{"type":"object","properties":{"termNo":{"type":"integer","format":"int32"},"startDate":{"type":"string","format":"date"},"endDate":{"type":"string","format":"date"},"fact":{"type":"boolean"},"credits":{"$ref":"#/components/schemas/Credits"},"rows":{"type":"array","items":{"$ref":"#/components/schemas/StudyPlanRowDto"}}}},"SemesterReflectionDto":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"academicYear":{"type":"string"},"termNo":{"type":"integer","format":"int32"},"whatWorked":{"type":"string"},"whatWasHard":{"type":"string"},"nextGoals":{"type":"string"},"satisfactionRating":{"type":"integer","format":"int32"},"workloadRating":{"type":"integer","format":"int32"},"updatedAt":{"type":"string","format":"date-time"}}},"ShowcaseDto":{"type":"object","properties":{"visible":{"type":"boolean"},"codes":{"type":"array","items":{"type":"string"}}}},"LessonFeedbackDto":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"courseId":{"type":"string","format":"uuid"},"courseCode":{"type":"string"},"courseTitle":{"type":"string"},"lessonDate":{"type":"string","format":"date"},"classNumber":{"type":"integer","format":"int32"},"rating":{"type":"integer","format":"int32"},"tags":{"type":"array","items":{"type":"string"}},"comment":{"type":"string"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"},"editable":{"type":"boolean"}}},"AcademicTermDto":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"academicYear":{"type":"string"},"termNo":{"type":"integer","format":"int32"},"programCode":{"type":"string"},"studyLevel":{"type":"string"},"startDate":{"type":"string","format":"date"},"endDate":{"type":"string","format":"date"},"classesStartDate":{"type":"string","format":"date"},"classesEndDate":{"type":"string","format":"date"},"weeks":{"type":"integer","format":"int32"},"holidays":{"type":"array","items":{"$ref":"#/components/schemas/HolidayPeriodDto"}},"enrollmentWindowStart":{"type":"string","format":"date-time"},"enrollmentWindowEnd":{"type":"string","format":"date-time"},"addDropWindowStart":{"type":"string","format":"date-time"},"addDropWindowEnd":{"type":"string","format":"date-time"},"examWindowStart":{"type":"string","format":"date"},"examWindowEnd":{"type":"string","format":"date"},"retakeWindowStart":{"type":"string","format":"date"},"retakeWindowEnd":{"type":"string","format":"date"},"status":{"type":"string"},"closedAt":{"type":"string","format":"date-time"},"closedBy":{"type":"string"},"closureNote":{"type":"string"},"reopenedAt":{"type":"string","format":"date-time"},"reopenReason":{"type":"string"}}},"HolidayPeriodDto":{"type":"object","properties":{"startDate":{"type":"string","format":"date"},"endDate":{"type":"string","format":"date"}}},"MaterialDetailDto":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"moduleId":{"type":"string","format":"uuid"},"orderIndex":{"type":"integer","format":"int32"},"courseId":{"type":"string","format":"uuid"},"type":{"type":"string","enum":["FILE","VIDEO","LECTURE","LINK","ANNOUNCEMENT"]},"title":{"type":"string"},"mimeType":{"type":"string"},"contentHtml":{"type":"string"},"contentDoc":{"type":"string"},"contentFormat":{"type":"string","enum":["HTML","DOC"]},"externalUrl":{"type":"string"},"publishedAt":{"type":"string","format":"date-time"},"announcedAt":{"type":"string","format":"date-time"},"durationSec":{"type":"integer","format":"int32"},"pageCount":{"type":"integer","format":"int32"},"availableFrom":{"type":"string","format":"date-time"},"availableUntil":{"type":"string","format":"date-time"},"visibleToStudents":{"type":"boolean"},"status":{"type":"string","enum":["DRAFT","PUBLISHED"]},"indexedForAi":{"type":"boolean"},"indexState":{"type":"string","enum":["NOT_APPLICABLE","NOT_INDEXED","INDEXING","INDEXED","FAILED"]},"indexFailCode":{"type":"string"},"kitState":{"type":"string","enum":["NOT_APPLICABLE","PENDING","RUNNING","READY","FAILED"]},"kitStartedAt":{"type":"string","format":"date-time"},"createdAt":{"type":"string","format":"date-time"},"s3FileId":{"type":"string","format":"uuid"},"files":{"type":"array","items":{"$ref":"#/components/schemas/MaterialFileDto"}},"videoPreview":{"$ref":"#/components/schemas/VideoPreviewDto"},"hasBody":{"type":"boolean"},"rendersInline":{"type":"boolean"},"generatedByAi":{"type":"boolean"},"sourceCitations":{"type":"array","items":{"type":"string"}}}},"MaterialFileDto":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"s3FileId":{"type":"string","format":"uuid"},"mimeType":{"type":"string"},"fileName":{"type":"string"},"durationSec":{"type":"integer","format":"int32"},"pageCount":{"type":"integer","format":"int32"},"orderIndex":{"type":"integer","format":"int32"}}},"VideoPreviewDto":{"type":"object","properties":{"intervalSec":{"type":"integer","format":"int32"},"tileWidth":{"type":"integer","format":"int32"},"tileHeight":{"type":"integer","format":"int32"},"cols":{"type":"integer","format":"int32"},"count":{"type":"integer","format":"int32"}}},"TrajectoryDto":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"programCode":{"type":"string"},"academicYear":{"type":"string"},"studyYear":{"type":"integer","format":"int32"},"editionYear":{"type":"string"},"titleRu":{"type":"string"},"titleKk":{"type":"string"},"titleEn":{"type":"string"},"descriptionRu":{"type":"string"},"descriptionKk":{"type":"string"},"descriptionEn":{"type":"string"},"status":{"type":"string"},"sortOrder":{"type":"integer","format":"int32"},"version":{"type":"integer","format":"int64"},"choices":{"type":"array","items":{"$ref":"#/components/schemas/Choice"}},"missingGroups":{"type":"array","items":{"type":"string"}},"studentsCount":{"type":"integer","format":"int64"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"},"publishedAt":{"type":"string","format":"date-time"}}},"GradeBandDto":{"type":"object","properties":{"minPct":{"type":"integer","format":"int32"},"maxPct":{"type":"integer","format":"int32"},"letter":{"type":"string"},"gpa":{"type":"number"},"passing":{"type":"boolean"}}},"Completion":{"type":"object","properties":{"completed":{"type":"boolean"},"completedAt":{"type":"string","format":"date-time"},"canLeave":{"type":"boolean"},"certificateId":{"type":"string","format":"uuid"},"enrollmentOrigin":{"type":"string"}}},"CourseDto":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"programId":{"type":"string","format":"uuid"},"code":{"type":"string"},"title":{"type":"string"},"titleKk":{"type":"string"},"titleEn":{"type":"string"},"description":{"type":"string"},"credits":{"type":"integer","format":"int32"},"trimester":{"type":"integer","format":"int32"},"academicYear":{"type":"string"},"type":{"type":"string","enum":["MANDATORY","ELECTIVE","PRACTICE","THESIS"]},"component":{"type":"string","enum":["OK","VK","KV"]},"language":{"type":"string"},"format":{"type":"string"},"teacherUserId":{"type":"string"},"teacherName":{"type":"string"},"status":{"type":"string","enum":["OPEN","CLOSED","ARCHIVED"]},"statusLabelRu":{"type":"string"},"statusLabelKk":{"type":"string"},"statusLabelEn":{"type":"string"},"gradingFinalized":{"type":"boolean"},"assistant":{"type":"boolean"},"superseded":{"type":"boolean"},"withdrawnAt":{"type":"string","format":"date-time"},"closedAt":{"type":"string","format":"date-time"},"frozenAt":{"type":"string","format":"date-time"},"rolledOverFromCourseId":{"type":"string","format":"uuid"},"rolledOverToCourseId":{"type":"string","format":"uuid"},"completedElements":{"type":"integer","format":"int32"},"totalElements":{"type":"integer","format":"int32"},"completionPct":{"type":"number","format":"double"},"streamId":{"type":"string","format":"uuid"},"streamNo":{"type":"integer","format":"int32"},"programCodes":{"type":"array","items":{"type":"string"}},"programTitles":{"type":"array","items":{"$ref":"#/components/schemas/ProgramTitle"}},"enrolledActiveCount":{"type":"integer","format":"int32"},"mainTeacherName":{"type":"string"},"assistantNames":{"type":"array","items":{"type":"string"}},"admissionThresholdPct":{"type":"integer","format":"int32"},"attendanceThresholdPct":{"type":"integer","format":"int32"},"syllabusFilled":{"type":"boolean"},"kind":{"type":"string","enum":["DISCIPLINE","PREREQUISITE","OPEN"]},"selfEnrollment":{"type":"boolean"},"completionMode":{"type":"string","enum":["GRADED","UNGRADED"]},"certificateEnabled":{"type":"boolean"},"startsOn":{"type":"string","format":"date"},"endsOn":{"type":"string","format":"date"},"contentOpensOn":{"type":"string","format":"date"},"skills":{"type":"array","items":{"$ref":"#/components/schemas/SkillRef"}},"completion":{"$ref":"#/components/schemas/Completion"}}},"ProgramTitle":{"type":"object","properties":{"code":{"type":"string"},"title":{"type":"string"},"titleKk":{"type":"string"},"titleEn":{"type":"string"}}},"SkillRef":{"type":"object","properties":{"skillId":{"type":"string","format":"uuid"},"code":{"type":"string"},"nameRu":{"type":"string"},"nameKk":{"type":"string"},"nameEn":{"type":"string"}}},"CourseSkillDto":{"type":"object","properties":{"skillId":{"type":"string","format":"uuid"},"code":{"type":"string"},"nameRu":{"type":"string"},"nameKk":{"type":"string"},"nameEn":{"type":"string"}}},"ModuleDto":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"title":{"type":"string"},"orderIndex":{"type":"integer","format":"int32"},"startDate":{"type":"string","format":"date"},"weekNo":{"type":"integer","format":"int32"},"isDefault":{"type":"boolean"},"isGeneral":{"type":"boolean"}}},"AssignmentAttachmentDto":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"assignmentId":{"type":"string","format":"uuid"},"type":{"type":"string","enum":["FILE","VIDEO","LECTURE","LINK","ANNOUNCEMENT"]},"title":{"type":"string"},"mimeType":{"type":"string"},"orderIndex":{"type":"integer","format":"int32"},"contentHtml":{"type":"string"},"s3FileId":{"type":"string","format":"uuid"},"createdAt":{"type":"string","format":"date-time"},"contentDoc":{"type":"string"},"contentFormat":{"type":"string","enum":["HTML","DOC"]}}},"NotebookSummaryDto":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"title":{"type":"string"},"sourceCount":{"type":"integer","format":"int64"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"},"sourceKinds":{"type":"array","items":{"type":"string"}}}},"StudyArtifactDto":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"type":{"type":"string","enum":["CHAT","FLASHCARDS","QUIZ","PODCAST","SUMMARY","MINDMAP","TIMELINE","TRANSCRIPT","NOTES","GLOSSARY"]},"reportKind":{"type":"string"},"title":{"type":"string"},"status":{"type":"string","enum":["GENERATING","READY","FAILED"]},"failCode":{"type":"string"},"language":{"type":"string"},"legacy":{"type":"boolean"},"sourceId":{"type":"string","format":"uuid"},"createdAt":{"type":"string","format":"date-time"},"completedAt":{"type":"string","format":"date-time"},"payload":{},"sourceIds":{"type":"array","items":{"type":"string","format":"uuid"}},"customPrompt":{"type":"string"}}},"NoteDto":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"title":{"type":"string"},"body":{"type":"string"},"origin":{"type":"string","enum":["MANUAL","CHAT"]},"citations":{},"sourceMessageId":{"type":"string","format":"uuid"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}},"ResumeShareStateDto":{"type":"object","properties":{"enabled":{"type":"boolean"},"token":{"type":"string"}}},"MatchOptionDto":{"type":"object","properties":{"index":{"type":"integer","format":"int32"},"text":{"type":"string"},"doc":{"type":"string"}}},"QuizQuestionDto":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"type":{"type":"string","enum":["SINGLE_CHOICE","MULTI_CHOICE","TRUE_FALSE","SHORT_ANSWER","NUMERIC","MATCHING","GAP_FILL","ESSAY"]},"text":{"type":"string"},"options":{"type":"array","items":{"type":"string"}},"points":{"type":"integer","format":"int32"},"matchingLeft":{"type":"array","items":{"type":"string"}},"matchingRight":{"type":"array","items":{"$ref":"#/components/schemas/MatchOptionDto"}},"gapCount":{"type":"integer","format":"int32"},"textDoc":{"type":"string"},"optionDocs":{"type":"array","items":{"type":"string"}},"matchingLeftDocs":{"type":"array","items":{"type":"string"}}}},"QuestionReviewDto":{"type":"object","properties":{"questionId":{"type":"string","format":"uuid"},"type":{"type":"string","enum":["SINGLE_CHOICE","MULTI_CHOICE","TRUE_FALSE","SHORT_ANSWER","NUMERIC","MATCHING","GAP_FILL","ESSAY"]},"questionText":{"type":"string"},"correct":{"type":"boolean"},"awaitingReview":{"type":"boolean"},"earnedPoints":{"type":"number"},"maxPoints":{"type":"integer","format":"int32"},"yourAnswer":{"type":"string"},"correctAnswer":{"type":"string"},"explanation":{"type":"string"},"sourceCitation":{"type":"string"},"teacherComment":{"type":"string"},"questionDoc":{"type":"string"},"explanationDoc":{"type":"string"},"yourAnswerPicks":{"type":"array","items":{"$ref":"#/components/schemas/ReviewPickDto"}},"correctAnswerPicks":{"type":"array","items":{"$ref":"#/components/schemas/ReviewPickDto"}}}},"QuizAttemptDto":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"quizId":{"type":"string","format":"uuid"},"status":{"type":"string","enum":["IN_PROGRESS","COMPLETED","AWAITING_REVIEW","REVIEWED"]},"scorePct":{"type":"number","format":"double"},"earnedPoints":{"type":"number"},"maxPoints":{"type":"number"},"correctCount":{"type":"integer","format":"int32"},"totalCount":{"type":"integer","format":"int32"},"awaitingReviewCount":{"type":"integer","format":"int32"},"attemptedAt":{"type":"string","format":"date-time"},"reviewedAt":{"type":"string","format":"date-time"},"closedByTimer":{"type":"boolean"},"closedByTeacher":{"type":"boolean"},"review":{"type":"array","items":{"$ref":"#/components/schemas/QuestionReviewDto"}}}},"ReviewPickDto":{"type":"object","properties":{"text":{"type":"string"},"doc":{"type":"string"},"matchedText":{"type":"string"},"matchedDoc":{"type":"string"}}},"PlacementAttemptStateDto":{"type":"object","properties":{"attemptId":{"type":"string","format":"uuid"},"directionId":{"type":"string","format":"uuid"},"directionCode":{"type":"string"},"directionName":{"type":"string"},"kind":{"type":"string","enum":["SCORED","SURVEY"]},"status":{"type":"string","enum":["IN_PROGRESS","COMPLETED"]},"askedCount":{"type":"integer","format":"int32"},"totalQuestions":{"type":"integer","format":"int32"},"question":{"$ref":"#/components/schemas/PlacementQuestionViewDto"},"result":{"$ref":"#/components/schemas/PlacementResultDto"}}},"PlacementQuestionViewDto":{"type":"object","properties":{"questionId":{"type":"string","format":"uuid"},"type":{"type":"string","enum":["SINGLE_CHOICE","MULTI_CHOICE","TRUE_FALSE","SHORT_ANSWER","NUMERIC","MATCHING","GAP_FILL","ESSAY"]},"text":{"type":"string"},"options":{"type":"array","items":{"type":"string"}},"difficulty":{"type":"integer","format":"int32"},"position":{"type":"integer","format":"int32"},"total":{"type":"integer","format":"int32"}}},"PlacementResultDto":{"type":"object","properties":{"directionId":{"type":"string","format":"uuid"},"directionCode":{"type":"string"},"directionName":{"type":"string"},"kind":{"type":"string","enum":["SCORED","SURVEY"]},"level":{"type":"integer","format":"int32"},"sharePct":{"type":"integer","format":"int32"},"askedCount":{"type":"integer","format":"int32"},"correctCount":{"type":"integer","format":"int32"},"achievedAt":{"type":"string","format":"date-time"},"attemptId":{"type":"string","format":"uuid"},"advice":{"type":"string"},"weak":{"type":"boolean"}}},"MyAttendanceAppealDto":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"courseId":{"type":"string","format":"uuid"},"courseCode":{"type":"string"},"courseTitle":{"type":"string"},"sectionId":{"type":"string","format":"uuid"},"lessonDate":{"type":"string","format":"date"},"kind":{"type":"string","enum":["MARK_ERROR","EXCUSED_REASON"]},"status":{"type":"string","enum":["PENDING","ACCEPTED","REJECTED","WITHDRAWN","CLOSED_UNRESOLVED"]},"message":{"type":"string"},"fileId":{"type":"string","format":"uuid"},"fileName":{"type":"string"},"statusAtSubmission":{"type":"string","enum":["PRESENT","ABSENT","LATE","EXCUSED"]},"resolvedStatus":{"type":"string","enum":["PRESENT","ABSENT","LATE","EXCUSED"]},"decisionComment":{"type":"string"},"decidedAt":{"type":"string","format":"date-time"},"createdAt":{"type":"string","format":"date-time"}}},"ElectiveAlternative":{"type":"object","properties":{"programDisciplineId":{"type":"string","format":"uuid"},"code":{"type":"string"},"titleRu":{"type":"string"},"titleKk":{"type":"string"},"titleEn":{"type":"string"},"credits":{"type":"integer","format":"int32"}}},"RecreditRef":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"previousDisciplineTitle":{"type":"string"},"previousCredits":{"type":"number"},"previousGrade":{"type":"string"},"basis":{"type":"string"},"decisionNumber":{"type":"string"},"decisionDate":{"type":"string","format":"date"},"academicYear":{"type":"string"},"termNo":{"type":"integer","format":"int32"},"confirmedAt":{"type":"string","format":"date-time"}}},"TranscriptRowDto":{"type":"object","properties":{"rowKey":{"type":"string"},"programDisciplineId":{"type":"string","format":"uuid"},"courseId":{"type":"string","format":"uuid"},"code":{"type":"string"},"titleRu":{"type":"string"},"titleKk":{"type":"string"},"titleEn":{"type":"string"},"category":{"type":"string"},"credits":{"type":"integer","format":"int32"},"planCredits":{"type":"integer","format":"int32"},"totalPct":{"type":"number"},"letterGrade":{"type":"string"},"gpaValue":{"type":"number"},"status":{"type":"string","enum":["PLANNED","IN_PROGRESS","PASSED","RECREDITED","ACADEMIC_DEBT","RETAKE","RESTUDY"]},"prerequisite":{"type":"boolean"},"replaced":{"type":"boolean"},"restudied":{"type":"boolean"},"outOfPlan":{"type":"boolean"},"notAdmitted":{"type":"boolean"},"countsInGpa":{"type":"boolean"},"electiveSlot":{"type":"boolean"},"electiveGroupCode":{"type":"string"},"electiveGroupTitleRu":{"type":"string"},"electiveGroupTitleKk":{"type":"string"},"electiveGroupTitleEn":{"type":"string"},"alternatives":{"type":"array","items":{"$ref":"#/components/schemas/ElectiveAlternative"}},"partNo":{"type":"integer","format":"int32"},"partsTotal":{"type":"integer","format":"int32"},"recredit":{"$ref":"#/components/schemas/RecreditRef"}}},"DescriptionPreviewDto":{"type":"object","properties":{"doc":{"type":"string"},"html":{"type":"string"},"markdown":{"type":"string"}}},"LockReasonDto":{"type":"object","properties":{"code":{"type":"string"},"params":{"type":"object","additionalProperties":{"type":"string"}}}},"MaterialDto":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"moduleId":{"type":"string","format":"uuid"},"orderIndex":{"type":"integer","format":"int32"},"type":{"type":"string","enum":["FILE","VIDEO","LECTURE","LINK","ANNOUNCEMENT"]},"title":{"type":"string"},"mimeType":{"type":"string"},"fileCount":{"type":"integer","format":"int32"},"externalUrl":{"type":"string"},"contentHtml":{"type":"string"},"contentDoc":{"type":"string"},"contentFormat":{"type":"string","enum":["HTML","DOC"]},"rendersInline":{"type":"boolean"},"hasBody":{"type":"boolean"},"showNoteInCourse":{"type":"boolean"},"notePreview":{"$ref":"#/components/schemas/DescriptionPreviewDto"},"authorName":{"type":"string"},"publishedAt":{"type":"string","format":"date-time"},"announcedAt":{"type":"string","format":"date-time"},"durationSec":{"type":"integer","format":"int32"},"pageCount":{"type":"integer","format":"int32"},"availableFrom":{"type":"string","format":"date-time"},"availableUntil":{"type":"string","format":"date-time"},"visibleToStudents":{"type":"boolean"},"status":{"type":"string","enum":["DRAFT","PUBLISHED"]},"indexedForAi":{"type":"boolean"},"indexState":{"type":"string","enum":["NOT_APPLICABLE","NOT_INDEXED","INDEXING","INDEXED","FAILED"]},"indexFailCode":{"type":"string"},"kitState":{"type":"string","enum":["NOT_APPLICABLE","PENDING","RUNNING","READY","FAILED"]},"kitStartedAt":{"type":"string","format":"date-time"},"kitArtifactCount":{"type":"integer","format":"int32"},"kitPendingCount":{"type":"integer","format":"int32"},"kitReleasedCount":{"type":"integer","format":"int32"},"generatedByAi":{"type":"boolean"},"sourceCitations":{"type":"array","items":{"type":"string"}},"createdAt":{"type":"string","format":"date-time"},"lockReasons":{"type":"array","items":{"$ref":"#/components/schemas/LockReasonDto"}}}},"MaterialArtifactDto":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"materialId":{"type":"string","format":"uuid"},"type":{"type":"string","enum":["TRANSCRIPT","NOTES","SUMMARY","GLOSSARY","FLASHCARDS","QUIZ"]},"payload":{},"sourceRefs":{},"state":{"type":"string","enum":["PENDING","RELEASED","HIDDEN"]},"hiddenByTeacher":{"type":"boolean"},"generatedAt":{"type":"string","format":"date-time"},"provider":{"type":"string","enum":["GEMINI","HARMIX"]},"language":{"type":"string"},"contentHash":{"type":"string"},"artifactVersion":{"type":"integer","format":"int32"}}},"GoalSummaryDto":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"code":{"type":"string"},"name":{"type":"string"},"nameKk":{"type":"string"},"nameEn":{"type":"string"},"readinessPct":{"type":"integer","format":"int32"},"step":{"type":"integer","format":"int32"},"confirmed":{"type":"integer","format":"int32"},"total":{"type":"integer","format":"int32"},"weakest":{"$ref":"#/components/schemas/WeakestAreaDto"}}},"MyGoalDto":{"type":"object","properties":{"state":{"type":"string","enum":["NO_GOAL","NO_SKILLS","READY"]},"goal":{"$ref":"#/components/schemas/GoalSummaryDto"}}},"WeakestAreaDto":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"nameRu":{"type":"string"},"nameKk":{"type":"string"},"nameEn":{"type":"string"},"pct":{"type":"integer","format":"int32"}}},"SkillDto":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"code":{"type":"string"},"nameRu":{"type":"string"},"nameKk":{"type":"string"},"nameEn":{"type":"string"},"aliases":{"type":"array","items":{"type":"string"}},"taxonomyVersion":{"type":"string"},"pendingModeration":{"type":"boolean"}}},"StudyArtifactSummaryDto":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"type":{"type":"string","enum":["CHAT","FLASHCARDS","QUIZ","PODCAST","SUMMARY","MINDMAP","TIMELINE","TRANSCRIPT","NOTES","GLOSSARY"]},"reportKind":{"type":"string"},"title":{"type":"string"},"status":{"type":"string","enum":["GENERATING","READY","FAILED"]},"failCode":{"type":"string"},"language":{"type":"string"},"legacy":{"type":"boolean"},"sourceId":{"type":"string","format":"uuid"},"createdAt":{"type":"string","format":"date-time"},"completedAt":{"type":"string","format":"date-time"}}},"CourseRef":{"type":"object","properties":{"courseId":{"type":"string","format":"uuid"},"courseCode":{"type":"string"},"courseTitle":{"type":"string"}}},"Reason":{"type":"object","properties":{"type":{"type":"string"},"importance":{"type":"string"},"messageRu":{"type":"string"},"messageKk":{"type":"string"},"messageEn":{"type":"string"},"courseId":{"type":"string","format":"uuid"}}},"TeacherAtRiskStudentDto":{"type":"object","properties":{"learnerId":{"type":"string","format":"uuid"},"keycloakId":{"type":"string"},"fullName":{"type":"string"},"programTitle":{"type":"string"},"riskLevel":{"type":"string"},"basis":{"type":"string"},"courses":{"type":"array","items":{"$ref":"#/components/schemas/CourseRef"}},"activeCount":{"type":"integer","format":"int32"},"reasons":{"type":"array","items":{"$ref":"#/components/schemas/Reason"}},"recommendedActionRu":{"type":"string"},"recommendedActionKk":{"type":"string"},"recommendedActionEn":{"type":"string"}}},"ParticipantCandidateDto":{"type":"object","properties":{"keycloakId":{"type":"string"},"fullName":{"type":"string"},"programCode":{"type":"string"},"courseYear":{"type":"integer","format":"int32"},"enrolled":{"type":"boolean"}}},"CourseFillDto":{"type":"object","properties":{"courseId":{"type":"string","format":"uuid"},"itemsDone":{"type":"integer","format":"int32"},"itemsTotal":{"type":"integer","format":"int32"},"fillPct":{"type":"number"},"items":{"type":"array","items":{"$ref":"#/components/schemas/Item"}}}},"Item":{"type":"object","properties":{"code":{"type":"string","enum":["SECTIONS","MATERIALS","MATERIALS_PUBLISHED","WORKS","WORKS_PUBLISHED","ASSESSMENT_SCHEME"]},"labelRu":{"type":"string"},"labelKk":{"type":"string"},"labelEn":{"type":"string"},"done":{"type":"boolean"}}},"HistoryFile":{"type":"object","properties":{"s3FileId":{"type":"string"},"originalFilename":{"type":"string"},"mimeType":{"type":"string"},"sizeBytes":{"type":"integer","format":"int64"},"expiresAt":{"type":"string","format":"date-time"},"purged":{"type":"boolean"}}},"SubmissionHistoryEventDto":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"at":{"type":"string","format":"date-time"},"action":{"type":"string"},"actorRole":{"type":"string"},"actorName":{"type":"string"},"late":{"type":"boolean"},"file":{"$ref":"#/components/schemas/HistoryFile"},"previousFile":{"$ref":"#/components/schemas/HistoryFile"},"comment":{"type":"string"},"score":{"type":"integer","format":"int32"},"maxScore":{"type":"integer","format":"int32"},"lateBySeconds":{"type":"integer","format":"int64"},"effectiveDeadline":{"type":"string","format":"date-time"},"afterGrade":{"type":"boolean"},"textBefore":{"type":"string"},"textAfter":{"type":"string"},"linkBefore":{"type":"string"},"linkAfter":{"type":"string"},"files":{"type":"array","items":{"$ref":"#/components/schemas/HistoryFile"}}}},"MediaChapterDto":{"type":"object","properties":{"startSec":{"type":"integer","format":"int32"},"title":{"type":"string"}}},"StudySourceDetailDto":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"spaceId":{"type":"string","format":"uuid"},"title":{"type":"string"},"kind":{"type":"string","enum":["FILE","TEXT","LINK","RECORDING","BOOK"]},"displayKind":{"type":"string"},"materialId":{"type":"string","format":"uuid"},"url":{"type":"string"},"s3FileId":{"type":"string","format":"uuid"},"selected":{"type":"boolean"},"readyForAi":{"type":"boolean"},"extractStatus":{"type":"string","enum":["PENDING","EXTRACTING","INDEXED","FAILED"]},"failReason":{"type":"string"},"failReasonCode":{"type":"string"},"transcriptUnavailableReason":{"type":"string"},"pageCount":{"type":"integer","format":"int32"},"textLength":{"type":"integer","format":"int32"},"guide":{"$ref":"#/components/schemas/SourceGuideDto"},"autoKitState":{"type":"string"},"createdAt":{"type":"string","format":"date-time"},"sizeBytes":{"type":"integer","format":"int64"},"updatedAt":{"type":"string","format":"date-time"},"fileMissing":{"type":"boolean"},"originalAvailable":{"type":"boolean"},"pageOffsets":{"type":"array","items":{"type":"integer","format":"int32"}},"youtube":{},"mediaChapters":{"type":"array","items":{"$ref":"#/components/schemas/MediaChapterDto"}},"mediaChaptersOrigin":{"type":"string"},"bodyDoc":{},"autoMaterials":{"type":"array","items":{"$ref":"#/components/schemas/StudyArtifactSummaryDto"}}}},"SourceTextWindowDto":{"type":"object","properties":{"sourceId":{"type":"string","format":"uuid"},"textLength":{"type":"integer","format":"int32"},"offset":{"type":"integer","format":"int32"},"text":{"type":"string"}}},"NotebookDetailDto":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"title":{"type":"string"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"},"preferredLocale":{"type":"string"},"maxSources":{"type":"integer","format":"int32"},"sources":{"type":"array","items":{"$ref":"#/components/schemas/StudySourceDto"}},"overview":{"$ref":"#/components/schemas/NotebookOverviewDto"},"artifacts":{"type":"array","items":{"$ref":"#/components/schemas/StudyArtifactSummaryDto"}},"notesCount":{"type":"integer","format":"int64"}}},"NotebookOverviewDto":{"type":"object","properties":{"state":{"type":"string"},"text":{"type":"string"},"questions":{"type":"array","items":{"type":"string"}},"locale":{"type":"string"}}},"CoursePickerDto":{"type":"object","properties":{"courseId":{"type":"string","format":"uuid"},"title":{"type":"string"},"sections":{"type":"array","items":{"$ref":"#/components/schemas/Section"}}}},"Section":{"type":"object","properties":{"title":{"type":"string"},"items":{"type":"array","items":{"$ref":"#/components/schemas/Item"}}}},"CoursePickerCourseDto":{"type":"object","properties":{"courseId":{"type":"string","format":"uuid"},"code":{"type":"string"},"academicYear":{"type":"string"},"title":{"type":"string"},"titleKk":{"type":"string"},"titleEn":{"type":"string"},"active":{"type":"boolean"},"materialCount":{"type":"integer","format":"int32"},"recordingCount":{"type":"integer","format":"int32"}}},"SkillOptionDto":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"code":{"type":"string"},"nameRu":{"type":"string"},"nameKk":{"type":"string"},"nameEn":{"type":"string"}}},"Area":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"nameRu":{"type":"string"},"nameKk":{"type":"string"},"nameEn":{"type":"string"},"type":{"type":"string"},"percent":{"type":"integer","format":"int32"},"step":{"type":"integer","format":"int32"}}},"Badge":{"type":"object","properties":{"code":{"type":"string"},"nameRu":{"type":"string"},"nameKk":{"type":"string"},"nameEn":{"type":"string"},"factRu":{"type":"string"},"factKk":{"type":"string"},"factEn":{"type":"string"}}},"Certificate":{"type":"object","properties":{"title":{"type":"string"},"issuer":{"type":"string"},"issuedOn":{"type":"string","format":"date"},"credentialUrl":{"type":"string"},"skills":{"type":"array","items":{"$ref":"#/components/schemas/SkillName"}},"verifiedAt":{"type":"string","format":"date-time"},"issuedByUniversity":{"type":"boolean"},"titleKk":{"type":"string"},"titleEn":{"type":"string"}}},"File":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"fileName":{"type":"string"}}},"Goal":{"type":"object","properties":{"code":{"type":"string"},"nameRu":{"type":"string"},"nameKk":{"type":"string"},"nameEn":{"type":"string"}}},"PublicResumeDto":{"type":"object","properties":{"fullName":{"type":"string"},"programCode":{"type":"string"},"programName":{"type":"string"},"skills":{"type":"array","deprecated":true,"items":{"deprecated":true}},"courses":{"type":"array","deprecated":true,"items":{"deprecated":true}},"sections":{"type":"array","deprecated":true,"items":{"deprecated":true}},"achievements":{"type":"array","items":{"$ref":"#/components/schemas/Work"}},"programLevel":{"type":"string"},"hasPhoto":{"type":"boolean"},"courseYear":{"type":"integer","format":"int32"},"searchStatus":{"type":"string"},"goal":{"$ref":"#/components/schemas/Goal"},"about":{"type":"string"},"contacts":{"type":"string"},"skillAreas":{"$ref":"#/components/schemas/SkillAreas"},"certificates":{"type":"array","items":{"$ref":"#/components/schemas/Certificate"}},"badges":{"type":"array","items":{"$ref":"#/components/schemas/Badge"}}}},"SkillAreas":{"type":"object","properties":{"state":{"type":"string"},"areas":{"type":"array","items":{"$ref":"#/components/schemas/Area"}},"confirmed":{"type":"integer","format":"int32"},"total":{"type":"integer","format":"int32"}}},"Work":{"type":"object","properties":{"kind":{"type":"string"},"title":{"type":"string"},"role":{"type":"string"},"startedOn":{"type":"string","format":"date"},"achievedOn":{"type":"string","format":"date"},"description":{"type":"string"},"link":{"type":"string"},"files":{"type":"array","items":{"$ref":"#/components/schemas/File"}},"origin":{"type":"string"},"confirmedByName":{"type":"string"},"status":{"type":"string"},"roleNameRu":{"type":"string"},"roleNameKk":{"type":"string"},"roleNameEn":{"type":"string"},"teamSize":{"type":"integer","format":"int32"},"stack":{"type":"array","items":{"$ref":"#/components/schemas/SkillName"}},"contributions":{"type":"array","items":{"type":"string"}},"confirmedBy":{"type":"string"}}},"QuizSummaryDto":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"courseId":{"type":"string","format":"uuid"},"moduleId":{"type":"string","format":"uuid"},"orderIndex":{"type":"integer","format":"int32"},"title":{"type":"string"},"status":{"type":"string","enum":["DRAFT","PUBLISHED"]},"availableFrom":{"type":"string","format":"date-time"},"availableUntil":{"type":"string","format":"date-time"},"windowClosed":{"type":"boolean"},"questionCount":{"type":"integer","format":"int64"},"componentId":{"type":"string","format":"uuid"},"attempted":{"type":"boolean"},"bestScorePct":{"type":"number","format":"double"},"lastAttemptAt":{"type":"string","format":"date-time"},"attemptsAllowed":{"type":"integer","format":"int32"},"attemptsUsed":{"type":"integer","format":"int32"},"canAttempt":{"type":"boolean"},"awaitingReview":{"type":"boolean"},"hasOpenAttempt":{"type":"boolean"},"openAttemptId":{"type":"string","format":"uuid"},"lockReasons":{"type":"array","items":{"$ref":"#/components/schemas/LockReasonDto"}},"perAttemptDraw":{"type":"boolean"}}},"QuizDto":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"courseId":{"type":"string","format":"uuid"},"moduleId":{"type":"string","format":"uuid"},"title":{"type":"string"},"status":{"type":"string","enum":["DRAFT","PUBLISHED"]},"availableFrom":{"type":"string","format":"date-time"},"availableUntil":{"type":"string","format":"date-time"},"componentId":{"type":"string","format":"uuid"},"attemptsAllowed":{"type":"integer","format":"int32"},"attemptsUsed":{"type":"integer","format":"int32"},"canAttempt":{"type":"boolean"},"showReview":{"type":"boolean"},"totalPoints":{"type":"integer","format":"int32"},"questionCount":{"type":"integer","format":"int32"},"questionsIncluded":{"type":"boolean"},"hasOpenAttempt":{"type":"boolean"},"openAttemptId":{"type":"string","format":"uuid"},"timeLimitMin":{"type":"integer","format":"int32"},"deadlineAt":{"type":"string","format":"date-time"},"deadlineSource":{"type":"string","enum":["TIME_LIMIT","AVAILABILITY_WINDOW","NONE"]},"serverNow":{"type":"string","format":"date-time"},"secondsRemaining":{"type":"integer","format":"int64"},"proctoringMode":{"type":"string","enum":["NONE","CAMERA","CAMERA_SCREEN"]},"proctoringLogTabLeave":{"type":"boolean"},"questions":{"type":"array","items":{"$ref":"#/components/schemas/QuizQuestionDto"}},"perAttemptDraw":{"type":"boolean"}}},"QuizAttemptHistoryDto":{"type":"object","properties":{"quizId":{"type":"string","format":"uuid"},"courseId":{"type":"string","format":"uuid"},"quizTitle":{"type":"string"},"showReview":{"type":"boolean"},"attemptsAllowed":{"type":"integer","format":"int32"},"attemptsUsed":{"type":"integer","format":"int32"},"canAttempt":{"type":"boolean"},"attempts":{"type":"array","items":{"$ref":"#/components/schemas/QuizAttemptHistoryItemDto"}}}},"QuizAttemptHistoryItemDto":{"type":"object","properties":{"attemptId":{"type":"string","format":"uuid"},"attemptNumber":{"type":"integer","format":"int32"},"learnerId":{"type":"string","format":"uuid"},"studentName":{"type":"string"},"attemptsUsed":{"type":"integer","format":"int32"},"status":{"type":"string","enum":["IN_PROGRESS","COMPLETED","AWAITING_REVIEW","REVIEWED"]},"startedAt":{"type":"string","format":"date-time"},"attemptedAt":{"type":"string","format":"date-time"},"deadlineAt":{"type":"string","format":"date-time"},"reviewedAt":{"type":"string","format":"date-time"},"scorePct":{"type":"number","format":"double"},"earnedPoints":{"type":"number"},"maxPoints":{"type":"number"},"closedByTimer":{"type":"boolean"},"closedByTeacher":{"type":"boolean"},"awaitingReview":{"type":"boolean"},"countsForGrade":{"type":"boolean"},"returnedByTeacher":{"type":"boolean"}}},"PublicTranscriptVerificationDto":{"type":"object","properties":{"valid":{"type":"boolean"},"number":{"type":"string"},"fullName":{"type":"string"},"programCode":{"type":"string"},"programTitle":{"type":"string"},"programTitleKk":{"type":"string"},"programTitleEn":{"type":"string"},"generatedAt":{"type":"string","format":"date-time"}}},"PublicGradesheetVerificationDto":{"type":"object","properties":{"courseCode":{"type":"string"},"courseTitle":{"type":"string"},"version":{"type":"integer","format":"int32"},"signed":{"type":"boolean"},"signedAt":{"type":"string","format":"date-time"},"overallValid":{"type":"boolean"},"signer":{"$ref":"#/components/schemas/PublicSigner"}}},"PublicSigner":{"type":"object","properties":{"fullName":{"type":"string"},"iinMasked":{"type":"string"},"role":{"type":"string"},"valid":{"type":"boolean"}}},"PublicCourseCertificateVerificationDto":{"type":"object","properties":{"status":{"type":"string"},"number":{"type":"string"},"learnerName":{"type":"string"},"courseTitle":{"type":"string"},"courseTitleKk":{"type":"string"},"courseTitleEn":{"type":"string"},"completedAt":{"type":"string","format":"date-time"},"issuedAt":{"type":"string","format":"date-time"},"revokedAt":{"type":"string","format":"date-time"}}},"WeekPlanClassDto":{"type":"object","properties":{"courseCode":{"type":"string"},"courseTitle":{"type":"string"},"activityType":{"type":"string"},"date":{"type":"string","format":"date"},"startTime":{"type":"string"},"endTime":{"type":"string"},"room":{"type":"string"},"teacherName":{"type":"string"}}},"WeekPlanDto":{"type":"object","properties":{"weekStart":{"type":"string","format":"date"},"weekEnd":{"type":"string","format":"date"},"scheduleAvailable":{"type":"boolean"},"classes":{"type":"array","items":{"$ref":"#/components/schemas/WeekPlanClassDto"}},"items":{"type":"array","items":{"$ref":"#/components/schemas/WeekPlanItemDto"}},"doneCount":{"type":"integer","format":"int32"},"totalCount":{"type":"integer","format":"int32"}}},"WeekPlanItemDto":{"type":"object","properties":{"kind":{"type":"string","enum":["ASSIGNMENT_DUE","PLACEMENT","CAREER_GOAL","PREP_BLOCK"]},"subjectId":{"type":"string","format":"uuid"},"titleRu":{"type":"string"},"titleKk":{"type":"string"},"titleEn":{"type":"string"},"detailRu":{"type":"string"},"detailKk":{"type":"string"},"detailEn":{"type":"string"},"done":{"type":"boolean"},"link":{"type":"string"},"dueAt":{"type":"string","format":"date-time"},"count":{"type":"integer","format":"int32"}}},"TrajectoryOptionDto":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"titleRu":{"type":"string"},"titleKk":{"type":"string"},"titleEn":{"type":"string"},"descriptionRu":{"type":"string"},"descriptionKk":{"type":"string"},"descriptionEn":{"type":"string"},"totalCredits":{"type":"integer","format":"int32"},"selected":{"type":"boolean"},"terms":{"type":"array","items":{"$ref":"#/components/schemas/Term"}}}},"AttendanceSlice":{"type":"object","properties":{"marked":{"type":"integer","format":"int32"},"present":{"type":"integer","format":"int32"},"late":{"type":"integer","format":"int32"},"absent":{"type":"integer","format":"int32"},"excused":{"type":"integer","format":"int32"},"ratePct":{"type":"integer","format":"int32"}}},"CourseGradeItem":{"type":"object","properties":{"courseId":{"type":"string","format":"uuid"},"courseCode":{"type":"string"},"courseTitle":{"type":"string"},"credits":{"type":"integer","format":"int32"},"totalPct":{"type":"number"},"letterGrade":{"type":"string"},"gpaValue":{"type":"number"},"status":{"type":"string","enum":["IN_PROGRESS","FINALIZED","FAILED","WITHDRAWN"]},"notAdmitted":{"type":"boolean"},"finalizedAt":{"type":"string","format":"date-time"},"courseKind":{"type":"string","enum":["DISCIPLINE","PREREQUISITE","OPEN"]}}},"ObservationDto":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"type":{"type":"string"},"importance":{"type":"string"},"messageRu":{"type":"string"},"messageKk":{"type":"string"},"messageEn":{"type":"string"},"payload":{"type":"object","additionalProperties":{}},"link":{"type":"string"},"createdAt":{"type":"string","format":"date-time"},"seen":{"type":"boolean"}}},"SemesterSummaryDto":{"type":"object","properties":{"academicYear":{"type":"string"},"termNo":{"type":"integer","format":"int32"},"termStart":{"type":"string","format":"date"},"termEnd":{"type":"string","format":"date"},"termGpa":{"type":"number"},"termCredits":{"type":"integer","format":"int32"},"termEarnedCredits":{"type":"integer","format":"int32"},"cumulativeGpa":{"type":"number"},"totalCredits":{"type":"integer","format":"int32"},"earnedCredits":{"type":"integer","format":"int32"},"courses":{"type":"array","items":{"$ref":"#/components/schemas/CourseGradeItem"}},"attendance":{"$ref":"#/components/schemas/AttendanceSlice"},"skills":{"type":"array","items":{"$ref":"#/components/schemas/SkillProgressItem"}},"observations":{"type":"array","items":{"$ref":"#/components/schemas/ObservationDto"}},"reflection":{"$ref":"#/components/schemas/SemesterReflectionDto"}}},"SkillProgressItem":{"type":"object","properties":{"skillId":{"type":"string","format":"uuid"},"skillCode":{"type":"string"},"skillName":{"type":"string"},"band":{"type":"string","enum":["ATTEMPTED","FAMILIAR","PROFICIENT","MASTERED"]},"probability":{"type":"number","format":"double"},"evidenceCount":{"type":"integer","format":"int32"},"lastEvidenceAt":{"type":"string","format":"date-time"}}},"PrepBlockDto":{"type":"object","properties":{"directionId":{"type":"string","format":"uuid"},"directionCode":{"type":"string"},"directionName":{"type":"string"},"level":{"type":"integer","format":"int32"},"sharePct":{"type":"integer","format":"int32"},"achievedAt":{"type":"string","format":"date-time"},"title":{"type":"string"},"body":{"type":"string"},"reason":{"type":"string"},"courseId":{"type":"string","format":"uuid"},"courseCode":{"type":"string"},"courseTitle":{"type":"string"},"materialId":{"type":"string","format":"uuid"},"url":{"type":"string"},"hasLink":{"type":"boolean"}}},"PrepPlanDto":{"type":"object","properties":{"blocks":{"type":"array","items":{"$ref":"#/components/schemas/PrepBlockDto"}},"generatedAt":{"type":"string","format":"date-time"}}},"PlacementDirectionStateDto":{"type":"object","properties":{"directionId":{"type":"string","format":"uuid"},"code":{"type":"string"},"name":{"type":"string"},"description":{"type":"string"},"kind":{"type":"string","enum":["SCORED","SURVEY"]},"status":{"type":"string","enum":["NOT_STARTED","IN_PROGRESS","COMPLETED","BANK_EMPTY"]},"questionsPerAttempt":{"type":"integer","format":"int32"},"availableQuestions":{"type":"integer","format":"int64"},"openAttemptId":{"type":"string","format":"uuid"},"result":{"$ref":"#/components/schemas/PlacementResultDto"}}},"PlacementOverviewDto":{"type":"object","properties":{"directions":{"type":"array","items":{"$ref":"#/components/schemas/PlacementDirectionStateDto"}},"completedDirections":{"type":"integer","format":"int32"},"startableDirections":{"type":"integer","format":"int32"},"allCompleted":{"type":"boolean"},"lastResultAt":{"type":"string","format":"date-time"}}},"AchievementDto":{"type":"object","properties":{"code":{"type":"string"},"category":{"type":"string"},"name":{"$ref":"#/components/schemas/LocalizedTextDto"},"condition":{"$ref":"#/components/schemas/LocalizedTextDto"},"tiered":{"type":"boolean"},"tier":{"type":"string"},"tiers":{"type":"array","items":{"$ref":"#/components/schemas/AchievementTierDto"}},"progress":{"$ref":"#/components/schemas/AchievementProgressDto"},"unavailableReason":{"type":"string"},"resumeEligible":{"type":"boolean"}}},"AchievementProgressDto":{"type":"object","properties":{"current":{"type":"integer","format":"int32"},"target":{"type":"integer","format":"int32"},"nextTier":{"type":"string"},"unit":{"type":"string"},"text":{"$ref":"#/components/schemas/LocalizedTextDto"}}},"AchievementTierDto":{"type":"object","properties":{"tier":{"type":"string"},"threshold":{"type":"integer","format":"int32"},"earnedAt":{"type":"string","format":"date-time"}}},"ExperienceDto":{"type":"object","properties":{"points":{"type":"integer","format":"int32"},"level":{"type":"integer","format":"int32"},"levelName":{"$ref":"#/components/schemas/LocalizedTextDto"},"levelThreshold":{"type":"integer","format":"int32"},"nextLevel":{"type":"integer","format":"int32"},"nextLevelName":{"$ref":"#/components/schemas/LocalizedTextDto"},"nextThreshold":{"type":"integer","format":"int32"},"pointsToNext":{"type":"integer","format":"int32"},"ladder":{"type":"array","items":{"$ref":"#/components/schemas/LevelStepDto"}}}},"GamificationOverviewDto":{"type":"object","properties":{"enabled":{"type":"boolean"},"experience":{"$ref":"#/components/schemas/ExperienceDto"},"achievements":{"type":"array","items":{"$ref":"#/components/schemas/AchievementDto"}},"showcase":{"$ref":"#/components/schemas/ShowcaseDto"}}},"LevelStepDto":{"type":"object","properties":{"level":{"type":"integer","format":"int32"},"code":{"type":"string"},"name":{"$ref":"#/components/schemas/LocalizedTextDto"},"threshold":{"type":"integer","format":"int32"}}},"PointRuleDto":{"type":"object","properties":{"code":{"type":"string"},"group":{"type":"string"},"label":{"$ref":"#/components/schemas/LocalizedTextDto"},"points":{"type":"integer","format":"int32"},"note":{"$ref":"#/components/schemas/LocalizedTextDto"}}},"PointRulesDto":{"type":"object","properties":{"rules":{"type":"array","items":{"$ref":"#/components/schemas/PointRuleDto"}},"ladder":{"type":"array","items":{"$ref":"#/components/schemas/LevelStepDto"}}}},"ElectiveHintDto":{"type":"object","properties":{"courseId":{"type":"string","format":"uuid"},"courseCode":{"type":"string"},"courseTitle":{"type":"string"},"credits":{"type":"integer","format":"int32"},"trimester":{"type":"integer","format":"int32"},"matchesGoal":{"type":"boolean"},"goalCompetencies":{"type":"array","items":{"type":"string"}},"closesGap":{"type":"boolean"},"gapSkills":{"type":"array","items":{"type":"string"}},"reason":{"type":"string"}}},"DashboardLevelDto":{"type":"object","properties":{"level":{"type":"integer","format":"int32"},"hasEnrollments":{"type":"boolean"},"activeEnrollments":{"type":"integer","format":"int32"},"hasSchedule":{"type":"boolean"}}},"MyCourseCertificateDto":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"courseId":{"type":"string","format":"uuid"},"courseTitle":{"type":"string"},"courseTitleKk":{"type":"string"},"courseTitleEn":{"type":"string"},"number":{"type":"string"},"issuedAt":{"type":"string","format":"date-time"},"revokedAt":{"type":"string","format":"date-time"},"hiddenOnResume":{"type":"boolean"}}},"AttendanceMarkDto":{"type":"object","properties":{"date":{"type":"string","format":"date"},"status":{"type":"string","enum":["PRESENT","ABSENT","LATE","EXCUSED"]},"sectionId":{"type":"string","format":"uuid"},"groupNo":{"type":"integer","format":"int32"},"markedByName":{"type":"string"},"markedAt":{"type":"string","format":"date-time"}}},"MyAttendanceCourseDto":{"type":"object","properties":{"courseId":{"type":"string","format":"uuid"},"courseCode":{"type":"string"},"courseTitle":{"type":"string"},"present":{"type":"integer","format":"int32"},"absent":{"type":"integer","format":"int32"},"late":{"type":"integer","format":"int32"},"excused":{"type":"integer","format":"int32"},"ratePct":{"type":"integer","format":"int32"},"admissionRatePct":{"type":"integer","format":"int32"},"admissionCountedFrom":{"type":"string","format":"date"},"attendanceThresholdPct":{"type":"integer","format":"int32"},"attendanceAdmitted":{"type":"boolean"},"waived":{"type":"boolean"},"waivedReason":{"type":"string"},"admissionRevokedReason":{"type":"string"},"missesLeft":{"type":"integer","format":"int32"},"attendancesNeeded":{"type":"integer","format":"int32"},"frozen":{"type":"boolean"},"records":{"type":"array","items":{"$ref":"#/components/schemas/AttendanceMarkDto"}}}},"MyAttendanceLessonDto":{"type":"object","properties":{"courseId":{"type":"string","format":"uuid"},"courseCode":{"type":"string"},"courseTitle":{"type":"string"},"sectionId":{"type":"string","format":"uuid"},"date":{"type":"string","format":"date"},"activityType":{"type":"string"},"groupNo":{"type":"integer","format":"int32"},"startTime":{"type":"string"},"endTime":{"type":"string"},"room":{"type":"string"},"online":{"type":"boolean"},"past":{"type":"boolean"},"status":{"type":"string","enum":["PRESENT","ABSENT","LATE","EXCUSED"]},"markedByName":{"type":"string"},"markedAt":{"type":"string","format":"date-time"},"appealId":{"type":"string","format":"uuid"},"appealStatus":{"type":"string","enum":["PENDING","ACCEPTED","REJECTED","WITHDRAWN","CLOSED_UNRESOLVED"]},"appealable":{"type":"boolean"},"appealBlockedReason":{"type":"string"},"appealBlockedCode":{"type":"string"}}},"MyAttendanceLessonsDto":{"type":"object","properties":{"from":{"type":"string","format":"date"},"to":{"type":"string","format":"date"},"scheduleAvailable":{"type":"boolean"},"lessons":{"type":"array","items":{"$ref":"#/components/schemas/MyAttendanceLessonDto"}}}},"CheckQuestionDto":{"type":"object","properties":{"quizId":{"type":"string","format":"uuid"},"question":{"$ref":"#/components/schemas/QuizQuestionDto"}}},"MaterialSpacesDto":{"type":"object","properties":{"materialId":{"type":"string","format":"uuid"},"spaceIds":{"type":"array","items":{"type":"string","format":"uuid"}}}},"MaterialContentDto":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"title":{"type":"string"},"mimeType":{"type":"string"},"content":{"type":"string"}}},"LessonFeedbackOptionsDto":{"type":"object","properties":{"tags":{"type":"array","items":{"$ref":"#/components/schemas/TagOption"}},"maxTags":{"type":"integer","format":"int32"},"ratingMin":{"type":"integer","format":"int32"},"ratingMax":{"type":"integer","format":"int32"},"commentMaxLength":{"type":"integer","format":"int32"},"editWindowHours":{"type":"integer","format":"int32"},"feedbackWindowDays":{"type":"integer","format":"int32"}}},"TagOption":{"type":"object","properties":{"code":{"type":"string"},"labelRu":{"type":"string"},"labelKk":{"type":"string"},"labelEn":{"type":"string"}}},"GradebookCriterionScoreDto":{"type":"object","properties":{"criterionId":{"type":"string","format":"uuid"},"title":{"type":"string"},"maxPoints":{"type":"integer","format":"int32"},"score":{"type":"integer","format":"int32"}}},"GradebookEntryDto":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"courseId":{"type":"string","format":"uuid"},"assignmentId":{"type":"string","format":"uuid"},"assignmentTitle":{"type":"string"},"totalScore":{"type":"integer","format":"int32"},"maxScore":{"type":"integer","format":"int32"},"feedback":{"type":"string"},"criterionScores":{"type":"array","items":{"$ref":"#/components/schemas/GradebookCriterionScoreDto"}},"approvedAt":{"type":"string","format":"date-time"},"totalOverridden":{"type":"boolean"},"revisionReason":{"type":"string"}}},"TranscriptDto":{"type":"object","properties":{"cumulativeGpa":{"type":"number"},"totalCredits":{"type":"integer","format":"int32"},"earnedCredits":{"type":"integer","format":"int32"},"terms":{"type":"array","items":{"$ref":"#/components/schemas/TranscriptTerm"}}}},"TranscriptTerm":{"type":"object","properties":{"academicYear":{"type":"string"},"termNo":{"type":"integer","format":"int32"},"termGpa":{"type":"number"},"termCredits":{"type":"integer","format":"int32"},"termEarnedCredits":{"type":"integer","format":"int32"},"courses":{"type":"array","items":{"$ref":"#/components/schemas/CourseGradeItem"}}}},"MyRecreditDto":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"disciplineCode":{"type":"string"},"disciplineTitle":{"type":"string"},"disciplineTitleKk":{"type":"string"},"disciplineTitleEn":{"type":"string"},"academicYear":{"type":"string"},"termNo":{"type":"integer","format":"int32"},"previousDisciplineTitle":{"type":"string"},"previousCredits":{"type":"number"},"previousGrade":{"type":"string"},"credits":{"type":"integer","format":"int32"},"letterGrade":{"type":"string"},"totalPct":{"type":"number"},"gpaValue":{"type":"number"},"basis":{"type":"string"},"decisionNumber":{"type":"string"},"decisionDate":{"type":"string","format":"date"},"confirmedAt":{"type":"string","format":"date-time"}}},"QuizAttemptFeedDto":{"type":"object","properties":{"quizAttemptId":{"type":"string","format":"uuid"},"quizId":{"type":"string","format":"uuid"},"quizTitle":{"type":"string"},"courseId":{"type":"string","format":"uuid"},"courseCode":{"type":"string"},"courseTitle":{"type":"string"},"scorePct":{"type":"number","format":"double"},"status":{"type":"string","enum":["IN_PROGRESS","COMPLETED","AWAITING_REVIEW","REVIEWED"]},"awaitingReview":{"type":"boolean"},"attemptNumber":{"type":"integer","format":"int32"},"attemptedAt":{"type":"string","format":"date-time"}}},"PlanTranscriptDto":{"type":"object","properties":{"header":{"$ref":"#/components/schemas/TranscriptHeaderDto"},"scope":{"type":"string","enum":["ALL","YEAR","COURSE"]},"academicYear":{"type":"string"},"courseNo":{"type":"integer","format":"int32"},"availableYears":{"type":"array","items":{"type":"string"}},"availableCourses":{"type":"array","items":{"type":"integer","format":"int32"}},"years":{"type":"array","items":{"$ref":"#/components/schemas/YearBlock"}},"summary":{"$ref":"#/components/schemas/Summary"},"generatedAt":{"type":"string","format":"date-time"}}},"Summary":{"type":"object","properties":{"kind":{"type":"string"},"registeredCredits":{"type":"integer","format":"int32"},"earnedCredits":{"type":"integer","format":"int32"},"failedCredits":{"type":"integer","format":"int32"},"recreditedCredits":{"type":"integer","format":"int32"},"restudiedCredits":{"type":"integer","format":"int32"},"gpa":{"type":"number"},"passedDisciplines":{"type":"integer","format":"int32"},"recreditedDisciplines":{"type":"integer","format":"int32"},"requiredCredits":{"type":"integer","format":"int32"},"remainingCredits":{"type":"integer","format":"int32"},"requirementMet":{"type":"boolean"},"statusCounts":{"type":"object","additionalProperties":{"type":"integer","format":"int32"}}}},"TermBlock":{"type":"object","properties":{"termNo":{"type":"integer","format":"int32"},"planSlot":{"type":"integer","format":"int32"},"startDate":{"type":"string","format":"date"},"endDate":{"type":"string","format":"date"},"rows":{"type":"array","items":{"$ref":"#/components/schemas/TranscriptRowDto"}},"totals":{"$ref":"#/components/schemas/TermTotals"}}},"TermTotals":{"type":"object","properties":{"registeredCredits":{"type":"integer","format":"int32"},"earnedCredits":{"type":"integer","format":"int32"},"failedCredits":{"type":"integer","format":"int32"},"gpa":{"type":"number"}}},"TranscriptHeaderDto":{"type":"object","properties":{"learnerId":{"type":"string","format":"uuid"},"studentKeycloakId":{"type":"string"},"fullName":{"type":"string"},"universityName":{"type":"string"},"programCode":{"type":"string"},"programTitle":{"type":"string"},"programTitleKk":{"type":"string"},"programTitleEn":{"type":"string"},"studyLevel":{"type":"string"},"studyForm":{"type":"string"},"instructionLanguage":{"type":"string"},"admissionYear":{"type":"integer","format":"int32"},"courseYear":{"type":"integer","format":"int32"},"fundingForm":{"type":"string"},"studyPeriodFrom":{"type":"string"},"studyPeriodTo":{"type":"string"},"documentPeriodFrom":{"type":"string"},"documentPeriodTo":{"type":"string"}}},"YearBlock":{"type":"object","properties":{"academicYear":{"type":"string"},"courseNo":{"type":"integer","format":"int32"},"terms":{"type":"array","items":{"$ref":"#/components/schemas/TermBlock"}},"totals":{"$ref":"#/components/schemas/YearTotals"}}},"YearTotals":{"type":"object","properties":{"registeredCredits":{"type":"integer","format":"int32"},"earnedCredits":{"type":"integer","format":"int32"},"gpa":{"type":"number"},"recreditedCredits":{"type":"integer","format":"int32"},"restudiedCredits":{"type":"integer","format":"int32"}}},"GpaSummaryDto":{"type":"object","properties":{"cumulativeGpa":{"type":"number"},"gradedCredits":{"type":"integer","format":"int32"},"earnedCredits":{"type":"integer","format":"int32"},"courses":{"type":"array","items":{"$ref":"#/components/schemas/CourseGradeItem"}}}},"ComponentScore":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"code":{"type":"string"},"name":{"type":"string"},"kind":{"type":"string","enum":["MIDTERM_CONTROL","FINAL_EXAM"]},"isExam":{"type":"boolean"},"weightPct":{"type":"integer","format":"int32"},"scorePct":{"type":"number"},"hasGradedElements":{"type":"boolean"},"scoringMode":{"type":"string","enum":["EXPLICIT_WEIGHTS","MAX_SCORE_SUM"]}}},"CourseGradeDto":{"type":"object","properties":{"courseId":{"type":"string","format":"uuid"},"courseCode":{"type":"string"},"courseTitle":{"type":"string"},"componentScores":{"type":"array","items":{"$ref":"#/components/schemas/ComponentScore"}},"admissionRatingPct":{"type":"number"},"admissionThresholdPct":{"type":"integer","format":"int32"},"admitted":{"type":"boolean"},"notAdmitted":{"type":"boolean"},"admissionDecided":{"type":"boolean"},"projected":{"type":"boolean"},"totalPct":{"type":"number"},"letterGrade":{"type":"string"},"gpaValue":{"type":"number"},"attendanceRatePct":{"type":"integer","format":"int32"},"attendanceThresholdPct":{"type":"integer","format":"int32"},"attendanceAdmitted":{"type":"boolean"},"attendanceWaived":{"type":"boolean"},"notAdmittedReason":{"type":"string"},"status":{"type":"string","enum":["IN_PROGRESS","FINALIZED","FAILED","WITHDRAWN"]},"gradesheetFileId":{"type":"string","format":"uuid"},"finalizedAt":{"type":"string","format":"date-time"},"warnings":{"type":"array","items":{"type":"string"}},"academicYear":{"type":"string"},"termNo":{"type":"integer","format":"int32"},"warningCodes":{"type":"array","items":{"$ref":"#/components/schemas/GradeWarning"}},"termCredits":{"type":"array","items":{"$ref":"#/components/schemas/TermCredit"}}}},"GradeWarning":{"type":"object","properties":{"code":{"type":"string"},"params":{"type":"object","additionalProperties":{"type":"string"}}}},"TermCredit":{"type":"object","properties":{"academicYear":{"type":"string"},"termNo":{"type":"integer","format":"int32"},"credits":{"type":"integer","format":"int32"}}},"MyCourseElementDto":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"type":{"type":"string"},"title":{"type":"string"},"componentId":{"type":"string","format":"uuid"},"componentName":{"type":"string"},"componentKind":{"type":"string","enum":["MIDTERM_CONTROL","FINAL_EXAM"]},"componentWeightPct":{"type":"integer","format":"int32"},"elementWeightPct":{"type":"integer","format":"int32"},"inFormula":{"type":"boolean"},"maxScore":{"type":"integer","format":"int32"},"myScore":{"type":"number"},"scorePct":{"type":"number"},"state":{"type":"string"},"deadline":{"type":"string","format":"date-time"},"windowClosed":{"type":"boolean"},"attemptsUsed":{"type":"integer","format":"int32"},"noSubmissionRequired":{"type":"boolean"}}},"FlashcardDeckSummaryDto":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"courseId":{"type":"string","format":"uuid"},"materialId":{"type":"string","format":"uuid"},"title":{"type":"string"},"status":{"type":"string","enum":["DRAFT","PUBLISHED"]},"generatedByAi":{"type":"boolean"},"cardCount":{"type":"integer","format":"int64"},"createdAt":{"type":"string","format":"date-time"}}},"CardDto":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"front":{"type":"string"},"back":{"type":"string"},"orderIndex":{"type":"integer","format":"int32"}}},"FlashcardDeckDto":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"courseId":{"type":"string","format":"uuid"},"materialId":{"type":"string","format":"uuid"},"title":{"type":"string"},"cards":{"type":"array","items":{"$ref":"#/components/schemas/CardDto"}}}},"PageResponseCourseDto":{"type":"object","properties":{"content":{"type":"array","items":{"$ref":"#/components/schemas/CourseDto"}},"page":{"type":"integer","format":"int32"},"size":{"type":"integer","format":"int32"},"totalElements":{"type":"integer","format":"int64"},"totalPages":{"type":"integer","format":"int32"}}},"CourseTreeDto":{"type":"object","properties":{"course":{"$ref":"#/components/schemas/CourseDto"},"modules":{"type":"array","items":{"$ref":"#/components/schemas/ModuleDto"}}}},"AssignmentListItemDto":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"courseId":{"type":"string","format":"uuid"},"moduleId":{"type":"string","format":"uuid"},"orderIndex":{"type":"integer","format":"int32"},"title":{"type":"string"},"status":{"type":"string","enum":["DRAFT","PUBLISHED"]},"descriptionPreview":{"$ref":"#/components/schemas/DescriptionPreviewDto"},"deadline":{"type":"string","format":"date-time"},"availableFrom":{"type":"string","format":"date-time"},"availableUntil":{"type":"string","format":"date-time"},"windowClosed":{"type":"boolean"},"componentId":{"type":"string","format":"uuid"},"mySubmissionStatus":{"type":"string","enum":["SUBMITTED","RETURNED","GRADED","WITHDRAWN"]},"lockReasons":{"type":"array","items":{"$ref":"#/components/schemas/LockReasonDto"}},"noSubmissionRequired":{"type":"boolean"},"myReturnComment":{"type":"string"},"myReturnedAt":{"type":"string","format":"date-time"}}},"CourseItemDto":{"type":"object","properties":{"type":{"type":"string","enum":["MATERIAL","ASSIGNMENT","QUIZ"]},"id":{"type":"string","format":"uuid"},"moduleId":{"type":"string","format":"uuid"},"orderIndex":{"type":"integer","format":"int32"},"material":{"$ref":"#/components/schemas/MaterialDto"},"assignment":{"$ref":"#/components/schemas/AssignmentListItemDto"},"quiz":{"$ref":"#/components/schemas/QuizSummaryDto"}}},"CourseInstanceDto":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"academicYear":{"type":"string"},"trimester":{"type":"integer","format":"int32"},"status":{"type":"string","enum":["OPEN","CLOSED","ARCHIVED"]},"statusLabelRu":{"type":"string"},"statusLabelKk":{"type":"string"},"statusLabelEn":{"type":"string"},"frozenAt":{"type":"string","format":"date-time"},"current":{"type":"boolean"}}},"CourseByStreamDto":{"type":"object","properties":{"courseId":{"type":"string","format":"uuid"},"code":{"type":"string"},"title":{"type":"string"},"streamNo":{"type":"integer","format":"int32"},"language":{"type":"string"}}},"CatalogCourseDto":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"title":{"type":"string"},"titleKk":{"type":"string"},"titleEn":{"type":"string"},"description":{"type":"string"},"teacherName":{"type":"string"},"startsOn":{"type":"string","format":"date"},"endsOn":{"type":"string","format":"date"},"completionMode":{"type":"string","enum":["GRADED","UNGRADED"]},"certificateEnabled":{"type":"boolean"},"skills":{"type":"array","items":{"$ref":"#/components/schemas/CourseSkillDto"}},"elementsCount":{"type":"integer","format":"int32"},"participantsCount":{"type":"integer","format":"int32"},"enrolled":{"type":"boolean"},"enrollmentOrigin":{"type":"string"}}},"CatalogFacetsDto":{"type":"object","properties":{"skills":{"type":"array","items":{"$ref":"#/components/schemas/SkillFacet"}},"teachers":{"type":"array","items":{"$ref":"#/components/schemas/TeacherFacet"}}}},"CatalogPageDto":{"type":"object","properties":{"content":{"type":"array","items":{"$ref":"#/components/schemas/CatalogCourseDto"}},"page":{"type":"integer","format":"int32"},"size":{"type":"integer","format":"int32"},"totalElements":{"type":"integer","format":"int64"},"totalPages":{"type":"integer","format":"int32"},"facets":{"$ref":"#/components/schemas/CatalogFacetsDto"}}},"SkillFacet":{"type":"object","properties":{"skillId":{"type":"string","format":"uuid"},"code":{"type":"string"},"nameRu":{"type":"string"},"nameKk":{"type":"string"},"nameEn":{"type":"string"},"count":{"type":"integer","format":"int32"}}},"TeacherFacet":{"type":"object","properties":{"keycloakId":{"type":"string"},"name":{"type":"string"},"count":{"type":"integer","format":"int32"}}},"AssignmentDetailDto":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"courseId":{"type":"string","format":"uuid"},"moduleId":{"type":"string","format":"uuid"},"title":{"type":"string"},"description":{"type":"string"},"descriptionDoc":{"type":"string"},"descriptionHtml":{"type":"string"},"submissionFormat":{"type":"string","enum":["FILE","TEXT","CODE","LINK"]},"deadline":{"type":"string","format":"date-time"},"deadlineWarning":{"type":"string"},"availableFrom":{"type":"string","format":"date-time"},"availableUntil":{"type":"string","format":"date-time"},"windowClosed":{"type":"boolean"},"componentId":{"type":"string","format":"uuid"},"rubric":{"$ref":"#/components/schemas/RubricDto"},"attachments":{"type":"array","items":{"$ref":"#/components/schemas/AssignmentAttachmentDto"}},"noSubmissionRequired":{"type":"boolean"}}},"RubricCriterionDto":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"title":{"type":"string"},"description":{"type":"string"},"maxPoints":{"type":"integer","format":"int32"},"orderIndex":{"type":"integer","format":"int32"}}},"RubricDto":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"title":{"type":"string"},"maxScore":{"type":"integer","format":"int32"},"criteria":{"type":"array","items":{"$ref":"#/components/schemas/RubricCriterionDto"}}}},"CourseSkillsDto":{"type":"object","properties":{"courseId":{"type":"string","format":"uuid"},"skills":{"type":"array","items":{"$ref":"#/components/schemas/SkillDto"}}}},"AreaDto":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"nameRu":{"type":"string"},"nameKk":{"type":"string"},"nameEn":{"type":"string"},"type":{"type":"string","enum":["PROFESSIONAL","DIGITAL","PERSONAL"]},"weight":{"type":"integer","format":"int32"},"pct":{"type":"integer","format":"int32"},"step":{"type":"integer","format":"int32"},"confirmed":{"type":"integer","format":"int32"},"total":{"type":"integer","format":"int32"},"skills":{"type":"array","items":{"$ref":"#/components/schemas/AreaSkillDto"}},"whereToLearn":{"type":"array","items":{"$ref":"#/components/schemas/LearnPlaceDto"}},"inProgressSkillCount":{"type":"integer","format":"int32"}}},"AreaSkillDto":{"type":"object","properties":{"skillId":{"type":"string","format":"uuid"},"nameRu":{"type":"string"},"nameKk":{"type":"string"},"nameEn":{"type":"string"},"band":{"type":"string","enum":["ATTEMPTED","FAMILIAR","PROFICIENT","MASTERED"]},"targetBand":{"type":"string","enum":["ATTEMPTED","FAMILIAR","PROFICIENT","MASTERED"]},"status":{"type":"string"},"outsideCurriculum":{"type":"boolean"},"viaNear":{"$ref":"#/components/schemas/NearSkillDto"},"source":{"$ref":"#/components/schemas/SourceDto"}}},"LearnPlaceDto":{"type":"object","properties":{"kind":{"type":"string"},"disciplineId":{"type":"string","format":"uuid"},"code":{"type":"string"},"titleRu":{"type":"string"},"titleKk":{"type":"string"},"titleEn":{"type":"string"},"trimester":{"type":"integer","format":"int32"},"status":{"type":"string"},"courseId":{"type":"string","format":"uuid"},"projectId":{"type":"string","format":"uuid"}}},"NearSkillDto":{"type":"object","properties":{"skillId":{"type":"string","format":"uuid"},"nameRu":{"type":"string"},"nameKk":{"type":"string"},"nameEn":{"type":"string"},"band":{"type":"string","enum":["ATTEMPTED","FAMILIAR","PROFICIENT","MASTERED"]}}},"NextStepDto":{"type":"object","properties":{"kind":{"type":"string"},"id":{"type":"string","format":"uuid"},"courseId":{"type":"string","format":"uuid"},"courseTitleRu":{"type":"string"},"courseTitleKk":{"type":"string"},"courseTitleEn":{"type":"string"},"title":{"type":"string"},"dueAt":{"type":"string","format":"date-time"},"raisesAreaIds":{"type":"array","items":{"type":"string","format":"uuid"}},"submissionFormat":{"type":"string","enum":["FILE","TEXT","CODE","LINK"]}}},"OwnSkillDto":{"type":"object","properties":{"skillId":{"type":"string","format":"uuid"},"nameRu":{"type":"string"},"nameKk":{"type":"string"},"nameEn":{"type":"string"},"band":{"type":"string","enum":["ATTEMPTED","FAMILIAR","PROFICIENT","MASTERED"]}}},"SourceDto":{"type":"object","properties":{"kind":{"type":"string"},"titleRu":{"type":"string"},"titleKk":{"type":"string"},"titleEn":{"type":"string"},"trimester":{"type":"integer","format":"int32"}}},"TrajectoryOverviewDto":{"type":"object","properties":{"state":{"type":"string"},"goal":{"$ref":"#/components/schemas/GoalSummaryDto"},"areas":{"type":"array","items":{"$ref":"#/components/schemas/AreaDto"}},"nextSteps":{"type":"array","items":{"$ref":"#/components/schemas/NextStepDto"}},"otherConfirmedSkills":{"type":"array","items":{"$ref":"#/components/schemas/OwnSkillDto"}}}},"MasteryOverviewDto":{"type":"object","properties":{"courseId":{"type":"string","format":"uuid"},"coursePct":{"type":"number","format":"double"},"completionPct":{"type":"number","format":"double"},"completedElements":{"type":"integer","format":"int32"},"totalElements":{"type":"integer","format":"int32"},"records":{"type":"array","items":{"$ref":"#/components/schemas/MasteryRecordDto"}}}},"MasteryRecordDto":{"type":"object","properties":{"skillId":{"type":"string","format":"uuid"},"skillCode":{"type":"string"},"skillNameRu":{"type":"string"},"skillNameKk":{"type":"string"},"skillNameEn":{"type":"string"},"band":{"type":"string","enum":["ATTEMPTED","FAMILIAR","PROFICIENT","MASTERED"]},"probability":{"type":"number","format":"double"},"lastEventAt":{"type":"string","format":"date-time"}}},"MasteryExplainDto":{"type":"object","properties":{"skillId":{"type":"string","format":"uuid"},"skillCode":{"type":"string"},"skillNameRu":{"type":"string"},"skillNameKk":{"type":"string"},"skillNameEn":{"type":"string"},"band":{"type":"string","enum":["ATTEMPTED","FAMILIAR","PROFICIENT","MASTERED"]},"probability":{"type":"number","format":"double"},"lastEventAt":{"type":"string","format":"date-time"},"attemptsCount":{"type":"integer","format":"int32"},"lastEvidenceType":{"type":"string","enum":["GRADE","QUIZ","COURSE","PROJECT","PLACEMENT","CERTIFICATE"]},"freshnessProbability":{"type":"number","format":"double"},"daysSinceLastEvidence":{"type":"integer","format":"int64"},"evidenceRefs":{"type":"object","additionalProperties":{}},"history":{"type":"array","items":{"$ref":"#/components/schemas/ObservationEntry"}}}},"ObservationEntry":{"type":"object","properties":{"source":{"type":"string","enum":["GRADE","QUIZ","COURSE","PLACEMENT","PROJECT","CERTIFICATE"]},"correct":{"type":"number","format":"double"},"total":{"type":"number","format":"double"},"weight":{"type":"number","format":"double"},"observedAt":{"type":"string","format":"date-time"}}},"CareerTrackDto":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"code":{"type":"string"},"name":{"type":"string"},"nameKk":{"type":"string"},"nameEn":{"type":"string"},"description":{"type":"string"},"descriptionKk":{"type":"string"},"descriptionEn":{"type":"string"},"areaCount":{"type":"integer","format":"int32"},"skillCount":{"type":"integer","format":"int32"}}},"MatchCriterionDto":{"type":"object","properties":{"key":{"type":"string"},"nameKk":{"type":"string"},"nameRu":{"type":"string"},"nameEn":{"type":"string"},"academicYear":{"type":"string"},"weight":{"type":"number"}}},"EmploymentSnapshotDto":{"type":"object","properties":{"id":{"type":"string"},"planId":{"type":"string"},"teacherKeycloakId":{"type":"string"},"displayName":{"type":"string"},"position":{"type":"string"},"positionNameKk":{"type":"string"},"positionNameRu":{"type":"string"},"positionNameEn":{"type":"string"},"rate":{"type":"number"},"periodShare":{"type":"number"},"contractType":{"type":"string"},"contractTypeNameKk":{"type":"string"},"contractTypeNameRu":{"type":"string"},"contractTypeNameEn":{"type":"string"},"sourceNote":{"type":"string"},"manuallyEdited":{"type":"boolean"},"languages":{"type":"array","items":{"type":"string"}},"positionTitle":{"type":"string"},"capacityNote":{"$ref":"#/components/schemas/WorkloadLabelDto"}}},"WorkloadLabelDto":{"type":"object","properties":{"code":{"type":"string"},"nameKk":{"type":"string"},"nameRu":{"type":"string"},"nameEn":{"type":"string"}}},"WorkloadDemandLineDto":{"type":"object","properties":{"id":{"type":"string"},"planId":{"type":"string"},"sourceType":{"type":"string"},"sourceTypeNameKk":{"type":"string"},"sourceTypeNameRu":{"type":"string"},"sourceTypeNameEn":{"type":"string"},"courseId":{"type":"string"},"courseCode":{"type":"string"},"disciplineTitle":{"type":"string"},"lessonType":{"type":"string"},"lessonTypeNameKk":{"type":"string"},"lessonTypeNameRu":{"type":"string"},"lessonTypeNameEn":{"type":"string"},"blockType":{"type":"string"},"blockTypeNameKk":{"type":"string"},"blockTypeNameRu":{"type":"string"},"blockTypeNameEn":{"type":"string"},"hoursPerGroup":{"type":"number"},"groupCount":{"type":"integer","format":"int32"},"streamFlag":{"type":"boolean"},"streamGroupCount":{"type":"integer","format":"int32"},"language":{"type":"string"},"totalHours":{"type":"number"},"teacherUserId":{"type":"string"}}},"AllocationLineDto":{"type":"object","properties":{"id":{"type":"string"},"demandLineId":{"type":"string"},"teacher":{"type":"string"},"displayName":{"type":"string"},"sharePct":{"type":"integer","format":"int32"},"hours":{"type":"number"},"overloaded":{"type":"boolean"},"overloadBasis":{"type":"string"},"manual":{"type":"boolean"}}},"ElectiveGroupDto":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"programVersionId":{"type":"string","format":"uuid"},"code":{"type":"string"},"nameKk":{"type":"string"},"nameRu":{"type":"string"},"nameEn":{"type":"string"},"orderIndex":{"type":"integer","format":"int32"},"members":{"type":"array","items":{"$ref":"#/components/schemas/Member"}}}},"Member":{"type":"object","properties":{"disciplineId":{"type":"string","format":"uuid"},"code":{"type":"string"},"nameKk":{"type":"string"},"nameRu":{"type":"string"},"nameEn":{"type":"string"},"credits":{"type":"number"},"trimester":{"type":"integer","format":"int32"},"orderIndex":{"type":"integer","format":"int32"}}},"ActivityHoursDto":{"type":"object","properties":{"lessonType":{"$ref":"#/components/schemas/LabelDto"},"hours":{"type":"number"}}},"CatalogRef":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"code":{"type":"string"},"nameKk":{"type":"string"},"nameRu":{"type":"string"},"nameEn":{"type":"string"},"classifierCode":{"type":"string"},"verified":{"type":"boolean"},"source":{"type":"string"}}},"DisciplineDto":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"programVersionId":{"type":"string","format":"uuid"},"code":{"type":"string"},"classifierCode":{"type":"string"},"nameKk":{"type":"string"},"nameRu":{"type":"string"},"nameEn":{"type":"string"},"descKk":{"type":"string"},"descRu":{"type":"string"},"descEn":{"type":"string"},"credits":{"type":"number"},"cycle":{"$ref":"#/components/schemas/LabelDto"},"component":{"$ref":"#/components/schemas/LabelDto"},"controlForm":{"$ref":"#/components/schemas/LabelDto"},"kind":{"$ref":"#/components/schemas/LabelDto"},"trimester":{"type":"integer","format":"int32"},"trimesterCredits":{"type":"array","items":{"$ref":"#/components/schemas/TrimesterCreditDto"}},"prerequisiteIds":{"type":"array","items":{"type":"string","format":"uuid"}},"postrequisiteIds":{"type":"array","items":{"type":"string","format":"uuid"}},"formedLearningOutcomeIds":{"type":"array","items":{"type":"string","format":"uuid"}},"teachingMethods":{"type":"array","items":{"type":"string"}},"assessmentMethodIds":{"type":"array","items":{"type":"string","format":"uuid"}},"activityHours":{"type":"array","items":{"$ref":"#/components/schemas/ActivityHoursDto"}},"literature":{"type":"string"},"digitalResources":{"type":"string"},"labBase":{"type":"string"},"responsibleTeacherId":{"type":"string","format":"uuid"},"responsibleTeacherKeycloakId":{"type":"string"},"attachedTeacherKeycloakIds":{"type":"array","items":{"type":"string"}},"schoolDepartmentId":{"type":"integer","format":"int64"},"linkedProfessionalTaskIds":{"type":"array","items":{"type":"string","format":"uuid"}},"catalog":{"$ref":"#/components/schemas/CatalogRef"},"electiveGroup":{"$ref":"#/components/schemas/ElectiveGroupRef"},"electiveGroupOrder":{"type":"integer","format":"int32"},"academicYear":{"type":"string"},"instructionLanguages":{"type":"array","items":{"$ref":"#/components/schemas/LabelDto"}},"source":{"type":"string"},"verified":{"type":"boolean"},"createdBy":{"type":"string"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}},"ElectiveGroupRef":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"code":{"type":"string"},"nameKk":{"type":"string"},"nameRu":{"type":"string"},"nameEn":{"type":"string"},"orderIndex":{"type":"integer","format":"int32"}}},"LabelDto":{"type":"object","properties":{"code":{"type":"string"},"nameKk":{"type":"string"},"nameRu":{"type":"string"},"nameEn":{"type":"string"}}},"TrimesterCreditDto":{"type":"object","properties":{"trimester":{"type":"integer","format":"int32"},"credits":{"type":"integer","format":"int32"}}},"Assignment":{"type":"object","properties":{"disciplineCode":{"type":"string","minLength":1},"responsibleTeacherId":{"type":"string","format":"uuid"}},"required":["disciplineCode"]},"CurriculumPlanDto":{"type":"object","properties":{"programVersionId":{"type":"string","format":"uuid"},"academicYear":{"type":"string"},"totalCredits":{"type":"number"},"mandatoryCredits":{"type":"number"},"universityCredits":{"type":"number"},"electiveCredits":{"type":"number"},"trimesterLayout":{"type":"object","additionalProperties":{"type":"integer","format":"int32"}},"trimesterCredits":{"type":"object","additionalProperties":{"type":"number"}},"trimesterCreditsStudent":{"type":"object","additionalProperties":{"type":"number"}},"warnings":{"type":"array","items":{"type":"string"}}}},"SyllabusApproverChainDto":{"type":"object","properties":{"schoolDepartmentId":{"type":"integer","format":"int64"},"schoolName":{"type":"string"},"inherited":{"type":"boolean"},"customized":{"type":"boolean"},"steps":{"type":"array","items":{"$ref":"#/components/schemas/SyllabusApproverStepDto"}},"acting":{"$ref":"#/components/schemas/LabelDto"},"explanation":{"$ref":"#/components/schemas/LabelDto"},"availableFunctions":{"type":"array","items":{"$ref":"#/components/schemas/LabelDto"}},"updatedAt":{"type":"string","format":"date-time"},"updatedBy":{"type":"string"}}},"SyllabusApproverStepDto":{"type":"object","properties":{"position":{"type":"integer","format":"int32"},"function":{"$ref":"#/components/schemas/LabelDto"},"hasCarrier":{"type":"boolean"}}},"CriterionDto":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"ordinal":{"type":"integer","format":"int32"},"titleRu":{"type":"string"},"titleKk":{"type":"string"},"titleEn":{"type":"string"},"shortLabelRu":{"type":"string"},"shortLabelKk":{"type":"string"},"shortLabelEn":{"type":"string"},"indicators":{"type":"array","items":{"$ref":"#/components/schemas/IndicatorDto"}},"levels":{"type":"array","items":{"$ref":"#/components/schemas/LevelDto"}}}},"IndicatorDto":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"ordinalLabel":{"type":"string"},"leadRu":{"type":"string"},"leadKk":{"type":"string"},"leadEn":{"type":"string"},"statementRu":{"type":"string"},"statementKk":{"type":"string"},"statementEn":{"type":"string"}}},"LevelDto":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"level":{"type":"string"},"textRu":{"type":"string"},"textKk":{"type":"string"},"textEn":{"type":"string"}}},"RubricTemplateRefDto":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"code":{"type":"string"},"titleRu":{"type":"string"},"titleKk":{"type":"string"},"titleEn":{"type":"string"},"introRu":{"type":"string"},"introKk":{"type":"string"},"introEn":{"type":"string"},"revisionNo":{"type":"integer","format":"int32"},"active":{"type":"boolean"},"createdBy":{"type":"string"},"criteria":{"type":"array","items":{"$ref":"#/components/schemas/CriterionDto"}}}},"AssessmentPeriodRefDto":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"code":{"type":"string"},"name":{"$ref":"#/components/schemas/LabelDto"},"defaultWeightPct":{"type":"string"},"capPoints":{"type":"string"},"examPeriod":{"type":"boolean"},"sortOrder":{"type":"integer","format":"int32"},"active":{"type":"boolean"}}},"AssessmentFormRefDto":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"code":{"type":"string"},"name":{"$ref":"#/components/schemas/LabelDto"},"sortOrder":{"type":"integer","format":"int32"},"active":{"type":"boolean"}}},"HoursCompareDto":{"type":"object","properties":{"lessonType":{"$ref":"#/components/schemas/LabelDto"},"planned":{"type":"string"},"passport":{"type":"string"},"matches":{"type":"boolean"}}},"ValidationFindingDto":{"type":"object","properties":{"severity":{"type":"string","enum":["CRITICAL","SUBSTANTIAL","RECOMMENDATIONAL"]},"severityNameKk":{"type":"string"},"severityNameRu":{"type":"string"},"severityNameEn":{"type":"string"},"code":{"type":"string","enum":["NO_OUTCOMES","OUTCOME_NOT_LINKED_TO_PLO","ASSESSMENT_WEIGHTS_NOT_100","PERIOD_POINTS_NOT_CAP","NO_EXAM_ITEM","ASSIGNMENT_NO_AIUSELEVEL","NO_APPROVAL_ROUTE","PLO_SNAPSHOT_EMPTY","WEAK_OUTCOME_VERB","OUTCOME_COUNT_OUT_OF_RANGE","WEEK_HOURS_MISMATCH","SIS_HOURS_MISMATCH","MUSEUM_HOURS_MISMATCH","ASSESSMENT_CONCENTRATION","UNVERIFIED_LITERATURE","INCOMPLETE_RUBRIC","ASSIGNMENT_RUBRIC_EMPTY","PASSPORT_INCOMPLETE","SOCIAL_COMPETENCE_EMPTY","EXAM_SPEC_INCOMPLETE","SECTION_INCOMPLETE","AI_ADVISORY"]},"message":{"type":"string"},"messageKk":{"type":"string"},"messageRu":{"type":"string"},"messageEn":{"type":"string"},"entityRef":{"type":"string"},"source":{"type":"string","enum":["RULE","AI"]}}},"WeekDto":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"weekNo":{"type":"integer","format":"int32"},"lectureTopic":{"type":"string"},"lectureTopicExtra":{"type":"string"},"outcomeIds":{"type":"array","items":{"type":"string","format":"uuid"}},"hours":{"type":"array","items":{"$ref":"#/components/schemas/WeekHoursDto"}},"seminar":{"$ref":"#/components/schemas/WeekSeminarDto"},"sisTasks":{"type":"array","items":{"$ref":"#/components/schemas/WeekSisTaskDto"}},"events":{"type":"array","items":{"$ref":"#/components/schemas/WeekEventDto"}}}},"WeekEventDto":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"eventType":{"$ref":"#/components/schemas/LabelDto"},"title":{"type":"string"},"hours":{"type":"string"},"description":{"type":"string"},"reportForm":{"type":"string"},"weekFrom":{"type":"integer","format":"int32"},"weekTo":{"type":"integer","format":"int32"},"sortOrder":{"type":"integer","format":"int32"}}},"WeekHoursDto":{"type":"object","properties":{"lessonType":{"$ref":"#/components/schemas/LabelDto"},"hours":{"type":"string"}}},"WeekPlanSetDto":{"type":"object","properties":{"weeks":{"type":"array","items":{"$ref":"#/components/schemas/WeekDto"}},"hoursByLessonType":{"type":"array","items":{"$ref":"#/components/schemas/HoursCompareDto"}},"museumHoursPlanned":{"type":"string"},"museumHoursRequired":{"type":"string"},"museumMatches":{"type":"boolean"},"weeksTotal":{"type":"integer","format":"int32"},"findings":{"type":"array","items":{"$ref":"#/components/schemas/ValidationFindingDto"}}}},"WeekReadingDto":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"kind":{"$ref":"#/components/schemas/LabelDto"},"literatureId":{"type":"string","format":"uuid"},"citation":{"type":"string"},"url":{"type":"string"},"sortOrder":{"type":"integer","format":"int32"}}},"WeekSeminarDto":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"topic":{"type":"string"},"hours":{"type":"string"},"subtopics":{"type":"array","items":{"type":"string"}},"readings":{"type":"array","items":{"$ref":"#/components/schemas/WeekReadingDto"}},"submissionForm":{"type":"string"},"deadlineRule":{"type":"string"}}},"WeekSisTaskDto":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"title":{"type":"string"},"hours":{"type":"string"},"subtopics":{"type":"array","items":{"type":"string"}},"readings":{"type":"array","items":{"$ref":"#/components/schemas/WeekReadingDto"}},"submissionForm":{"type":"string"},"deadlineRule":{"type":"string"},"appearsInExam":{"type":"boolean"},"sortOrder":{"type":"integer","format":"int32"}}},"DigitalToolDto":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"versionId":{"type":"string","format":"uuid"},"name":{"type":"string"},"purpose":{"type":"string"},"url":{"type":"string"}}},"TeachingMethodRefDto":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"versionId":{"type":"string","format":"uuid"},"methodCode":{"type":"string"},"rationale":{"type":"string"}}},"SyllabusSectionDto":{"type":"object","properties":{"sectionKey":{"$ref":"#/components/schemas/LabelDto"},"content":{"type":"object","additionalProperties":{}},"complete":{"type":"boolean"},"source":{"type":"string"},"sortOrder":{"type":"integer","format":"int32"},"mandatory":{"type":"boolean"},"freeText":{"type":"boolean"},"autoComplete":{"type":"boolean"}}},"CourseRubricDto":{"type":"object","properties":{"templateCode":{"type":"string"},"intro":{"type":"string"},"levels":{"type":"array","items":{"$ref":"#/components/schemas/LevelHeaderDto"}},"criteria":{"type":"array","items":{"$ref":"#/components/schemas/CriterionDto"}}}},"LevelHeaderDto":{"type":"object","properties":{"level":{"type":"string"},"label":{"type":"string"},"letterLabel":{"type":"string"},"band":{"type":"string"}}},"LevelTextDto":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"level":{"type":"string"},"text":{"type":"string"}}},"HoursRow":{"type":"object","properties":{"lessonType":{"$ref":"#/components/schemas/LabelDto"},"hours":{"type":"string"}}},"Lecturer":{"type":"object","properties":{"fullName":{"type":"string"},"shortName":{"type":"string"},"degree":{"type":"string"},"academicTitle":{"type":"string"},"email":{"type":"string"},"office":{"type":"string"},"university":{"type":"string"}}},"SyllabusPassportDto":{"type":"object","properties":{"courseCode":{"type":"string"},"classifierCode":{"type":"string"},"courseCodeDisplay":{"type":"string"},"title":{"type":"string"},"titleRu":{"type":"string"},"titleKk":{"type":"string"},"titleEn":{"type":"string"},"degreeLevel":{"type":"string"},"cycle":{"$ref":"#/components/schemas/LabelDto"},"component":{"$ref":"#/components/schemas/LabelDto"},"programName":{"type":"string"},"yearOfStudy":{"type":"integer","format":"int32"},"trimester":{"type":"integer","format":"int32"},"yearTrimesterLabel":{"type":"string"},"language":{"$ref":"#/components/schemas/LabelDto"},"credits":{"type":"string"},"totalHours":{"type":"string"},"academicYear":{"type":"string"},"hours":{"type":"array","items":{"$ref":"#/components/schemas/HoursRow"}},"prerequisitesAuto":{"type":"string"},"prerequisitesExtra":{"type":"string"},"postrequisitesAuto":{"type":"string"},"postrequisitesExtra":{"type":"string"},"lecturer":{"$ref":"#/components/schemas/Lecturer"},"refreshedAt":{"type":"string"},"refreshIncomplete":{"type":"boolean"}}},"DisciplineOutcomeDto":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"versionId":{"type":"string","format":"uuid"},"code":{"type":"string"},"statement":{"type":"string"},"bloomLevel":{"type":"string"},"action":{"type":"string"},"object":{"type":"string"},"condition":{"type":"string"},"qualityCriterion":{"type":"string"},"mapsToProgramOutcomeRefIds":{"type":"array","items":{"type":"string","format":"uuid"}}}},"LiteratureSourceDto":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"versionId":{"type":"string","format":"uuid"},"citation":{"type":"string"},"url":{"type":"string"},"primary":{"type":"boolean"},"linkVerified":{"type":"boolean"},"sortOrder":{"type":"integer","format":"int32"},"ordinal":{"type":"integer","format":"int32"}}},"CourseParametersDefaultsDto":{"type":"object","properties":{"attendanceMinPct":{"type":"integer","format":"int32"},"admissionAttendancePct":{"type":"integer","format":"int32"},"weeksPerTrimester":{"type":"integer","format":"int32"}}},"CourseParametersDto":{"type":"object","properties":{"midtermAdmissionMinPoints":{"type":"integer","format":"int32"},"attendanceMinPct":{"type":"integer","format":"int32"},"examFormat":{"type":"string"},"examFormatLabel":{"$ref":"#/components/schemas/LabelDto"},"examQuestionCount":{"type":"integer","format":"int32"},"examDurationMin":{"type":"integer","format":"int32"},"examPlatform":{"type":"string"},"examLanguage":{"type":"string"},"mandatoryMuseumHours":{"type":"string"},"communicationChannel":{"type":"string"},"aiMode":{"type":"string"},"aiModeLabel":{"$ref":"#/components/schemas/LabelDto"},"officeHours":{"type":"string"},"socialCompetences":{"type":"array","items":{"$ref":"#/components/schemas/SocialCompetenceDto"}},"defaults":{"$ref":"#/components/schemas/CourseParametersDefaultsDto"}}},"SocialCompetenceDto":{"type":"object","properties":{"criterionId":{"type":"string","format":"uuid"},"ordinal":{"type":"integer","format":"int32"},"title":{"type":"string"}}},"AssignmentTemplateDto":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"versionId":{"type":"string","format":"uuid"},"title":{"type":"string"},"type":{"$ref":"#/components/schemas/LabelTriple"},"aiUseLevel":{"type":"string"},"integrityColor":{"type":"string"},"integrityCheckStatus":{"type":"string"},"integrityCheckNote":{"type":"string"},"weight":{"type":"number"},"deadlineRule":{"type":"string"},"isTeam":{"type":"boolean"},"checkedOutcomeRefIds":{"type":"array","items":{"type":"string","format":"uuid"}},"requiresPlagiarismCheck":{"type":"boolean"},"requiresProctoring":{"type":"boolean"},"requiresRepository":{"type":"boolean"}}},"LabelTriple":{"type":"object","properties":{"code":{"type":"string"},"nameKk":{"type":"string"},"nameRu":{"type":"string"},"nameEn":{"type":"string"}}},"AssignmentRubricDto":{"type":"object","properties":{"assignmentId":{"type":"string","format":"uuid"},"maxScore":{"type":"string"},"items":{"type":"array","items":{"$ref":"#/components/schemas/ItemDto"}}}},"ItemDto":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"criterionId":{"type":"string","format":"uuid"},"ordinal":{"type":"integer","format":"int32"},"title":{"type":"string"},"maxPoints":{"type":"string"},"sortOrder":{"type":"integer","format":"int32"},"indicators":{"type":"array","items":{"$ref":"#/components/schemas/IndicatorDto"}},"levels":{"type":"array","items":{"$ref":"#/components/schemas/LevelTextDto"}}}},"AssessmentSetDto":{"type":"object","properties":{"periods":{"type":"array","items":{"$ref":"#/components/schemas/PeriodDto"}},"totalWeightPct":{"type":"string"},"formulaText":{"type":"string"},"formulaTextShort":{"type":"string"},"formsUsed":{"type":"array","items":{"type":"string"}},"findings":{"type":"array","items":{"$ref":"#/components/schemas/ValidationFindingDto"}}}},"ACADEMIC_GroupDto":{"type":"object","properties":{"label":{"type":"string"},"subtotal":{"type":"string"}}},"PeriodDto":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"periodCode":{"type":"string"},"name":{"$ref":"#/components/schemas/LabelDto"},"weightPct":{"type":"string"},"capPoints":{"type":"string"},"examPeriod":{"type":"boolean"},"minRequirement":{"type":"string"},"retakePolicy":{"type":"string"},"sortOrder":{"type":"integer","format":"int32"},"itemsPointsSum":{"type":"string"},"groups":{"type":"array","items":{"$ref":"#/components/schemas/ACADEMIC_GroupDto"}},"items":{"type":"array","items":{"$ref":"#/components/schemas/ItemDto"}}}},"ProgramDto":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"code":{"type":"string"},"nameKk":{"type":"string"},"nameRu":{"type":"string"},"nameEn":{"type":"string"},"shortTitle":{"type":"string"},"qualificationLevel":{"type":"string"},"educationArea":{"type":"string"},"directionCode":{"type":"string"},"programGroup":{"type":"string"},"mskoLevel":{"type":"string"},"nrkLevel":{"type":"string"},"orkLevel":{"type":"string"},"degreeAwarded":{"type":"string"},"schoolDepartmentId":{"type":"integer","format":"int64"},"academicYearFrom":{"type":"string"},"currentVersionId":{"type":"string","format":"uuid"},"draftVersionId":{"type":"string","format":"uuid"},"createdBy":{"type":"string"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"},"currentVersionStatus":{"$ref":"#/components/schemas/LabelDto"},"currentPublicationStatus":{"type":"string"}}},"CatalogDisciplineDto":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"code":{"type":"string"},"nameKk":{"type":"string"},"nameRu":{"type":"string"},"nameEn":{"type":"string"},"classifierCode":{"type":"string"},"descKk":{"type":"string"},"descRu":{"type":"string"},"descEn":{"type":"string"},"degree":{"$ref":"#/components/schemas/LabelDto"},"academicYear":{"type":"string"},"courseYear":{"type":"integer","format":"int32"},"programIds":{"type":"array","items":{"type":"string","format":"uuid"}},"source":{"type":"string"},"verified":{"type":"boolean"},"createdBy":{"type":"string"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}},"AssessmentMethodDto":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"code":{"type":"string"},"nameKk":{"type":"string"},"nameRu":{"type":"string"},"nameEn":{"type":"string"},"type":{"$ref":"#/components/schemas/LabelDto"},"createdBy":{"type":"string"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}},"ApprovalRouteDto":{"type":"object","properties":{"route":{"$ref":"#/components/schemas/LabelDto"},"returnPolicy":{"$ref":"#/components/schemas/LabelDto"},"returnPolicies":{"type":"array","items":{"$ref":"#/components/schemas/LabelDto"}},"steps":{"type":"array","items":{"$ref":"#/components/schemas/ApprovalRouteStepDto"}},"stepsSettingPath":{"type":"string"},"availableFunctions":{"type":"array","items":{"$ref":"#/components/schemas/LabelDto"}},"customized":{"type":"boolean"},"updatedAt":{"type":"string","format":"date-time"},"updatedBy":{"type":"string"}}},"ApprovalRouteStepDto":{"type":"object","properties":{"step":{"$ref":"#/components/schemas/LabelDto"},"approvers":{"type":"array","items":{"$ref":"#/components/schemas/ApprovalStepFunctionDto"}},"acting":{"$ref":"#/components/schemas/LabelDto"},"customized":{"type":"boolean"},"updatedAt":{"type":"string","format":"date-time"},"updatedBy":{"type":"string"}}},"ApprovalStepFunctionDto":{"type":"object","properties":{"position":{"type":"integer","format":"int32"},"function":{"$ref":"#/components/schemas/LabelDto"},"hasCarrier":{"type":"boolean"}}},"WorkloadPlanDto":{"type":"object","properties":{"id":{"type":"string"},"academicYear":{"type":"string"},"schoolDepartmentId":{"type":"integer","format":"int64"},"status":{"type":"string"},"statusNameKk":{"type":"string"},"statusNameRu":{"type":"string"},"statusNameEn":{"type":"string"},"optimizationGoal":{"type":"string"}}},"WorkloadApprovalTransitionDto":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"fromStatus":{"$ref":"#/components/schemas/WorkloadLabelDto"},"toStatus":{"$ref":"#/components/schemas/WorkloadLabelDto"},"action":{"$ref":"#/components/schemas/WorkloadLabelDto"},"actorUserId":{"type":"string"},"actorFunction":{"$ref":"#/components/schemas/WorkloadLabelDto"},"comment":{"type":"string"},"occurredAt":{"type":"string","format":"date-time"}}},"WorkloadWorkflowActionDto":{"type":"object","properties":{"action":{"$ref":"#/components/schemas/WorkloadLabelDto"},"toStatus":{"$ref":"#/components/schemas/WorkloadLabelDto"},"requiredFunction":{"$ref":"#/components/schemas/WorkloadLabelDto"},"commentRequired":{"type":"boolean"},"allowedForMe":{"type":"boolean"}}},"WorkloadWorkflowStateDto":{"type":"object","properties":{"planId":{"type":"string","format":"uuid"},"schoolDepartmentId":{"type":"integer","format":"int64"},"currentStatus":{"$ref":"#/components/schemas/WorkloadLabelDto"},"availableActions":{"type":"array","items":{"$ref":"#/components/schemas/WorkloadWorkflowActionDto"}},"history":{"type":"array","items":{"$ref":"#/components/schemas/WorkloadApprovalTransitionDto"}}}},"CapacityPerBlockDto":{"type":"object","properties":{"blockType":{"type":"string"},"blockTypeNameKk":{"type":"string"},"blockTypeNameRu":{"type":"string"},"blockTypeNameEn":{"type":"string"},"target":{"type":"number"},"assigned":{"type":"number"},"available":{"type":"number"}}},"CapacityRecordDto":{"type":"object","properties":{"id":{"type":"string"},"planId":{"type":"string"},"teacherKeycloakId":{"type":"string"},"displayName":{"type":"string"},"totalCapacity":{"type":"number"},"perBlock":{"type":"array","items":{"$ref":"#/components/schemas/CapacityPerBlockDto"}},"contractType":{"type":"string"},"contractTypeNameKk":{"type":"string"},"contractTypeNameRu":{"type":"string"},"contractTypeNameEn":{"type":"string"},"rate":{"type":"number"},"note":{"$ref":"#/components/schemas/WorkloadLabelDto"}}},"AppealDto":{"type":"object","properties":{"id":{"type":"string"},"planId":{"type":"string"},"teacherKeycloakId":{"type":"string"},"teacherDisplayName":{"type":"string"},"allocationLineId":{"type":"string"},"text":{"type":"string"},"status":{"type":"string"},"statusNameKk":{"type":"string"},"statusNameRu":{"type":"string"},"statusNameEn":{"type":"string"},"decisionComment":{"type":"string"},"decidedByKeycloakId":{"type":"string"},"decidedAt":{"type":"string","format":"date-time"},"createdAt":{"type":"string","format":"date-time"}}},"UnassignedLineDto":{"type":"object","properties":{"lineId":{"type":"string"},"disciplineTitle":{"type":"string"},"lessonType":{"type":"string"},"totalHours":{"type":"number"},"reason":{"type":"string"},"reasonNameKk":{"type":"string"},"reasonNameRu":{"type":"string"},"reasonNameEn":{"type":"string"}}},"NumbersRequest":{"type":"object","properties":{"expectedAttendancePct":{"type":"integer","format":"int32","maximum":1000,"minimum":0},"maxMissedPct":{"type":"integer","format":"int32","maximum":1000,"minimum":0},"admissionAttendancePct":{"type":"integer","format":"int32","maximum":1000,"minimum":0},"latenessMinutes":{"type":"integer","format":"int32","maximum":1000,"minimum":0},"latenessCountAsAbsence":{"type":"integer","format":"int32","maximum":1000,"minimum":0},"lateSubmissionPenaltyPctPerDay":{"type":"integer","format":"int32","maximum":1000,"minimum":0},"lateSubmissionMaxDays":{"type":"integer","format":"int32","maximum":1000,"minimum":0},"excuseDocumentDays":{"type":"integer","format":"int32","maximum":1000,"minimum":0},"instructorResponseWorkingDays":{"type":"integer","format":"int32","maximum":1000,"minimum":0},"inPersonLessonMin":{"type":"integer","format":"int32","maximum":1000,"minimum":0},"onlineLessonMin":{"type":"integer","format":"int32","maximum":1000,"minimum":0},"examArriveEarlyMin":{"type":"integer","format":"int32","maximum":1000,"minimum":0},"gradeAnnulmentDays":{"type":"integer","format":"int32","maximum":1000,"minimum":0},"weeksPerTrimester":{"type":"integer","format":"int32","maximum":30,"minimum":1}},"required":["admissionAttendancePct","examArriveEarlyMin","excuseDocumentDays","expectedAttendancePct","gradeAnnulmentDays","inPersonLessonMin","instructorResponseWorkingDays","lateSubmissionMaxDays","lateSubmissionPenaltyPctPerDay","latenessCountAsAbsence","latenessMinutes","maxMissedPct","onlineLessonMin","weeksPerTrimester"]},"TextsDto":{"type":"object","properties":{"integrity":{"$ref":"#/components/schemas/TripleDto"},"honorCode":{"$ref":"#/components/schemas/TripleDto"},"genaiPolicy":{"$ref":"#/components/schemas/TripleDto"},"technology":{"$ref":"#/components/schemas/TripleDto"},"instructorCommunication":{"$ref":"#/components/schemas/TripleDto"},"policyPresence":{"$ref":"#/components/schemas/TripleDto"},"policyAbsences":{"$ref":"#/components/schemas/TripleDto"},"policyPreparation":{"$ref":"#/components/schemas/TripleDto"},"policyConduct":{"$ref":"#/components/schemas/TripleDto"},"policyPunctuality":{"$ref":"#/components/schemas/TripleDto"},"policyDeadlines":{"$ref":"#/components/schemas/TripleDto"},"examProcedures":{"$ref":"#/components/schemas/TripleDto"},"privacy":{"$ref":"#/components/schemas/TripleDto"},"courseScheduleStatement":{"$ref":"#/components/schemas/TripleDto"},"inclusionStatement":{"$ref":"#/components/schemas/TripleDto"},"assessmentMethodology":{"$ref":"#/components/schemas/TripleDto"},"courseworkIntro":{"$ref":"#/components/schemas/TripleDto"}},"required":["assessmentMethodology","courseScheduleStatement","courseworkIntro","examProcedures","genaiPolicy","honorCode","inclusionStatement","instructorCommunication","integrity","policyAbsences","policyConduct","policyDeadlines","policyPreparation","policyPresence","policyPunctuality","privacy","technology"]},"TripleDto":{"type":"object","properties":{"ru":{"type":"string","minLength":1},"kk":{"type":"string","minLength":1},"en":{"type":"string","minLength":1}},"required":["en","kk","ru"]},"AbbreviationAdminDto":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"code":{"type":"string"},"meaningRu":{"type":"string"},"meaningKk":{"type":"string"},"meaningEn":{"type":"string"},"sortOrder":{"type":"integer","format":"int32"}}},"PolicyDefaultsAdminDto":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"revisionNo":{"type":"integer","format":"int32"},"active":{"type":"boolean"},"origin":{"type":"string"},"effectiveFrom":{"type":"string","format":"date"},"createdAt":{"type":"string","format":"date-time"},"createdBy":{"type":"string"},"texts":{"$ref":"#/components/schemas/TextsDto"},"numbers":{"$ref":"#/components/schemas/NumbersRequest"},"abbreviations":{"type":"array","items":{"$ref":"#/components/schemas/AbbreviationAdminDto"}}}},"SyllabusDto":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"disciplineId":{"type":"string","format":"uuid"},"programVersionId":{"type":"string","format":"uuid"},"programId":{"type":"string","format":"uuid"},"courseCode":{"type":"string"},"courseId":{"type":"string","format":"uuid"},"courseIds":{"type":"array","items":{"type":"string","format":"uuid"}},"responsibleTeacherUserId":{"type":"string","format":"uuid"},"responsibleTeacherKeycloakId":{"type":"string"},"currentStatus":{"$ref":"#/components/schemas/LabelDto"},"publicationStatus":{"$ref":"#/components/schemas/LabelDto"},"schoolDepartmentId":{"type":"integer","format":"int64"},"activeVersionId":{"type":"string","format":"uuid"},"activeVersionNo":{"type":"integer","format":"int32"},"activeVersionImmutable":{"type":"boolean"},"activeVersionSource":{"type":"string"},"language":{"$ref":"#/components/schemas/LabelDto"},"sections":{"type":"array","items":{"$ref":"#/components/schemas/SyllabusSectionDto"}},"sourceFile":{"$ref":"#/components/schemas/SyllabusImportSourceFileDto"},"titleDiverged":{"type":"boolean"},"createdBy":{"type":"string"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}},"SyllabusImportSourceFileDto":{"type":"object","properties":{"fileId":{"type":"string","format":"uuid"},"filename":{"type":"string"},"sizeBytes":{"type":"integer","format":"int64"},"mimeType":{"type":"string"},"uploadedAt":{"type":"string","format":"date-time"},"pageCount":{"type":"integer","format":"int32"},"structureSource":{"$ref":"#/components/schemas/LabelDto"},"documentLanguage":{"$ref":"#/components/schemas/LabelDto"}}},"SyllabusImportRunDto":{"type":"object","properties":{"runId":{"type":"string","format":"uuid"},"syllabusId":{"type":"string","format":"uuid"},"syllabusVersionId":{"type":"string","format":"uuid"},"status":{"$ref":"#/components/schemas/LabelDto"},"stage":{"$ref":"#/components/schemas/LabelDto"},"percent":{"type":"integer","format":"int32"},"sectionsDone":{"type":"integer","format":"int32"},"sectionsTotal":{"type":"integer","format":"int32"},"etaSeconds":{"type":"integer","format":"int32"},"elapsedSeconds":{"type":"integer","format":"int32"},"startedAt":{"type":"string","format":"date-time"},"finishedAt":{"type":"string","format":"date-time"},"errorCode":{"type":"string"},"message":{"type":"string"},"retryable":{"type":"boolean"},"partial":{"type":"boolean"},"dismissed":{"type":"boolean"},"dismissedAt":{"type":"string","format":"date-time"},"appliedSections":{"type":"array","items":{"$ref":"#/components/schemas/LabelDto"}},"documentSections":{"type":"array","items":{"$ref":"#/components/schemas/LabelDto"}},"sectionsDoneKeys":{"type":"array","items":{"type":"string"}},"currentSectionKey":{"type":"string"},"aiCallCount":{"type":"integer","format":"int32"},"sourceFile":{"$ref":"#/components/schemas/SyllabusImportSourceFileDto"}}},"AlternativeDto":{"type":"object","properties":{"value":{},"evidence":{"$ref":"#/components/schemas/SyllabusImportEvidenceDto"}}},"ColumnDto":{"type":"object","properties":{"key":{"type":"string"},"header":{"$ref":"#/components/schemas/LabelDto"},"numeric":{"type":"boolean"}}},"ACADEMIC_RowDto":{"type":"object","properties":{"rowPath":{"type":"string"},"status":{"type":"string"},"cells":{"type":"object","additionalProperties":{"type":"string"}},"leafPaths":{"type":"array","items":{"type":"string"}}}},"SyllabusImportCollectionDto":{"type":"object","properties":{"rootPath":{"type":"string"},"columns":{"type":"array","items":{"$ref":"#/components/schemas/ColumnDto"}},"rows":{"type":"array","items":{"$ref":"#/components/schemas/ACADEMIC_RowDto"}}}},"SyllabusImportConflictDto":{"type":"object","properties":{"valueFromReference":{"type":"string"},"valueFromFile":{"type":"string"},"message":{"type":"string"}}},"SyllabusImportDecisionDto":{"type":"object","properties":{"decision":{"type":"string"},"value":{},"savedAt":{"type":"string","format":"date-time"}}},"SyllabusImportEvidenceDto":{"type":"object","properties":{"quote":{"type":"string"},"page":{"type":"integer","format":"int32"},"fromTable":{"type":"boolean"},"quoteVerified":{"type":"boolean"}}},"SyllabusImportFieldDto":{"type":"object","properties":{"path":{"type":"string"},"label":{"$ref":"#/components/schemas/LabelDto"},"kind":{"type":"string"},"unit":{"$ref":"#/components/schemas/LabelDto"},"status":{"type":"string"},"reasonCode":{"type":"string"},"value":{},"valueLabel":{"type":"string"},"alternatives":{"type":"array","items":{"$ref":"#/components/schemas/AlternativeDto"}},"currentValue":{},"overwrites":{"type":"boolean"},"editable":{"type":"boolean"},"referenceKey":{"type":"string"},"conflict":{"$ref":"#/components/schemas/SyllabusImportConflictDto"},"evidence":{"$ref":"#/components/schemas/SyllabusImportEvidenceDto"},"decision":{"$ref":"#/components/schemas/SyllabusImportDecisionDto"}}},"SyllabusImportSectionDto":{"type":"object","properties":{"sectionKey":{"$ref":"#/components/schemas/LabelDto"},"status":{"$ref":"#/components/schemas/LabelDto"},"reasonCode":{"type":"string"},"foundCount":{"type":"integer","format":"int32"},"uncertainCount":{"type":"integer","format":"int32"},"notFoundCount":{"type":"integer","format":"int32"},"readOnly":{"type":"boolean"},"alreadyFilled":{"type":"boolean"},"appliedAt":{"type":"string","format":"date-time"},"fields":{"type":"array","items":{"$ref":"#/components/schemas/SyllabusImportFieldDto"}},"collections":{"type":"array","items":{"$ref":"#/components/schemas/SyllabusImportCollectionDto"}}}},"SyllabusValidationDto":{"type":"object","properties":{"hasCritical":{"type":"boolean"},"criticalCount":{"type":"integer","format":"int32"},"substantialCount":{"type":"integer","format":"int32"},"recommendationalCount":{"type":"integer","format":"int32"},"findings":{"type":"array","items":{"$ref":"#/components/schemas/ValidationFindingDto"}}}},"CommitteeMembershipDto":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"keycloakUserId":{"type":"string","format":"uuid"},"function":{"$ref":"#/components/schemas/LabelDto"},"schoolDepartmentId":{"type":"integer","format":"int64"},"schoolDepartmentName":{"type":"string"}}},"CatalogDisciplineTeacherDto":{"type":"object","properties":{"teacherKeycloakId":{"type":"string"},"attachedAt":{"type":"string","format":"date-time"},"source":{"type":"string"}}},"AiPromptJournalEntryDto":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"syllabusVersionId":{"type":"string","format":"uuid"},"runId":{"type":"string","format":"uuid"},"userId":{"type":"string"},"role":{"type":"string"},"occurredAt":{"type":"string","format":"date-time"},"sectionKey":{"$ref":"#/components/schemas/LabelTriple"},"action":{"$ref":"#/components/schemas/LabelTriple"},"prompt":{"type":"string"},"aiModel":{"type":"string"},"aiResponseRef":{"type":"string"},"userAction":{"$ref":"#/components/schemas/LabelTriple"},"finalText":{"type":"string"},"confidentiality":{"$ref":"#/components/schemas/LabelTriple"}}},"BlockShareDto":{"type":"object","properties":{"block":{"type":"string"},"blockNameKk":{"type":"string"},"blockNameRu":{"type":"string"},"blockNameEn":{"type":"string"},"sharePct":{"type":"integer","format":"int32"}}},"FacultyPositionProfileDto":{"type":"object","properties":{"position":{"type":"string"},"positionNameKk":{"type":"string"},"positionNameRu":{"type":"string"},"positionNameEn":{"type":"string"},"academicYear":{"type":"string"},"blockShares":{"type":"array","items":{"$ref":"#/components/schemas/BlockShareDto"}},"sumShares":{"type":"integer","format":"int32"},"lectureAllowed":{"type":"boolean"}}},"WorkloadFindingDto":{"type":"object","properties":{"severity":{"type":"string","enum":["CRITICAL","SUBSTANTIAL"]},"severityNameKk":{"type":"string"},"severityNameRu":{"type":"string"},"severityNameEn":{"type":"string"},"code":{"type":"string"},"codeNameKk":{"type":"string"},"codeNameRu":{"type":"string"},"codeNameEn":{"type":"string"},"message":{"type":"string"},"entityRef":{"type":"string"}}},"WorkloadValidationDto":{"type":"object","properties":{"hasCritical":{"type":"boolean"},"criticalCount":{"type":"integer","format":"int32"},"substantialCount":{"type":"integer","format":"int32"},"findings":{"type":"array","items":{"$ref":"#/components/schemas/WorkloadFindingDto"}}}},"MyWorkloadSheetDto":{"type":"object","properties":{"planId":{"type":"string"},"planStatus":{"type":"string"},"planStatusNameKk":{"type":"string"},"planStatusNameRu":{"type":"string"},"planStatusNameEn":{"type":"string"},"blocks":{"type":"array","items":{"$ref":"#/components/schemas/SheetBlockDto"}},"totalHours":{"type":"number"},"capacityTotal":{"type":"number"},"capacityPerBlock":{"type":"array","items":{"$ref":"#/components/schemas/CapacityPerBlockDto"}},"appeals":{"type":"array","items":{"$ref":"#/components/schemas/AppealDto"}}}},"SheetAllocationDto":{"type":"object","properties":{"allocationId":{"type":"string"},"demandLineId":{"type":"string"},"courseCode":{"type":"string"},"disciplineTitle":{"type":"string"},"lessonType":{"type":"string"},"lessonTypeNameKk":{"type":"string"},"lessonTypeNameRu":{"type":"string"},"lessonTypeNameEn":{"type":"string"},"hours":{"type":"number"},"sharePct":{"type":"integer","format":"int32"},"overloadBasis":{"type":"string"}}},"SheetBlockDto":{"type":"object","properties":{"blockType":{"type":"string"},"blockTypeNameKk":{"type":"string"},"blockTypeNameRu":{"type":"string"},"blockTypeNameEn":{"type":"string"},"allocations":{"type":"array","items":{"$ref":"#/components/schemas/SheetAllocationDto"}},"totalHours":{"type":"number"}}},"EligibilityCodeDto":{"type":"object","properties":{"code":{"type":"string"},"nameKk":{"type":"string"},"nameRu":{"type":"string"},"nameEn":{"type":"string"}}},"MatrixCandidateDto":{"type":"object","properties":{"teacher":{"type":"string"},"displayName":{"type":"string"},"eligible":{"type":"boolean"},"rejectionCodes":{"type":"array","items":{"$ref":"#/components/schemas/EligibilityCodeDto"}},"score":{"type":"number"},"components":{"type":"array","items":{"$ref":"#/components/schemas/ScoreComponentDto"}}}},"MatrixDto":{"type":"object","properties":{"line":{"$ref":"#/components/schemas/WorkloadDemandLineDto"},"candidates":{"type":"array","items":{"$ref":"#/components/schemas/MatrixCandidateDto"}},"scored":{"type":"boolean"},"notice":{"$ref":"#/components/schemas/WorkloadLabelDto"}}},"ScoreComponentDto":{"type":"object","properties":{"criterion":{"type":"string"},"criterionNameKk":{"type":"string"},"criterionNameRu":{"type":"string"},"criterionNameEn":{"type":"string"},"weightUsed":{"type":"number"},"value":{"type":"number"},"explanation":{"type":"string"}}},"Block":{"type":"object","properties":{"blockType":{"type":"string","enum":["TEACHING","EDU_METHODICAL","RESEARCH","ORG_METHODICAL","SOCIAL_EDUCATIONAL","PROF_DEVELOPMENT"]},"allocations":{"type":"array","items":{"$ref":"#/components/schemas/Assignment"}},"totalHours":{"type":"number"}}},"IndividualPlanDraftDto":{"type":"object","properties":{"id":{"type":"string"},"planId":{"type":"string"},"teacherKeycloakId":{"type":"string"},"teacherDisplayName":{"type":"string"},"blocks":{"type":"array","items":{"$ref":"#/components/schemas/Block"}},"totalHours":{"type":"number"},"generatedAt":{"type":"string","format":"date-time"}}},"AllocationsDto":{"type":"object","properties":{"lines":{"type":"array","items":{"$ref":"#/components/schemas/AllocationLineDto"}},"unassigned":{"type":"array","items":{"$ref":"#/components/schemas/UnassignedLineDto"}}}},"VersionOutcomeDto":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"code":{"type":"string"},"textKk":{"type":"string"},"textRu":{"type":"string"},"textEn":{"type":"string"},"bloomVerb":{"type":"string"},"bloomLevel":{"type":"string"},"measurable":{"type":"boolean"},"competenceCodes":{"type":"array","items":{"type":"string"}},"disciplineCodes":{"type":"array","items":{"type":"string"}}}},"SyllabusEnumLabelDto":{"type":"object","properties":{"code":{"type":"string"},"nameKk":{"type":"string"},"nameRu":{"type":"string"},"nameEn":{"type":"string"}}},"TeachingMethodDto":{"type":"object","properties":{"code":{"type":"string"},"nameKk":{"type":"string"},"nameRu":{"type":"string"},"nameEn":{"type":"string"},"descriptionRu":{"type":"string"}}},"RubricLevelDto":{"type":"object","properties":{"code":{"type":"string"},"nameKk":{"type":"string"},"nameRu":{"type":"string"},"nameEn":{"type":"string"},"letterLabel":{"type":"string"},"band":{"type":"string"}}},"PolicyBlockDto":{"type":"object","properties":{"code":{"type":"string"},"nameKk":{"type":"string"},"nameRu":{"type":"string"},"nameEn":{"type":"string"},"section":{"type":"string"}}},"GradingScaleDto":{"type":"object","properties":{"letter":{"type":"string"},"gpa":{"type":"number"},"percentFrom":{"type":"integer","format":"int32"},"percentTo":{"type":"integer","format":"int32"},"traditionalKk":{"type":"string"},"traditionalRu":{"type":"string"},"traditionalEn":{"type":"string"}}},"DefaultTextDto":{"type":"object","properties":{"key":{"type":"string"},"ru":{"type":"string"},"kk":{"type":"string"},"en":{"type":"string"}}},"BloomLevelDto":{"type":"object","properties":{"code":{"type":"string"},"ordinal":{"type":"integer","format":"int32"},"nameKk":{"type":"string"},"nameRu":{"type":"string"},"nameEn":{"type":"string"},"verbs":{"type":"array","items":{"type":"string"}}}},"AiUseLevelRefDto":{"type":"object","properties":{"code":{"type":"string"},"titleKk":{"type":"string"},"titleRu":{"type":"string"},"titleEn":{"type":"string"},"semanticsKk":{"type":"string"},"semanticsRu":{"type":"string"},"semanticsEn":{"type":"string"},"integrityColor":{"type":"string"},"tutorModeKk":{"type":"string"},"tutorModeRu":{"type":"string"},"tutorModeEn":{"type":"string"}}},"PolicyDefaultsSummaryDto":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"revisionNo":{"type":"integer","format":"int32"},"active":{"type":"boolean"},"origin":{"type":"string"},"effectiveFrom":{"type":"string","format":"date"},"createdAt":{"type":"string","format":"date-time"},"createdBy":{"type":"string"}}},"SyllabusSummaryDto":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"disciplineId":{"type":"string","format":"uuid"},"programVersionId":{"type":"string","format":"uuid"},"programId":{"type":"string","format":"uuid"},"courseCode":{"type":"string"},"courseId":{"type":"string","format":"uuid"},"courseIds":{"type":"array","items":{"type":"string","format":"uuid"}},"responsibleTeacherUserId":{"type":"string","format":"uuid"},"responsibleTeacherKeycloakId":{"type":"string"},"currentStatus":{"$ref":"#/components/schemas/LabelDto"},"publicationStatus":{"$ref":"#/components/schemas/LabelDto"},"language":{"$ref":"#/components/schemas/LabelDto"},"schoolDepartmentId":{"type":"integer","format":"int64"},"createdBy":{"type":"string"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"},"disciplineNameRu":{"type":"string"},"disciplineNameKk":{"type":"string"},"disciplineNameEn":{"type":"string"},"programCode":{"type":"string"},"credits":{"type":"number"},"responsibleTeacherName":{"type":"string"},"academicYear":{"type":"string"},"sectionsComplete":{"type":"integer","format":"int32"},"sectionsTotal":{"type":"integer","format":"int32"},"criticalCount":{"type":"integer","format":"int32"},"importedFromFile":{"type":"boolean"}}},"SyllabusSignPayloadDto":{"type":"object","properties":{"canonicalXml":{"type":"string"},"expectedIin":{"type":"string"}}},"ProgramOutcomeRefDto":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"externalProgramOutcomeId":{"type":"string","format":"uuid"},"code":{"type":"string"},"statement":{"type":"string"},"statementRu":{"type":"string"},"statementKk":{"type":"string"},"statementEn":{"type":"string"}}},"AbbrevDto":{"type":"object","properties":{"code":{"type":"string"},"meaning":{"type":"string"}}},"BlockDto":{"type":"object","properties":{"key":{"$ref":"#/components/schemas/LabelDto"},"section":{"type":"string"},"defaultText":{"type":"string"},"addition":{"type":"string"}}},"NumbersDto":{"type":"object","properties":{"expectedAttendancePct":{"type":"integer","format":"int32"},"maxMissedPct":{"type":"integer","format":"int32"},"admissionAttendancePct":{"type":"integer","format":"int32"},"latenessMinutes":{"type":"integer","format":"int32"},"latenessCountAsAbsence":{"type":"integer","format":"int32"},"lateSubmissionPenaltyPctPerDay":{"type":"integer","format":"int32"},"lateSubmissionMaxDays":{"type":"integer","format":"int32"},"excuseDocumentDays":{"type":"integer","format":"int32"},"instructorResponseWorkingDays":{"type":"integer","format":"int32"},"inPersonLessonMin":{"type":"integer","format":"int32"},"onlineLessonMin":{"type":"integer","format":"int32"},"examArriveEarlyMin":{"type":"integer","format":"int32"},"gradeAnnulmentDays":{"type":"integer","format":"int32"},"weeksPerTrimester":{"type":"integer","format":"int32"}}},"SyllabusPolicyViewDto":{"type":"object","properties":{"language":{"type":"string"},"revisionNo":{"type":"integer","format":"int32"},"blocks":{"type":"array","items":{"$ref":"#/components/schemas/BlockDto"}},"numbers":{"$ref":"#/components/schemas/NumbersDto"},"abbreviations":{"type":"array","items":{"$ref":"#/components/schemas/AbbrevDto"}}}},"SyllabusImportDraftDto":{"type":"object","properties":{"runId":{"type":"string","format":"uuid"},"syllabusId":{"type":"string","format":"uuid"},"syllabusVersionId":{"type":"string","format":"uuid"},"generatedAt":{"type":"string","format":"date-time"},"sourceFile":{"$ref":"#/components/schemas/SyllabusImportSourceFileDto"},"partial":{"type":"boolean"},"foundTotal":{"type":"integer","format":"int32"},"uncertainTotal":{"type":"integer","format":"int32"},"notFoundTotal":{"type":"integer","format":"int32"},"sections":{"type":"array","items":{"$ref":"#/components/schemas/SyllabusImportSectionDto"}}}},"SyllabusExportDto":{"type":"object","properties":{"fileId":{"type":"string"},"format":{"type":"string"},"filename":{"type":"string"},"sizeBytes":{"type":"integer","format":"int64"}}},"ChangeLogEntryDto":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"versionId":{"type":"string","format":"uuid"},"actor":{"type":"string"},"actorName":{"type":"string"},"occurredAt":{"type":"string","format":"date-time"},"action":{"type":"string"},"reason":{"type":"string"}}},"SyllabusApproverDto":{"type":"object","properties":{"syllabusId":{"type":"string","format":"uuid"},"schoolDepartmentId":{"type":"integer","format":"int64"},"chain":{"type":"array","items":{"$ref":"#/components/schemas/SyllabusApproverStepDto"}},"acting":{"$ref":"#/components/schemas/LabelDto"},"skipped":{"type":"array","items":{"$ref":"#/components/schemas/LabelDto"}},"explanation":{"$ref":"#/components/schemas/LabelDto"}}},"SyllabusApprovalDto":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"syllabusVersionId":{"type":"string","format":"uuid"},"decision":{"type":"string"},"actorKeycloakId":{"type":"string"},"actorFunction":{"$ref":"#/components/schemas/LabelDto"},"comment":{"type":"string"},"occurredAt":{"type":"string","format":"date-time"},"signerCommonName":{"type":"string"},"signedAt":{"type":"string","format":"date-time"},"maskedIin":{"type":"string"},"signatureValid":{"type":"boolean"}}},"AlignmentMatrixDto":{"type":"object","properties":{"nodes":{"type":"array","items":{"$ref":"#/components/schemas/Node"}},"edges":{"type":"array","items":{"$ref":"#/components/schemas/Edge"}},"gaps":{"type":"array","items":{"$ref":"#/components/schemas/Gap"}}}},"Edge":{"type":"object","properties":{"from":{"type":"string"},"to":{"type":"string"},"kind":{"type":"string"}}},"Gap":{"type":"object","properties":{"type":{"type":"string","enum":["OUTCOME_NOT_LINKED_TO_PLO","OUTCOME_NOT_IN_WEEK","WEEK_WITHOUT_OUTCOME","OUTCOME_NOT_IN_ASSIGNMENT","ASSIGNMENT_WITHOUT_OUTCOME"]},"nodeId":{"type":"string"},"message":{"type":"string"}}},"Node":{"type":"object","properties":{"id":{"type":"string"},"type":{"type":"string","enum":["PROGRAM_OUTCOME","DISCIPLINE_OUTCOME","WEEK","ASSIGNMENT","ASSESSMENT"]},"code":{"type":"string"},"label":{"type":"string"},"title":{"type":"string"}}},"AiLevel":{"type":"object","properties":{"code":{"type":"string"},"name":{"type":"string"},"description":{"type":"string"}}},"Literature":{"type":"object","properties":{"ordinal":{"type":"integer","format":"int32"},"citation":{"type":"string"},"url":{"type":"string"},"primary":{"type":"boolean"}}},"Outcome":{"type":"object","properties":{"code":{"type":"string"},"statement":{"type":"string"},"mapsTo":{"type":"string"}}},"ScaleRow":{"type":"object","properties":{"letter":{"type":"string"},"gpa":{"type":"string"},"percent":{"type":"string"},"traditional":{"type":"string"}}},"ACADEMIC_Section":{"type":"object","properties":{"key":{"$ref":"#/components/schemas/LabelDto"},"content":{"type":"object","additionalProperties":{}},"sortOrder":{"type":"integer","format":"int32"}}},"StudentSyllabusDto":{"type":"object","properties":{"courseCode":{"type":"string"},"courseTitle":{"type":"string"},"programName":{"type":"string"},"academicYear":{"type":"string"},"credits":{"type":"string"},"controlForm":{"type":"string"},"teacherFullName":{"type":"string"},"status":{"$ref":"#/components/schemas/LabelDto"},"language":{"$ref":"#/components/schemas/LabelDto"},"passport":{"$ref":"#/components/schemas/SyllabusPassportDto"},"sections":{"type":"array","items":{"$ref":"#/components/schemas/ACADEMIC_Section"}},"outcomes":{"type":"array","items":{"$ref":"#/components/schemas/Outcome"}},"methods":{"type":"array","items":{"type":"string"}},"assessment":{"$ref":"#/components/schemas/AssessmentSetDto"},"courseParameters":{"$ref":"#/components/schemas/CourseParametersDto"},"weekPlan":{"type":"array","items":{"$ref":"#/components/schemas/WeekDto"}},"rubric":{"$ref":"#/components/schemas/CourseRubricDto"},"policies":{"$ref":"#/components/schemas/SyllabusPolicyViewDto"},"literature":{"type":"array","items":{"$ref":"#/components/schemas/Literature"}},"tools":{"type":"array","items":{"$ref":"#/components/schemas/Tool"}},"aiPolicy":{"type":"array","items":{"$ref":"#/components/schemas/AiLevel"}},"gradingScale":{"type":"array","items":{"$ref":"#/components/schemas/ScaleRow"}}}},"Tool":{"type":"object","properties":{"name":{"type":"string"},"purpose":{"type":"string"},"url":{"type":"string"}}},"ReferenceItemDto":{"type":"object","properties":{"code":{"type":"string"},"nameKk":{"type":"string"},"nameRu":{"type":"string"},"nameEn":{"type":"string"},"ordinal":{"type":"integer","format":"int32"},"validUntil":{"type":"string","format":"date"}}},"ReferencesResponse":{"type":"object","properties":{"qualificationLevels":{"type":"array","items":{"$ref":"#/components/schemas/ReferenceItemDto"}},"mskoLevels":{"type":"array","items":{"$ref":"#/components/schemas/ReferenceItemDto"}},"nrkLevels":{"type":"array","items":{"$ref":"#/components/schemas/ReferenceItemDto"}},"orkLevels":{"type":"array","items":{"$ref":"#/components/schemas/ReferenceItemDto"}},"goso":{"type":"array","items":{"$ref":"#/components/schemas/ReferenceItemDto"}},"directionsOfStudy":{"type":"array","items":{"$ref":"#/components/schemas/ReferenceItemDto"}},"programGroups":{"type":"array","items":{"$ref":"#/components/schemas/ReferenceItemDto"}},"dublinDescriptors":{"type":"array","items":{"$ref":"#/components/schemas/ReferenceItemDto"}},"bloomVerbs":{"type":"array","items":{"$ref":"#/components/schemas/ReferenceItemDto"}},"lessonTypes":{"type":"array","items":{"$ref":"#/components/schemas/LabelDto"}},"controlForms":{"type":"array","items":{"$ref":"#/components/schemas/LabelDto"}}}},"ProgramVersionDto":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"programId":{"type":"string","format":"uuid"},"versionNumber":{"type":"integer","format":"int32"},"status":{"$ref":"#/components/schemas/LabelDto"},"parentVersionId":{"type":"string","format":"uuid"},"academicYear":{"type":"string"},"instructionLanguages":{"type":"array","items":{"$ref":"#/components/schemas/LabelDto"}},"goalTextKk":{"type":"string"},"goalTextRu":{"type":"string"},"goalTextEn":{"type":"string"},"conceptTextKk":{"type":"string"},"conceptTextRu":{"type":"string"},"conceptTextEn":{"type":"string"},"applicationArea":{"type":"string"},"professionalStandardRef":{"type":"string"},"atlasProfessionRef":{"type":"string"},"careerPositions":{"type":"array","items":{"type":"string"}},"publicationStatus":{"type":"string"},"approvedAt":{"type":"string","format":"date-time"},"approvedBy":{"type":"string"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}},"EffectiveFunctionsDto":{"type":"object","properties":{"keycloakUserId":{"type":"string","format":"uuid"},"orgFactsResolved":{"type":"boolean"},"homeSchoolDepartmentId":{"type":"integer","format":"int64"},"grants":{"type":"array","items":{"$ref":"#/components/schemas/FunctionGrantDto"}}}},"FunctionGrantDto":{"type":"object","properties":{"function":{"$ref":"#/components/schemas/LabelDto"},"schoolDepartmentId":{"type":"integer","format":"int64"},"global":{"type":"boolean"}}},"FunctionAuthorizationDto":{"type":"object","properties":{"keycloakUserId":{"type":"string","format":"uuid"},"function":{"$ref":"#/components/schemas/LabelDto"},"schoolDepartmentId":{"type":"integer","format":"int64"},"allowed":{"type":"boolean"},"orgFactsResolved":{"type":"boolean"},"schoolIsAcademic":{"type":"boolean"},"reason":{"type":"string"}}},"CatalogDisciplineUsageDto":{"type":"object","properties":{"catalogDisciplineId":{"type":"string","format":"uuid"},"code":{"type":"string"},"rowCount":{"type":"integer","format":"int32"},"usedInPrograms":{"type":"array","items":{"$ref":"#/components/schemas/Usage"}}}},"Usage":{"type":"object","properties":{"programVersionId":{"type":"string","format":"uuid"},"programCode":{"type":"string"},"programName":{"type":"string"},"disciplineRowId":{"type":"string","format":"uuid"}}},"TeacherAvailabilityResponse":{"type":"object","properties":{"timeslots":{"type":"array","items":{"$ref":"#/components/schemas/TimeslotOptionDto"}},"availableTimeslotIds":{"type":"array","items":{"type":"string","format":"uuid"}},"blockedTimeslotIds":{"type":"array","items":{"type":"string","format":"uuid"}},"undesiredTimeslotIds":{"type":"array","items":{"type":"string","format":"uuid"}}}},"TimeslotOptionDto":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"day":{"type":"string","enum":["MONDAY","TUESDAY","WEDNESDAY","THURSDAY","FRIDAY","SATURDAY"]},"classNumber":{"type":"integer","format":"int32"},"startTime":{"type":"string"},"endTime":{"type":"string"}}},"CalendarConflictDto":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"date":{"type":"string","format":"date"},"dayOfWeek":{"type":"string","enum":["MONDAY","TUESDAY","WEDNESDAY","THURSDAY","FRIDAY","SATURDAY","SUNDAY"]},"startTime":{"type":"string"},"endTime":{"type":"string"},"allDay":{"type":"boolean"},"eventId":{"type":"string","format":"uuid"},"meetingId":{"type":"string","format":"uuid"},"courseCode":{"type":"string"},"activityType":{"type":"string","enum":["LECTURE","PRACTICE","LAB"]},"roomId":{"type":"string","format":"uuid"},"roomDisplayName":{"type":"string"}}},"CalendarEventDto":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"seriesId":{"type":"string","format":"uuid"},"kind":{"type":"string","enum":["EVENT","MEETING","ROOM_CLOSED","OTHER"]},"status":{"type":"string","enum":["PENDING","APPROVED","REJECTED","CANCELLED","EXPIRED"]},"title":{"type":"string"},"displayTitle":{"type":"string"},"displayTitleKk":{"type":"string"},"displayTitleEn":{"type":"string"},"purpose":{"type":"string"},"attendees":{"type":"integer","format":"int32"},"date":{"type":"string","format":"date"},"dayOfWeek":{"type":"string","enum":["MONDAY","TUESDAY","WEDNESDAY","THURSDAY","FRIDAY","SATURDAY","SUNDAY"]},"allDay":{"type":"boolean"},"startTime":{"type":"string"},"endTime":{"type":"string"},"startsAt":{"type":"string","format":"date-time"},"endsAt":{"type":"string","format":"date-time"},"roomId":{"type":"string","format":"uuid"},"roomNumber":{"type":"string"},"roomBuilding":{"type":"string"},"roomDisplayName":{"type":"string"},"roomCapacity":{"type":"integer","format":"int32"},"programCode":{"type":"string"},"studyLevel":{"type":"string"},"academicYear":{"type":"string"},"disciplineCode":{"type":"string"},"streamId":{"type":"string","format":"uuid"},"streamNo":{"type":"integer","format":"int32"},"teacherInstructorId":{"type":"string","format":"uuid"},"teacherName":{"type":"string"},"teaching":{"type":"boolean"},"responsibleName":{"type":"string"},"authorName":{"type":"string"},"mine":{"type":"boolean"},"canEdit":{"type":"boolean"},"conflict":{"type":"boolean"},"conflictWith":{"type":"array","items":{"$ref":"#/components/schemas/CalendarConflictDto"}},"version":{"type":"integer","format":"int64"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}},"TimeslotDto":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"dayOfWeek":{"type":"string","enum":["MONDAY","TUESDAY","WEDNESDAY","THURSDAY","FRIDAY","SATURDAY"]},"classNumber":{"type":"integer","format":"int32"},"startTime":{"type":"string"},"endTime":{"type":"string"}}},"MeetingViewDto":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"meetingIndex":{"type":"integer","format":"int32"},"timeslotId":{"type":"string","format":"uuid"},"roomId":{"type":"string","format":"uuid"},"pinned":{"type":"boolean"},"version":{"type":"integer","format":"int64"},"roomNumber":{"type":"string"},"day":{"type":"string","enum":["MONDAY","TUESDAY","WEDNESDAY","THURSDAY","FRIDAY","SATURDAY"]},"classNumber":{"type":"integer","format":"int32"},"startTime":{"type":"string"},"endTime":{"type":"string"}}},"StreamGroupView":{"type":"object","properties":{"sectionId":{"type":"string","format":"uuid"},"groupNo":{"type":"integer","format":"int32"},"teacherKeycloakId":{"type":"string"},"teacherName":{"type":"string"},"currentEnrolled":{"type":"integer","format":"int32"},"maxStudents":{"type":"integer","format":"int32"},"format":{"type":"string","enum":["ONSITE","ONLINE_COURSE","ONLINE","MODULAR"]},"room":{"type":"string"}}},"StreamProgramView":{"type":"object","properties":{"programCode":{"type":"string"},"programTitle":{"type":"string"},"programTitleKk":{"type":"string"},"programTitleEn":{"type":"string"},"programShortTitle":{"type":"string"}}},"StreamTeacherSummaryDto":{"type":"object","properties":{"streamId":{"type":"string","format":"uuid"},"streamNo":{"type":"integer","format":"int32"},"courseId":{"type":"string","format":"uuid"},"courseCode":{"type":"string"},"courseTitle":{"type":"string"},"courseTitleKk":{"type":"string"},"courseTitleEn":{"type":"string"},"trimester":{"type":"integer","format":"int32"},"academicYear":{"type":"string"},"instructionLanguage":{"type":"string","enum":["KZ","EN"]},"programs":{"type":"array","items":{"$ref":"#/components/schemas/StreamProgramView"}},"mainInstructorKeycloakId":{"type":"string"},"mainInstructorName":{"type":"string"},"assistants":{"type":"array","items":{"$ref":"#/components/schemas/TeacherView"}},"lectureSectionId":{"type":"string","format":"uuid"},"lectureSectionIds":{"type":"array","items":{"type":"string","format":"uuid"}},"lectureFormat":{"type":"string","enum":["ONSITE","ONLINE_COURSE","ONLINE","MODULAR"]},"lectureRoom":{"type":"string"},"onlineMeetingUrl":{"type":"string"},"streamEnrolled":{"type":"integer","format":"int32"},"groups":{"type":"array","items":{"$ref":"#/components/schemas/StreamGroupView"}}}},"TeacherView":{"type":"object","properties":{"keycloakId":{"type":"string"},"name":{"type":"string"}}},"Deviation":{"type":"object","properties":{"code":{"type":"string"},"courseCode":{"type":"string"},"message":{"type":"string"}}},"SCHEDULING_Item":{"type":"object","properties":{"courseCode":{"type":"string"},"courseTitle":{"type":"string"},"courseTitleKk":{"type":"string"},"courseTitleEn":{"type":"string"},"credits":{"type":"integer","format":"int32"},"change":{"type":"string","enum":["KEEP","CHANGE","NEW"]},"streamId":{"type":"string","format":"uuid"},"streamNo":{"type":"integer","format":"int32"},"language":{"type":"string","enum":["KZ","EN"]},"teacherName":{"type":"string"},"lectureSectionId":{"type":"string","format":"uuid"},"lectureSlots":{"type":"array","items":{"$ref":"#/components/schemas/SlotView"}},"practiceSectionId":{"type":"string","format":"uuid"},"practiceGroupNo":{"type":"integer","format":"int32"},"practiceSlots":{"type":"array","items":{"$ref":"#/components/schemas/SlotView"}},"practiceTeacherName":{"type":"string"},"previous":{"$ref":"#/components/schemas/Previous"},"enrollmentIds":{"type":"array","items":{"type":"string","format":"uuid"}}}},"Previous":{"type":"object","properties":{"streamNo":{"type":"integer","format":"int32"},"practiceGroupNo":{"type":"integer","format":"int32"},"teacherName":{"type":"string"},"lectureSlots":{"type":"array","items":{"$ref":"#/components/schemas/SlotView"}},"practiceSlots":{"type":"array","items":{"$ref":"#/components/schemas/SlotView"}}}},"ScheduleProposalDto":{"type":"object","properties":{"proposalId":{"type":"string","format":"uuid"},"trimester":{"type":"integer","format":"int32"},"status":{"type":"string","enum":["PROPOSED","NO_COMPLETE_SET","NOTHING_TO_DO","WINDOW_CLOSED","NOT_ELIGIBLE","APPLIED","CANCELLED","EXPIRED"]},"complete":{"type":"boolean"},"expiresAt":{"type":"string","format":"date-time"},"expiresInSeconds":{"type":"integer","format":"int64"},"items":{"type":"array","items":{"$ref":"#/components/schemas/SCHEDULING_Item"}},"deviations":{"type":"array","items":{"$ref":"#/components/schemas/Deviation"}},"missingCourses":{"type":"array","items":{"type":"string"}},"weekSummary":{"type":"object","additionalProperties":{"type":"integer","format":"int32"}},"message":{"type":"string"}}},"SlotView":{"type":"object","properties":{"day":{"type":"string","enum":["MONDAY","TUESDAY","WEDNESDAY","THURSDAY","FRIDAY","SATURDAY"]},"classNumber":{"type":"integer","format":"int32"},"startTime":{"type":"string"},"endTime":{"type":"string"},"roomNumber":{"type":"string"}}},"TeacherClassDto":{"type":"object","properties":{"date":{"type":"string","format":"date"},"dayOfWeek":{"type":"string","enum":["MONDAY","TUESDAY","WEDNESDAY","THURSDAY","FRIDAY","SATURDAY"]},"classNumber":{"type":"integer","format":"int32"},"startTime":{"type":"string"},"endTime":{"type":"string"},"startsAt":{"type":"string","format":"date-time"},"sectionId":{"type":"string","format":"uuid"},"meetingId":{"type":"string","format":"uuid"},"timeslotId":{"type":"string","format":"uuid"},"courseId":{"type":"string","format":"uuid"},"courseCode":{"type":"string"},"courseTitle":{"type":"string"},"courseTitleKk":{"type":"string"},"courseTitleEn":{"type":"string"},"activityType":{"type":"string","enum":["LECTURE","PRACTICE","LAB"]},"room":{"type":"string"},"onlineMeetingUrl":{"type":"string"},"instructorNames":{"type":"array","items":{"type":"string"}},"online":{"type":"boolean"},"streamNo":{"type":"integer","format":"int32"},"jointSectionIds":{"type":"array","items":{"type":"string","format":"uuid"}},"instructionLanguage":{"type":"string","enum":["KZ","EN"]},"streamPrograms":{"type":"array","items":{"$ref":"#/components/schemas/StreamProgramView"}},"streamEnrolled":{"type":"integer","format":"int32"},"currentEnrolled":{"type":"integer","format":"int32"},"streamId":{"type":"string","format":"uuid"},"groupNo":{"type":"integer","format":"int32"},"mainInstructorName":{"type":"string"},"groupTeacherName":{"type":"string"}}},"StreamLessonDto":{"type":"object","properties":{"date":{"type":"string","format":"date"},"dayOfWeek":{"type":"string","enum":["MONDAY","TUESDAY","WEDNESDAY","THURSDAY","FRIDAY","SATURDAY"]},"classNumber":{"type":"integer","format":"int32"},"startTime":{"type":"string"},"endTime":{"type":"string"},"sectionId":{"type":"string","format":"uuid"},"meetingId":{"type":"string","format":"uuid"},"activityType":{"type":"string","enum":["LECTURE","PRACTICE","LAB"]},"groupNo":{"type":"integer","format":"int32"},"room":{"type":"string"},"online":{"type":"boolean"},"eventId":{"type":"string","format":"uuid"},"eventKind":{"type":"string","enum":["EVENT","MEETING","ROOM_CLOSED","OTHER"]},"eventTitle":{"type":"string"}}},"SectionViewDto":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"courseId":{"type":"string","format":"uuid"},"courseCode":{"type":"string"},"courseTitle":{"type":"string"},"courseTitleKk":{"type":"string"},"courseTitleEn":{"type":"string"},"programCode":{"type":"string"},"programCodes":{"type":"array","items":{"type":"string"},"uniqueItems":true},"instructionLanguage":{"type":"string","enum":["KZ","EN"]},"deliveryFormat":{"type":"string","enum":["ONSITE","ONLINE_COURSE","ONLINE","MODULAR"]},"trimester":{"type":"integer","format":"int32"},"studyLevel":{"type":"string"},"academicYear":{"type":"string"},"courseType":{"type":"string","enum":["MANDATORY","ELECTIVE"]},"activityType":{"type":"string","enum":["LECTURE","PRACTICE","LAB"]},"instructorIds":{"type":"array","items":{"type":"string","format":"uuid"}},"instructorNames":{"type":"array","items":{"type":"string"}},"isLocked":{"type":"boolean"},"minStudents":{"type":"integer","format":"int32"},"maxStudents":{"type":"integer","format":"int32"},"effectiveMaxStudents":{"type":"integer","format":"int32"},"currentEnrolled":{"type":"integer","format":"int32"},"version":{"type":"integer","format":"int64"},"onlineMeetingUrl":{"type":"string"},"meetings":{"type":"array","items":{"$ref":"#/components/schemas/MeetingViewDto"}},"totalWeeklyHours":{"type":"integer","format":"int32"},"instructorMaxWeeklyHours":{"type":"integer","format":"int32"},"enrollmentId":{"type":"string","format":"uuid"},"streamNo":{"type":"integer","format":"int32"},"online":{"type":"boolean"},"jointSectionIds":{"type":"array","items":{"type":"string","format":"uuid"}},"groupNo":{"type":"integer","format":"int32"},"streamId":{"type":"string","format":"uuid"},"streamPrograms":{"type":"array","items":{"$ref":"#/components/schemas/StreamProgramView"}},"streamEnrolled":{"type":"integer","format":"int32"}}},"RosterEntryDto":{"type":"object","properties":{"studentId":{"type":"string"},"fullName":{"type":"string"},"status":{"type":"string","enum":["ENROLLED","CANCELLED"]},"enrolledAt":{"type":"string","format":"date-time"}}},"ClassMeetingDates":{"type":"object","properties":{"meetingId":{"type":"string","format":"uuid"},"meetingIndex":{"type":"integer","format":"int32"},"timeslotId":{"type":"string","format":"uuid"},"day":{"type":"string","enum":["MONDAY","TUESDAY","WEDNESDAY","THURSDAY","FRIDAY","SATURDAY"]},"classNumber":{"type":"integer","format":"int32"},"startTime":{"type":"string"},"endTime":{"type":"string"},"roomNumber":{"type":"string"},"dates":{"type":"array","items":{"type":"string","format":"date"}}}},"SectionClassDatesDto":{"type":"object","properties":{"sectionId":{"type":"string","format":"uuid"},"courseId":{"type":"string","format":"uuid"},"courseCode":{"type":"string"},"courseTitle":{"type":"string"},"courseTitleKk":{"type":"string"},"courseTitleEn":{"type":"string"},"trimester":{"type":"integer","format":"int32"},"timezone":{"type":"string"},"termStartDate":{"type":"string","format":"date"},"classesStartDate":{"type":"string","format":"date"},"classesEndDate":{"type":"string","format":"date"},"termEndDate":{"type":"string","format":"date"},"canonAvailable":{"type":"boolean"},"onlineMeetingUrl":{"type":"string"},"online":{"type":"boolean"},"meetings":{"type":"array","items":{"$ref":"#/components/schemas/ClassMeetingDates"}}}},"ActiveRoomDto":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"number":{"type":"string"},"building":{"type":"string"},"name":{"type":"string"},"capacity":{"type":"integer","format":"int32"},"roomType":{"type":"string","enum":["LECTURE","COMPUTER","LAB","COWORKING","SELF_STUDY","OTHER"]},"displayName":{"type":"string"}}},"RegistrarStudentDto":{"type":"object","properties":{"studentId":{"type":"string"},"fullName":{"type":"string"},"programCode":{"type":"string"},"programTitle":{"type":"string"},"instructionLanguage":{"type":"string","enum":["KZ","EN"]}}},"RegistrarStudentSearchDto":{"type":"object","properties":{"content":{"type":"array","items":{"$ref":"#/components/schemas/RegistrarStudentDto"}},"total":{"type":"integer","format":"int32"}}},"RegistrarStudentScheduleDto":{"type":"object","properties":{"studentId":{"type":"string"},"fullName":{"type":"string"},"programCode":{"type":"string"},"programTitle":{"type":"string"},"instructionLanguage":{"type":"string","enum":["KZ","EN"]},"sections":{"type":"array","items":{"$ref":"#/components/schemas/SectionViewDto"}}}},"MyScheduleDto":{"type":"object","properties":{"role":{"type":"string"},"sections":{"type":"array","items":{"$ref":"#/components/schemas/SectionViewDto"}},"hiddenSections":{"type":"array","items":{"$ref":"#/components/schemas/SectionViewDto"}},"requiredElectiveCount":{"type":"integer","format":"int32"},"chosenElectiveCourses":{"type":"integer","format":"int32"},"instructorId":{"type":"string","format":"uuid"},"maxWeeklyHours":{"type":"integer","format":"int32"}}},"NextClassDto":{"type":"object","properties":{"found":{"type":"boolean"},"date":{"type":"string","format":"date"},"day":{"type":"string","enum":["MONDAY","TUESDAY","WEDNESDAY","THURSDAY","FRIDAY","SATURDAY"]},"classNumber":{"type":"integer","format":"int32"},"startTime":{"type":"string"},"endTime":{"type":"string"},"startsAt":{"type":"string","format":"date-time"},"sectionId":{"type":"string","format":"uuid"},"courseId":{"type":"string","format":"uuid"},"courseCode":{"type":"string"},"courseTitle":{"type":"string"},"courseTitleKk":{"type":"string"},"courseTitleEn":{"type":"string"},"roomNumber":{"type":"string"},"onlineMeetingUrl":{"type":"string"},"instructorNames":{"type":"array","items":{"type":"string"}},"online":{"type":"boolean"},"activityType":{"type":"string","enum":["LECTURE","PRACTICE","LAB"]},"instructionLanguage":{"type":"string","enum":["KZ","EN"]},"streamPrograms":{"type":"array","items":{"$ref":"#/components/schemas/StreamProgramView"}},"streamEnrolled":{"type":"integer","format":"int32"},"currentEnrolled":{"type":"integer","format":"int32"},"streamNo":{"type":"integer","format":"int32"},"groupNo":{"type":"integer","format":"int32"},"dayOfWeek":{"type":"string","enum":["MONDAY","TUESDAY","WEDNESDAY","THURSDAY","FRIDAY","SATURDAY","SUNDAY"]},"eventId":{"type":"string","format":"uuid"},"eventKind":{"type":"string","enum":["EVENT","MEETING","ROOM_CLOSED","OTHER"]},"eventTitle":{"type":"string"}}},"LessonDateDto":{"type":"object","properties":{"date":{"type":"string","format":"date"},"dayOfWeek":{"type":"string","enum":["MONDAY","TUESDAY","WEDNESDAY","THURSDAY","FRIDAY","SATURDAY"]},"classNumber":{"type":"integer","format":"int32"},"startTime":{"type":"string"},"endTime":{"type":"string"},"meetingType":{"type":"string","enum":["LECTURE","PRACTICE","LAB"]},"room":{"type":"string"},"onlineMeetingUrl":{"type":"string"},"sectionId":{"type":"string","format":"uuid"},"courseId":{"type":"string","format":"uuid"},"meetingId":{"type":"string","format":"uuid"},"timeslotId":{"type":"string","format":"uuid"},"online":{"type":"boolean"}}},"EnrollmentWindowDto":{"type":"object","properties":{"trimester":{"type":"integer","format":"int32"},"programCode":{"type":"string"},"open":{"type":"boolean"},"code":{"type":"string"},"opensAt":{"type":"string","format":"date-time"},"closesAt":{"type":"string","format":"date-time"},"addDropStart":{"type":"string","format":"date-time"},"addDropEnd":{"type":"string","format":"date-time"},"serverTime":{"type":"string","format":"date-time"},"source":{"type":"string"}}},"EnrollmentEligibilityDto":{"type":"object","properties":{"eligible":{"type":"boolean"},"reasonCode":{"type":"string"},"reason":{"type":"string"},"programCode":{"type":"string"},"instructionLanguage":{"type":"string","enum":["KZ","EN"]}}},"SCHEDULING_Alternative":{"type":"object","properties":{"courseCode":{"type":"string"},"courseTitle":{"type":"string"},"courseTitleKk":{"type":"string"},"courseTitleEn":{"type":"string"},"credits":{"type":"integer","format":"int32"},"orderIndex":{"type":"integer","format":"int32"},"teacherAssigned":{"type":"boolean"},"streamCount":{"type":"integer","format":"int32"},"chosen":{"type":"boolean"}}},"ElectiveCatalogDto":{"type":"object","properties":{"requiredElectiveCount":{"type":"integer","format":"int32"},"chosenElectiveCourses":{"type":"integer","format":"int32"},"chosenCredits":{"type":"integer","format":"int32"},"creditLimit":{"type":"integer","format":"int32"},"programCode":{"type":"string"},"instructionLanguage":{"type":"string","enum":["KZ","EN"]},"reasonCode":{"type":"string"},"reason":{"type":"string"},"sections":{"type":"array","items":{"$ref":"#/components/schemas/ElectiveSectionDto"}},"electiveGroups":{"type":"array","items":{"$ref":"#/components/schemas/ElectiveGroupOfferDto"}},"studyPlanTerms":{"type":"array","items":{"$ref":"#/components/schemas/StudyPlanTermDto"}}}},"ElectiveGroupOfferDto":{"type":"object","properties":{"code":{"type":"string"},"titleKk":{"type":"string"},"titleRu":{"type":"string"},"titleEn":{"type":"string"},"orderIndex":{"type":"integer","format":"int32"},"chosenCourseCode":{"type":"string"},"chosenComplete":{"type":"boolean"},"alternatives":{"type":"array","items":{"$ref":"#/components/schemas/SCHEDULING_Alternative"}}}},"ElectiveSectionDto":{"type":"object","properties":{"sectionId":{"type":"string","format":"uuid"},"courseId":{"type":"string","format":"uuid"},"courseCode":{"type":"string"},"courseTitle":{"type":"string"},"courseTitleKk":{"type":"string"},"courseTitleEn":{"type":"string"},"activityType":{"type":"string","enum":["LECTURE","PRACTICE","LAB"]},"instructionLanguage":{"type":"string","enum":["KZ","EN"]},"deliveryFormat":{"type":"string","enum":["ONSITE","ONLINE_COURSE","ONLINE","MODULAR"]},"courseCredits":{"type":"integer","format":"int32"},"instructorNames":{"type":"array","items":{"type":"string"}},"meetings":{"type":"array","items":{"$ref":"#/components/schemas/MeetingViewDto"}},"maxStudents":{"type":"integer","format":"int32"},"effectiveMaxStudents":{"type":"integer","format":"int32"},"currentEnrolled":{"type":"integer","format":"int32"},"freeSeats":{"type":"integer","format":"int32"},"myStatus":{"type":"string","enum":["ENROLLED","CANCELLED"]},"myEnrollmentId":{"type":"string","format":"uuid"}}},"StudyPlanTermDto":{"type":"object","properties":{"academicYear":{"type":"string"},"termNo":{"type":"integer","format":"int32"},"mode":{"type":"string"},"studyYear":{"type":"integer","format":"int32"},"trajectoryId":{"type":"string"},"trajectoryTitleRu":{"type":"string"},"trajectoryTitleKk":{"type":"string"},"trajectoryTitleEn":{"type":"string"}}},"CourseStreamSummaryDto":{"type":"object","properties":{"courseCode":{"type":"string"},"sectionCount":{"type":"integer","format":"int32"},"sectionCountsByActivity":{"type":"object","additionalProperties":{"type":"integer","format":"int32"}},"distinctStudentCount":{"type":"integer","format":"int64"},"weekdays":{"type":"array","items":{"type":"string","enum":["MONDAY","TUESDAY","WEDNESDAY","THURSDAY","FRIDAY","SATURDAY"]}},"totalWeeklyHours":{"type":"integer","format":"int32"}}},"PracticeView":{"type":"object","properties":{"sectionId":{"type":"string","format":"uuid"},"groupNo":{"type":"integer","format":"int32"},"activityType":{"type":"string","enum":["LECTURE","PRACTICE","LAB"]},"slots":{"type":"array","items":{"$ref":"#/components/schemas/SlotView"}},"currentEnrolled":{"type":"integer","format":"int32"},"maxStudents":{"type":"integer","format":"int32"},"freeSeats":{"type":"integer","format":"int32"},"teacherName":{"type":"string"},"format":{"type":"string","enum":["ONSITE","ONLINE_COURSE","ONLINE","MODULAR"]}}},"StreamView":{"type":"object","properties":{"streamId":{"type":"string","format":"uuid"},"streamNo":{"type":"integer","format":"int32"},"language":{"type":"string","enum":["KZ","EN"]},"capacity":{"type":"integer","format":"int32"},"teacherName":{"type":"string"},"lectureSectionId":{"type":"string","format":"uuid"},"lectureSlots":{"type":"array","items":{"$ref":"#/components/schemas/SlotView"}},"practices":{"type":"array","items":{"$ref":"#/components/schemas/PracticeView"}},"programQuotas":{"type":"array","items":{"$ref":"#/components/schemas/StudentProgramQuotaView"}},"myProgramCode":{"type":"string"},"myProgramAllowed":{"type":"boolean"},"myProgramFreeSeats":{"type":"integer","format":"int32"},"lectureFreeSeats":{"type":"integer","format":"int32"},"lectureFormat":{"type":"string","enum":["ONSITE","ONLINE_COURSE","ONLINE","MODULAR"]}}},"StudentProgramQuotaView":{"type":"object","properties":{"programCode":{"type":"string"},"programTitle":{"type":"string"},"programTitleKk":{"type":"string"},"programTitleEn":{"type":"string"},"programShortTitle":{"type":"string"},"quota":{"type":"integer","format":"int32"},"enrolled":{"type":"integer","format":"int64"},"freeSeats":{"type":"integer","format":"int32"}}},"StudentStreamsDto":{"type":"object","properties":{"courseCode":{"type":"string"},"courseTitle":{"type":"string"},"courseTitleKk":{"type":"string"},"courseTitleEn":{"type":"string"},"credits":{"type":"integer","format":"int32"},"streams":{"type":"array","items":{"$ref":"#/components/schemas/StreamView"}}}},"CourseStreamDto":{"type":"object","properties":{"sectionId":{"type":"string","format":"uuid"},"activityType":{"type":"string","enum":["LECTURE","PRACTICE","LAB"]},"instructorIds":{"type":"array","items":{"type":"string","format":"uuid"}},"instructorNames":{"type":"array","items":{"type":"string"}},"currentEnrolled":{"type":"integer","format":"int32"},"maxStudents":{"type":"integer","format":"int32"},"weekdays":{"type":"array","items":{"type":"string","enum":["MONDAY","TUESDAY","WEDNESDAY","THURSDAY","FRIDAY","SATURDAY"]}},"weeklyHours":{"type":"integer","format":"int32"},"onlineMeetingUrl":{"type":"string"}}},"OccupancyDto":{"type":"object","properties":{"from":{"type":"string","format":"date"},"to":{"type":"string","format":"date"},"rooms":{"type":"array","items":{"$ref":"#/components/schemas/ActiveRoomDto"}},"events":{"type":"array","items":{"$ref":"#/components/schemas/CalendarEventDto"}}}},"CalendarEventChangeDto":{"type":"object","properties":{"field":{"type":"string"},"before":{"type":"string"},"after":{"type":"string"},"beforeRef":{"type":"string","format":"uuid"},"afterRef":{"type":"string","format":"uuid"}}},"CalendarEventHistoryDto":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"eventId":{"type":"string","format":"uuid"},"seriesId":{"type":"string","format":"uuid"},"action":{"type":"string","enum":["CREATED","UPDATED","DELETED"]},"actorName":{"type":"string"},"createdAt":{"type":"string","format":"date-time"},"changes":{"type":"array","items":{"$ref":"#/components/schemas/CalendarEventChangeDto"}}}},"VacancyCardDto":{"type":"object","properties":{"vacancyId":{"type":"integer","format":"int64"},"externalId":{"type":"string"},"url":{"type":"string"},"title":{"type":"string"},"companyName":{"type":"string"},"city":{"type":"string"},"seniority":{"type":"string","enum":["JUNIOR","MIDDLE","SENIOR","LEAD","UNKNOWN"]},"salaryFrom":{"type":"integer","format":"int32"},"salaryTo":{"type":"integer","format":"int32"},"salaryCurrency":{"type":"string"},"publishedAt":{"type":"string","format":"date-time"}}},"VacancyListResponse":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/VacancyCardDto"}}}},"MatchItemDto":{"type":"object","properties":{"vacancyId":{"type":"integer","format":"int64"},"externalId":{"type":"string"},"url":{"type":"string"},"title":{"type":"string"},"companyName":{"type":"string"},"city":{"type":"string"},"seniority":{"type":"string","enum":["JUNIOR","MIDDLE","SENIOR","LEAD","UNKNOWN"]},"salaryFrom":{"type":"integer","format":"int32"},"salaryTo":{"type":"integer","format":"int32"},"salaryCurrency":{"type":"string"},"publishedAt":{"type":"string","format":"date-time"},"score":{"type":"number","format":"double"},"matched":{"type":"array","items":{"$ref":"#/components/schemas/MatchedSkillDto"}},"missing":{"type":"array","items":{"$ref":"#/components/schemas/MissingSkillDto"}}}},"MatchedSkillDto":{"type":"object","properties":{"name":{"type":"string"},"displayName":{"type":"string"},"similarity":{"type":"number","format":"double"},"viaInput":{"type":"string"}}},"MissingSkillDto":{"type":"object","properties":{"name":{"type":"string"},"displayName":{"type":"string"}}},"SyllabusMatchResponse":{"type":"object","properties":{"syllabusId":{"type":"integer","format":"int64"},"courseExternalId":{"type":"string"},"title":{"type":"string"},"skillsCount":{"type":"integer","format":"int32"},"stale":{"type":"boolean"},"items":{"type":"array","items":{"$ref":"#/components/schemas/MatchItemDto"}}}},"MatchListResponse":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/MatchItemDto"}},"stale":{"type":"boolean"},"unrecognizedSkills":{"type":"array","items":{"type":"string"}}}},"CompaniesResponse":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/CompanyAggregateDto"}},"stale":{"type":"boolean"},"unrecognizedSkills":{"type":"array","items":{"type":"string"}}}},"CompanyAggregateDto":{"type":"object","properties":{"companyName":{"type":"string"},"vacanciesCount":{"type":"integer","format":"int64"},"avgMatchScore":{"type":"number","format":"double"},"samplePositions":{"type":"array","items":{"type":"string"}}}},"AdminEventDetailDto":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"kind":{"type":"string"},"clubId":{"type":"string","format":"uuid"},"clubName":{"type":"string"},"clubSlug":{"type":"string"},"title":{"type":"string"},"description":{"type":"string"},"posterFileId":{"type":"string","format":"uuid"},"hasPoster":{"type":"boolean"},"startsAt":{"type":"string","format":"date-time"},"endsAt":{"type":"string","format":"date-time"},"format":{"type":"string"},"placeKind":{"type":"string"},"roomId":{"type":"string","format":"uuid"},"placeLabel":{"type":"string"},"onlineUrl":{"type":"string"},"direction":{"$ref":"#/components/schemas/EventDirectionRefDto"},"visibility":{"type":"string"},"status":{"type":"string"},"registrationEnabled":{"type":"boolean"},"capacity":{"type":"integer","format":"int32"},"registrationClosesAt":{"type":"string","format":"date-time"},"checkinMode":{"type":"string"},"checkinWindowBeforeMin":{"type":"integer","format":"int32"},"organizerKeycloakId":{"type":"string"},"organizerName":{"type":"string"},"level":{"type":"string"},"socialCredits":{"type":"number"},"reviewRequestedAt":{"type":"string","format":"date-time"},"reviewedAt":{"type":"string","format":"date-time"},"reviewedBy":{"type":"string"},"reviewComment":{"type":"string"},"siteStatus":{"type":"string"},"siteRequestedAt":{"type":"string","format":"date-time"},"siteDecidedAt":{"type":"string","format":"date-time"},"siteDecidedBy":{"type":"string"},"siteComment":{"type":"string"},"closedAt":{"type":"string","format":"date-time"},"closedBy":{"type":"string"},"organizerReport":{"type":"string"},"confirmedAt":{"type":"string","format":"date-time"},"confirmedBy":{"type":"string"},"confirmComment":{"type":"string"},"cancelledAt":{"type":"string","format":"date-time"},"cancelReason":{"type":"string"},"createdAt":{"type":"string","format":"date-time"},"registeredCount":{"type":"integer","format":"int64"},"needsDecision":{"type":"integer","format":"int64"},"registrations":{"type":"array","items":{"$ref":"#/components/schemas/EventRegistrationDto"}},"attendance":{"type":"array","items":{"$ref":"#/components/schemas/EventAttendanceDto"}},"ratings":{"$ref":"#/components/schemas/RatingsSummaryDto"},"audit":{"type":"array","items":{"$ref":"#/components/schemas/AuditEntryDto"}},"organizerUnit":{"type":"string"},"audienceProgramCodes":{"type":"array","items":{"type":"string"}},"audienceInstructionLanguages":{"type":"array","items":{"type":"string"}},"audienceCourseYears":{"type":"array","items":{"type":"integer","format":"int32"}},"contactInfo":{"type":"string"},"publishedAt":{"type":"string","format":"date-time"},"campusUrl":{"type":"string"}}},"AuditEntryDto":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"entityType":{"type":"string"},"entityId":{"type":"string"},"action":{"type":"string"},"actorKeycloakId":{"type":"string"},"actorName":{"type":"string"},"actorRole":{"type":"string"},"comment":{"type":"string"},"createdAt":{"type":"string","format":"date-time"}}},"EventAttendanceDto":{"type":"object","properties":{"keycloakId":{"type":"string"},"name":{"type":"string"},"hasPhoto":{"type":"boolean"},"checkedInAt":{"type":"string","format":"date-time"},"method":{"type":"string"},"role":{"type":"string"},"organizerStatus":{"type":"string"},"staffStatus":{"type":"string"},"score":{"type":"integer","format":"int32"},"reportRating":{"type":"integer","format":"int32"},"reportText":{"type":"string"},"hasReportPhoto":{"type":"boolean"},"reportSubmittedAt":{"type":"string","format":"date-time"}}},"EventDirectionRefDto":{"type":"object","properties":{"code":{"type":"string"},"nameRu":{"type":"string"},"nameKk":{"type":"string"},"nameEn":{"type":"string"},"block":{"type":"string"},"valueBased":{"type":"boolean"}}},"EventRegistrationDto":{"type":"object","properties":{"keycloakId":{"type":"string"},"name":{"type":"string"},"hasPhoto":{"type":"boolean"},"status":{"type":"string"},"noShow":{"type":"boolean"},"checkedIn":{"type":"boolean"},"registeredAt":{"type":"string","format":"date-time"},"cancelledAt":{"type":"string","format":"date-time"}}},"RatingsSummaryDto":{"type":"object","properties":{"count":{"type":"integer","format":"int64"},"average":{"type":"number"},"distribution":{"type":"array","items":{"type":"integer","format":"int64"}}}},"ConsultationTemplateDayDto":{"type":"object","properties":{"dayOfWeek":{"type":"integer","format":"int32"},"startTimes":{"type":"array","items":{"type":"string"}}}},"ConsultationSettingsDto":{"type":"object","properties":{"keycloakId":{"type":"string"},"displayName":{"type":"string"},"format":{"type":"string"},"location":{"type":"string"},"onlineUrl":{"type":"string"},"windowStartHour":{"type":"integer","format":"int32"},"windowEndHour":{"type":"integer","format":"int32"},"acceptingBookings":{"type":"boolean"},"template":{"type":"array","items":{"$ref":"#/components/schemas/ConsultationTemplateDayDto"}}}},"ConsultationBookingBriefDto":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"status":{"type":"string"},"startTime":{"type":"string"},"endTime":{"type":"string"},"studentName":{"type":"string"}}},"ConsultationDayDto":{"type":"object","properties":{"date":{"type":"string","format":"date"},"dayOfWeek":{"type":"integer","format":"int32"},"slots":{"type":"array","items":{"$ref":"#/components/schemas/ConsultationSlotDto"}},"bookings":{"type":"array","items":{"$ref":"#/components/schemas/ConsultationBookingBriefDto"}}}},"ConsultationSlotDto":{"type":"object","properties":{"startTime":{"type":"string"},"endTime":{"type":"string"},"state":{"type":"string"},"closedBy":{"type":"string"},"exceptionId":{"type":"string","format":"uuid"},"exceptionKind":{"type":"string"},"exceptionNote":{"type":"string"},"oneOff":{"type":"boolean"},"bookingId":{"type":"string","format":"uuid"}}},"ConsultationExceptionDto":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"kind":{"type":"string"},"dateFrom":{"type":"string","format":"date"},"dateTo":{"type":"string","format":"date"},"startTime":{"type":"string"},"endTime":{"type":"string"},"note":{"type":"string"},"createdAt":{"type":"string","format":"date-time"}}},"MyEventDetailDto":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"kind":{"type":"string"},"clubId":{"type":"string","format":"uuid"},"clubName":{"type":"string"},"clubSlug":{"type":"string"},"title":{"type":"string"},"description":{"type":"string"},"posterFileId":{"type":"string","format":"uuid"},"hasPoster":{"type":"boolean"},"startsAt":{"type":"string","format":"date-time"},"endsAt":{"type":"string","format":"date-time"},"format":{"type":"string"},"placeKind":{"type":"string"},"roomId":{"type":"string","format":"uuid"},"placeLabel":{"type":"string"},"onlineUrl":{"type":"string"},"direction":{"$ref":"#/components/schemas/EventDirectionRefDto"},"visibility":{"type":"string"},"status":{"type":"string"},"registrationEnabled":{"type":"boolean"},"capacity":{"type":"integer","format":"int32"},"registrationClosesAt":{"type":"string","format":"date-time"},"checkinMode":{"type":"string"},"checkinWindowBeforeMin":{"type":"integer","format":"int32"},"organizerKeycloakId":{"type":"string"},"organizerName":{"type":"string"},"level":{"type":"string"},"socialCredits":{"type":"number"},"reviewComment":{"type":"string"},"reviewedAt":{"type":"string","format":"date-time"},"siteStatus":{"type":"string"},"siteComment":{"type":"string"},"closedAt":{"type":"string","format":"date-time"},"organizerReport":{"type":"string"},"confirmedAt":{"type":"string","format":"date-time"},"confirmComment":{"type":"string"},"cancelReason":{"type":"string"},"registeredCount":{"type":"integer","format":"int64"},"attendanceCount":{"type":"integer","format":"int64"},"canEdit":{"type":"boolean"},"canClose":{"type":"boolean"},"canCancel":{"type":"boolean"},"confirmed":{"type":"boolean"}}},"CLUBS_AchievementDto":{"type":"object","properties":{"title":{"type":"string"},"year":{"type":"integer","format":"int32"},"description":{"type":"string"},"url":{"type":"string"}}},"LanguageDto":{"type":"object","properties":{"code":{"type":"string"},"name":{"type":"string"},"level":{"type":"string"}}},"ConsentDto":{"type":"object","properties":{"signed":{"type":"boolean"},"signedAt":{"type":"string","format":"date-time"}}},"CvDto":{"type":"object","properties":{"fileName":{"type":"string"},"sizeBytes":{"type":"integer","format":"int64"}}},"MyApplicationDto":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"status":{"type":"string"},"decisionComment":{"type":"string"},"removalReason":{"type":"string"},"fullName":{"type":"string"},"programName":{"type":"string"},"courseYear":{"type":"integer","format":"int32"},"phone":{"type":"string"},"telegram":{"type":"string"},"socialUrl":{"type":"string"},"languages":{"type":"array","items":{"$ref":"#/components/schemas/LanguageDto"}},"achievements":{"type":"array","items":{"$ref":"#/components/schemas/CLUBS_AchievementDto"}},"cv":{"$ref":"#/components/schemas/CvDto"},"whyMe":{"type":"string"},"plans":{"type":"string"},"goals":{"type":"string"},"values":{"type":"string"},"submittedAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"},"canEdit":{"type":"boolean"},"canWithdraw":{"type":"boolean"},"consent":{"$ref":"#/components/schemas/ConsentDto"},"canSignConsent":{"type":"boolean"}}},"AiFindingDto":{"type":"object","properties":{"field":{"type":"string"},"severity":{"type":"string"},"reason":{"type":"string"},"fragment":{"type":"string"}}},"ChangeRequestDto":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"clubId":{"type":"string","format":"uuid"},"clubName":{"type":"string"},"clubSlug":{"type":"string"},"proposed":{"$ref":"#/components/schemas/ClubChangeFieldsDto"},"current":{"$ref":"#/components/schemas/ClubChangeFieldsDto"},"proposedPlan":{"type":"array","items":{"$ref":"#/components/schemas/ClubPlanItemDto"}},"currentPlan":{"type":"array","items":{"$ref":"#/components/schemas/ClubPlanItemDto"}},"status":{"type":"string"},"aiOutcome":{"type":"string"},"aiFindings":{"type":"array","items":{"$ref":"#/components/schemas/AiFindingDto"}},"aiCheckedAt":{"type":"string","format":"date-time"},"createdByName":{"type":"string"},"createdAt":{"type":"string","format":"date-time"},"decidedAt":{"type":"string","format":"date-time"},"decisionComment":{"type":"string"}}},"ClubChangeFieldsDto":{"type":"object","properties":{"name":{"type":"string"},"description":{"type":"string"},"purpose":{"type":"string"},"logoFileId":{"type":"string","format":"uuid"}}},"ClubMemberDto":{"type":"object","properties":{"keycloakId":{"type":"string"},"name":{"type":"string"},"role":{"type":"string"},"hasPhoto":{"type":"boolean"},"courseYear":{"type":"integer","format":"int32"},"contactPhone":{"type":"string"},"accountActive":{"type":"boolean"},"joinedAt":{"type":"string","format":"date-time"},"showcase":{"$ref":"#/components/schemas/MemberShowcaseDto"}}},"ClubPlanItemDto":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"month":{"type":"string"},"title":{"type":"string"},"format":{"type":"string"},"expectedParticipants":{"type":"integer","format":"int32"},"direction":{"$ref":"#/components/schemas/EventDirectionRefDto"},"eventId":{"type":"string","format":"uuid"}}},"ClubPlanRulesDto":{"type":"object","properties":{"windowFrom":{"type":"string"},"windowTo":{"type":"string"},"minPerMonth":{"type":"integer","format":"int32"},"minValueBased":{"type":"integer","format":"int32"},"months":{"type":"array","items":{"type":"string"}}}},"ClubPlanSummaryDto":{"type":"object","properties":{"monthsRequired":{"type":"integer","format":"int32"},"monthsDone":{"type":"integer","format":"int32"},"valueBasedRequired":{"type":"integer","format":"int32"},"valueBasedDone":{"type":"integer","format":"int32"},"monthsMissing":{"type":"array","items":{"type":"string"}},"itemsTotal":{"type":"integer","format":"int32"},"complete":{"type":"boolean"}}},"DirectionRefDto":{"type":"object","properties":{"code":{"type":"string"},"nameRu":{"type":"string"},"nameKk":{"type":"string"},"nameEn":{"type":"string"}}},"HeadDto":{"type":"object","properties":{"keycloakId":{"type":"string"},"name":{"type":"string"},"hasPhoto":{"type":"boolean"},"accountInactive":{"type":"boolean"}}},"CLUBS_Item":{"type":"object","properties":{"code":{"type":"string"},"tier":{"type":"string"},"nameRu":{"type":"string"},"nameKk":{"type":"string"},"nameEn":{"type":"string"}}},"JoinRequestDto":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"keycloakId":{"type":"string"},"name":{"type":"string"},"hasPhoto":{"type":"boolean"},"status":{"type":"string"},"createdAt":{"type":"string","format":"date-time"},"decidedAt":{"type":"string","format":"date-time"}}},"MemberShowcaseDto":{"type":"object","properties":{"level":{"type":"integer","format":"int32"},"levelNameRu":{"type":"string"},"levelNameKk":{"type":"string"},"levelNameEn":{"type":"string"},"achievements":{"type":"array","items":{"$ref":"#/components/schemas/CLUBS_Item"}}}},"MyClubDetailDto":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"slug":{"type":"string"},"name":{"type":"string"},"direction":{"$ref":"#/components/schemas/DirectionRefDto"},"description":{"type":"string"},"purpose":{"type":"string"},"plan":{"type":"string"},"planItems":{"type":"array","items":{"$ref":"#/components/schemas/ClubPlanItemDto"}},"planRules":{"$ref":"#/components/schemas/ClubPlanRulesDto"},"planSummary":{"$ref":"#/components/schemas/ClubPlanSummaryDto"},"status":{"type":"string"},"joinMode":{"type":"string"},"hasLogo":{"type":"boolean"},"logoFileId":{"type":"string","format":"uuid"},"contactPhone":{"type":"string"},"clubEmail":{"type":"string"},"head":{"$ref":"#/components/schemas/HeadDto"},"memberCount":{"type":"integer","format":"int32"},"minMembersToSubmit":{"type":"integer","format":"int32"},"canSubmit":{"type":"boolean"},"decisionComment":{"type":"string"},"suspendReason":{"type":"string"},"archiveReason":{"type":"string"},"submittedAt":{"type":"string","format":"date-time"},"decidedAt":{"type":"string","format":"date-time"},"lastActivityAt":{"type":"string","format":"date-time"},"myRole":{"type":"string"},"manager":{"type":"boolean"},"owner":{"type":"boolean"},"members":{"type":"array","items":{"$ref":"#/components/schemas/ClubMemberDto"}},"pendingJoinRequests":{"type":"array","items":{"$ref":"#/components/schemas/JoinRequestDto"}},"inviteUrl":{"type":"string"},"changeRequest":{"$ref":"#/components/schemas/ChangeRequestDto"}}},"ClubPostDto":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"clubId":{"type":"string","format":"uuid"},"clubName":{"type":"string"},"clubSlug":{"type":"string"},"authorKeycloakId":{"type":"string"},"authorName":{"type":"string"},"title":{"type":"string"},"body":{"type":"string"},"audience":{"type":"string"},"status":{"type":"string"},"hiddenReason":{"type":"string"},"publishedAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"},"canEdit":{"type":"boolean"},"images":{"type":"array","items":{"$ref":"#/components/schemas/ClubPostImageDto"}}}},"ClubPostImageDto":{"type":"object","properties":{"fileId":{"type":"string","format":"uuid"},"position":{"type":"integer","format":"int32"}}},"EventDirectionDto":{"type":"object","properties":{"code":{"type":"string"},"nameRu":{"type":"string"},"nameKk":{"type":"string"},"nameEn":{"type":"string"},"hintRu":{"type":"string"},"hintKk":{"type":"string"},"hintEn":{"type":"string"},"block":{"type":"string"},"valueBased":{"type":"boolean"},"sortOrder":{"type":"integer","format":"int32"},"active":{"type":"boolean"}}},"ElectionStageDto":{"type":"object","properties":{"code":{"type":"string"},"startDate":{"type":"string","format":"date"},"endDate":{"type":"string","format":"date"}}},"DirectionDto":{"type":"object","properties":{"code":{"type":"string"},"nameRu":{"type":"string"},"nameKk":{"type":"string"},"nameEn":{"type":"string"},"sortOrder":{"type":"integer","format":"int32"},"active":{"type":"boolean"}}},"ConsultationBookingDetailDto":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"date":{"type":"string","format":"date"},"startTime":{"type":"string"},"endTime":{"type":"string"},"status":{"type":"string"},"studentKeycloakId":{"type":"string"},"studentName":{"type":"string"},"studentProgram":{"type":"string"},"studentCourseYear":{"type":"integer","format":"int32"},"reason":{"type":"string"},"reasonErased":{"type":"boolean"},"cancelReason":{"type":"string"},"cancelledByRole":{"type":"string"},"cancelledAt":{"type":"string","format":"date-time"},"markedAt":{"type":"string","format":"date-time"},"rescheduleCount":{"type":"integer","format":"int32"},"previousDate":{"type":"string","format":"date"},"previousStartTime":{"type":"string"},"canMark":{"type":"boolean"},"canChange":{"type":"boolean"},"journal":{"type":"array","items":{"$ref":"#/components/schemas/ConsultationJournalDto"}},"createdAt":{"type":"string","format":"date-time"}}},"ConsultationJournalDto":{"type":"object","properties":{"action":{"type":"string"},"actorRole":{"type":"string"},"details":{"type":"string"},"createdAt":{"type":"string","format":"date-time"}}},"MyAttendanceDto":{"type":"object","properties":{"checkedInAt":{"type":"string","format":"date-time"},"method":{"type":"string"},"role":{"type":"string"},"organizerStatus":{"type":"string"},"staffStatus":{"type":"string"},"reportSubmitted":{"type":"boolean"},"reportRating":{"type":"integer","format":"int32"},"reportText":{"type":"string"},"hasReportPhoto":{"type":"boolean"},"reportSubmittedAt":{"type":"string","format":"date-time"}}},"MyConsultationDto":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"psychologistKeycloakId":{"type":"string"},"psychologistName":{"type":"string"},"date":{"type":"string","format":"date"},"startTime":{"type":"string"},"endTime":{"type":"string"},"status":{"type":"string"},"format":{"type":"string"},"location":{"type":"string"},"onlineUrl":{"type":"string"},"reason":{"type":"string"},"cancelReason":{"type":"string"},"cancelledByRole":{"type":"string"},"cancelledAt":{"type":"string","format":"date-time"},"canChange":{"type":"boolean"},"createdAt":{"type":"string","format":"date-time"}}},"InviteDto":{"type":"object","properties":{"token":{"type":"string"},"url":{"type":"string"},"qrDataUri":{"type":"string"}}},"LedgerEntryDto":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"studentKeycloakId":{"type":"string"},"source":{"type":"string"},"eventId":{"type":"string","format":"uuid"},"clubId":{"type":"string","format":"uuid"},"clubName":{"type":"string"},"externalAchievementId":{"type":"string","format":"uuid"},"title":{"type":"string"},"happenedAt":{"type":"string","format":"date"},"academicYear":{"type":"string"},"role":{"type":"string"},"level":{"type":"string"},"socialCredits":{"type":"number"},"score":{"type":"integer","format":"int32"},"status":{"type":"string"},"note":{"type":"string"},"createdAt":{"type":"string","format":"date-time"},"confirmedAt":{"type":"string","format":"date-time"},"revokedAt":{"type":"string","format":"date-time"},"revokeReason":{"type":"string"}}},"AdminEventSummaryDto":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"kind":{"type":"string"},"clubId":{"type":"string","format":"uuid"},"clubName":{"type":"string"},"title":{"type":"string"},"startsAt":{"type":"string","format":"date-time"},"endsAt":{"type":"string","format":"date-time"},"placeLabel":{"type":"string"},"visibility":{"type":"string"},"status":{"type":"string"},"organizerKeycloakId":{"type":"string"},"organizerName":{"type":"string"},"registeredCount":{"type":"integer","format":"int64"},"attendanceCount":{"type":"integer","format":"int64"},"level":{"type":"string"},"socialCredits":{"type":"number"},"hasPoster":{"type":"boolean"},"reviewRequestedAt":{"type":"string","format":"date-time"},"siteStatus":{"type":"string"},"organizerUnit":{"type":"string"},"targeted":{"type":"boolean"}}},"PageDtoAdminEventSummaryDto":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/AdminEventSummaryDto"}},"page":{"type":"integer","format":"int32"},"size":{"type":"integer","format":"int32"},"total":{"type":"integer","format":"int64"}}},"CheckinMaterialsDto":{"type":"object","properties":{"checkinUrl":{"type":"string"},"token":{"type":"string"},"printedQrDataUri":{"type":"string"},"mode":{"type":"string"}}},"ConsultationStatsDto":{"type":"object","properties":{"from":{"type":"string","format":"date"},"to":{"type":"string","format":"date"},"total":{"type":"integer","format":"int64"},"booked":{"type":"integer","format":"int64"},"completed":{"type":"integer","format":"int64"},"cancelled":{"type":"integer","format":"int64"},"noShow":{"type":"integer","format":"int64"}}},"ConsultationCalendarDto":{"type":"object","properties":{"from":{"type":"string","format":"date"},"to":{"type":"string","format":"date"},"windowStartHour":{"type":"integer","format":"int32"},"windowEndHour":{"type":"integer","format":"int32"},"days":{"type":"array","items":{"$ref":"#/components/schemas/ConsultationDayDto"}}}},"ConsultationBookingRowDto":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"date":{"type":"string","format":"date"},"startTime":{"type":"string"},"endTime":{"type":"string"},"status":{"type":"string"},"studentKeycloakId":{"type":"string"},"studentName":{"type":"string"},"studentProgram":{"type":"string"},"studentCourseYear":{"type":"integer","format":"int32"},"rescheduleCount":{"type":"integer","format":"int32"},"createdAt":{"type":"string","format":"date-time"}}},"PageDtoConsultationBookingRowDto":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/ConsultationBookingRowDto"}},"page":{"type":"integer","format":"int32"},"size":{"type":"integer","format":"int32"},"total":{"type":"integer","format":"int64"}}},"PublicInvitePreviewDto":{"type":"object","properties":{"clubId":{"type":"string","format":"uuid"},"slug":{"type":"string"},"name":{"type":"string"},"direction":{"$ref":"#/components/schemas/DirectionRefDto"},"description":{"type":"string"},"memberCount":{"type":"integer","format":"int32"},"hasLogo":{"type":"boolean"},"status":{"type":"string"}}},"PageDtoPublicEventDto":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/PublicEventDto"}},"page":{"type":"integer","format":"int32"},"size":{"type":"integer","format":"int32"},"total":{"type":"integer","format":"int64"}}},"PublicEventDto":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"title":{"type":"string"},"description":{"type":"string"},"startsAt":{"type":"string","format":"date-time"},"endsAt":{"type":"string","format":"date-time"},"format":{"type":"string"},"placeKind":{"type":"string"},"placeLabel":{"type":"string"},"onlineUrl":{"type":"string"},"clubName":{"type":"string"},"clubSlug":{"type":"string"},"hasPoster":{"type":"boolean"}}},"PageDtoPublicClubDto":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/PublicClubDto"}},"page":{"type":"integer","format":"int32"},"size":{"type":"integer","format":"int32"},"total":{"type":"integer","format":"int64"}}},"PublicClubDto":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"slug":{"type":"string"},"name":{"type":"string"},"direction":{"$ref":"#/components/schemas/DirectionRefDto"},"description":{"type":"string"},"hasLogo":{"type":"boolean"}}},"PublicClubDetailDto":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"slug":{"type":"string"},"name":{"type":"string"},"direction":{"$ref":"#/components/schemas/DirectionRefDto"},"description":{"type":"string"},"purpose":{"type":"string"},"memberCount":{"type":"integer","format":"int32"},"hasLogo":{"type":"boolean"},"upcomingEvents":{"type":"array","items":{"$ref":"#/components/schemas/PublicEventDto"}}}},"InvitePreviewDto":{"type":"object","properties":{"clubId":{"type":"string","format":"uuid"},"slug":{"type":"string"},"name":{"type":"string"},"direction":{"$ref":"#/components/schemas/DirectionRefDto"},"description":{"type":"string"},"memberCount":{"type":"integer","format":"int32"},"hasLogo":{"type":"boolean"},"status":{"type":"string"},"head":{"$ref":"#/components/schemas/HeadDto"},"my":{"$ref":"#/components/schemas/MyClubStateDto"}}},"MyClubStateDto":{"type":"object","properties":{"role":{"type":"string"},"memberStatus":{"type":"string"},"joinRequestStatus":{"type":"string"},"canJoin":{"type":"boolean"},"joinState":{"type":"string"}}},"MyEventSummaryDto":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"title":{"type":"string"},"startsAt":{"type":"string","format":"date-time"},"endsAt":{"type":"string","format":"date-time"},"placeLabel":{"type":"string"},"clubId":{"type":"string","format":"uuid"},"clubName":{"type":"string"},"status":{"type":"string"},"registered":{"type":"boolean"},"noShow":{"type":"boolean"},"checkedIn":{"type":"boolean"},"staffStatus":{"type":"string"},"reportSubmitted":{"type":"boolean"},"canReport":{"type":"boolean"},"organizer":{"type":"boolean"},"hasPoster":{"type":"boolean"}}},"PageDtoMyEventSummaryDto":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/MyEventSummaryDto"}},"page":{"type":"integer","format":"int32"},"size":{"type":"integer","format":"int32"},"total":{"type":"integer","format":"int64"}}},"CandidateCardDto":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"fullName":{"type":"string"},"programName":{"type":"string"},"courseYear":{"type":"integer","format":"int32"}}},"CandidateProfileDto":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"fullName":{"type":"string"},"programName":{"type":"string"},"courseYear":{"type":"integer","format":"int32"},"socialUrl":{"type":"string"},"languages":{"type":"array","items":{"$ref":"#/components/schemas/LanguageDto"}},"achievements":{"type":"array","items":{"$ref":"#/components/schemas/CLUBS_AchievementDto"}},"whyMe":{"type":"string"},"plans":{"type":"string"},"goals":{"type":"string"},"values":{"type":"string"}}},"ConsentSignPayloadDto":{"type":"object","properties":{"pdfBase64":{"type":"string"},"expectedIin":{"type":"string"},"currentCmsBase64":{"type":"string"},"signableXmlBase64":{"type":"string"},"currentContentCmsBase64":{"type":"string"}}},"ElectionMeDto":{"type":"object","properties":{"fullName":{"type":"string"},"programName":{"type":"string"},"courseYear":{"type":"integer","format":"int32"}}},"ElectionResultsDto":{"type":"object","properties":{"turnout":{"$ref":"#/components/schemas/ResultsTurnoutDto"},"candidates":{"type":"array","items":{"$ref":"#/components/schemas/ResultCandidateDto"}},"tieResolvedByCommission":{"type":"boolean"},"publishedAt":{"type":"string","format":"date-time"}}},"MyApplicationBriefDto":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"status":{"type":"string"},"decisionComment":{"type":"string"},"removalReason":{"type":"string"},"canEdit":{"type":"boolean"},"canWithdraw":{"type":"boolean"},"consentSigned":{"type":"boolean"},"canSignConsent":{"type":"boolean"}}},"MyElectionDto":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"academicYear":{"type":"string"},"today":{"type":"string","format":"date"},"phase":{"type":"string"},"stages":{"type":"array","items":{"$ref":"#/components/schemas/ElectionStageDto"}},"eligible":{"type":"boolean"},"debatesEventId":{"type":"string","format":"uuid"},"candidatesVisible":{"type":"boolean"},"votingOpen":{"type":"boolean"},"hasVoted":{"type":"boolean"},"voteAnnulled":{"type":"boolean"},"voteAnnulReason":{"type":"string"},"me":{"$ref":"#/components/schemas/ElectionMeDto"},"myApplication":{"$ref":"#/components/schemas/MyApplicationBriefDto"},"results":{"$ref":"#/components/schemas/ElectionResultsDto"}}},"MyElectionResponse":{"type":"object","properties":{"election":{"$ref":"#/components/schemas/MyElectionDto"}}},"ResultCandidateDto":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"fullName":{"type":"string"},"programName":{"type":"string"},"courseYear":{"type":"integer","format":"int32"},"votes":{"type":"integer","format":"int64"},"percent":{"type":"number","format":"double"},"winner":{"type":"boolean"}}},"ResultsTurnoutDto":{"type":"object","properties":{"voted":{"type":"integer","format":"int64"},"eligible":{"type":"integer","format":"int32"},"percent":{"type":"number","format":"double"}}},"MyConsultationsDto":{"type":"object","properties":{"active":{"$ref":"#/components/schemas/MyConsultationDto"},"history":{"type":"array","items":{"$ref":"#/components/schemas/MyConsultationDto"}}}},"ConsultationSlotsDayDto":{"type":"object","properties":{"date":{"type":"string","format":"date"},"available":{"type":"boolean"},"times":{"type":"array","items":{"$ref":"#/components/schemas/ConsultationTimeDto"}}}},"ConsultationSlotsDto":{"type":"object","properties":{"psychologistKeycloakId":{"type":"string"},"horizonFrom":{"type":"string","format":"date"},"horizonTo":{"type":"string","format":"date"},"days":{"type":"array","items":{"$ref":"#/components/schemas/ConsultationSlotsDayDto"}}}},"ConsultationTimeDto":{"type":"object","properties":{"startTime":{"type":"string"},"endTime":{"type":"string"}}},"ConsultationPsychologistDto":{"type":"object","properties":{"keycloakId":{"type":"string"},"displayName":{"type":"string"},"format":{"type":"string"},"location":{"type":"string"}}},"MyClubSummaryDto":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"slug":{"type":"string"},"name":{"type":"string"},"direction":{"$ref":"#/components/schemas/DirectionRefDto"},"status":{"type":"string"},"role":{"type":"string"},"memberStatus":{"type":"string"},"memberCount":{"type":"integer","format":"int32"},"hasLogo":{"type":"boolean"},"joinedAt":{"type":"string","format":"date-time"},"lastActivityAt":{"type":"string","format":"date-time"}}},"ClubCreationAccessDto":{"type":"object","properties":{"allowed":{"type":"boolean"},"reason":{"type":"string"}}},"CheckinEventDto":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"title":{"type":"string"},"startsAt":{"type":"string","format":"date-time"},"endsAt":{"type":"string","format":"date-time"},"placeLabel":{"type":"string"},"clubName":{"type":"string"}}},"CheckinPreviewDto":{"type":"object","properties":{"event":{"$ref":"#/components/schemas/CheckinEventDto"},"state":{"type":"string"},"reason":{"type":"string"},"canCheckIn":{"type":"boolean"}}},"ActivityDto":{"type":"object","properties":{"academicYear":{"type":"string"},"entries":{"type":"array","items":{"$ref":"#/components/schemas/LedgerEntryDto"}},"confirmedEntries":{"type":"integer","format":"int64"},"confirmedCredits":{"type":"number"},"ssci100":{"type":"number"},"ssciGpa":{"type":"number"},"gpa":{"type":"number"},"iros":{"type":"number"},"igpaPreliminary":{"type":"number"},"weights":{"$ref":"#/components/schemas/IgpaWeightsDto"},"preliminary":{"type":"boolean"},"availableYears":{"type":"array","items":{"type":"string"}}}},"IgpaWeightsDto":{"type":"object","properties":{"gpa":{"type":"number"},"iros":{"type":"number"},"ssci":{"type":"number"}}},"HealthDto":{"type":"object","properties":{"status":{"type":"string"},"service":{"type":"string"},"activeClubs":{"type":"integer","format":"int64"}}},"PageDtoClubPostDto":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/ClubPostDto"}},"page":{"type":"integer","format":"int32"},"size":{"type":"integer","format":"int32"},"total":{"type":"integer","format":"int64"}}},"CatalogEventDto":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"kind":{"type":"string"},"clubId":{"type":"string","format":"uuid"},"clubName":{"type":"string"},"clubSlug":{"type":"string"},"title":{"type":"string"},"startsAt":{"type":"string","format":"date-time"},"endsAt":{"type":"string","format":"date-time"},"format":{"type":"string"},"placeKind":{"type":"string"},"placeLabel":{"type":"string"},"onlineUrl":{"type":"string"},"visibility":{"type":"string"},"status":{"type":"string"},"hasPoster":{"type":"boolean"},"registrationEnabled":{"type":"boolean"},"capacity":{"type":"integer","format":"int32"},"registeredCount":{"type":"integer","format":"int64"},"registered":{"type":"boolean"},"checkedIn":{"type":"boolean"},"organizerUnit":{"type":"string"},"contactInfo":{"type":"string"},"listState":{"type":"string"}}},"PageDtoCatalogEventDto":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/CatalogEventDto"}},"page":{"type":"integer","format":"int32"},"size":{"type":"integer","format":"int32"},"total":{"type":"integer","format":"int64"}}},"CatalogEventDetailDto":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"kind":{"type":"string"},"clubId":{"type":"string","format":"uuid"},"clubName":{"type":"string"},"clubSlug":{"type":"string"},"title":{"type":"string"},"description":{"type":"string"},"startsAt":{"type":"string","format":"date-time"},"endsAt":{"type":"string","format":"date-time"},"format":{"type":"string"},"placeKind":{"type":"string"},"placeLabel":{"type":"string"},"onlineUrl":{"type":"string"},"roomId":{"type":"string","format":"uuid"},"direction":{"$ref":"#/components/schemas/EventDirectionRefDto"},"visibility":{"type":"string"},"status":{"type":"string"},"hasPoster":{"type":"boolean"},"registrationEnabled":{"type":"boolean"},"capacity":{"type":"integer","format":"int32"},"registrationClosesAt":{"type":"string","format":"date-time"},"registeredCount":{"type":"integer","format":"int64"},"checkinMode":{"type":"string"},"checkinWindowBeforeMin":{"type":"integer","format":"int32"},"organizerName":{"type":"string"},"level":{"type":"string"},"socialCredits":{"type":"number"},"cancelReason":{"type":"string"},"my":{"$ref":"#/components/schemas/MyEventStateDto"},"organizerUnit":{"type":"string"},"contactInfo":{"type":"string"},"listState":{"type":"string"}}},"MyEventStateDto":{"type":"object","properties":{"registrationStatus":{"type":"string"},"registrationState":{"type":"string"},"canRegister":{"type":"boolean"},"canCancelRegistration":{"type":"boolean"},"checkinState":{"type":"string"},"attendance":{"$ref":"#/components/schemas/MyAttendanceDto"},"canReport":{"type":"boolean"},"reportDeadline":{"type":"string","format":"date-time"},"organizer":{"type":"boolean"}}},"CatalogClubDto":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"slug":{"type":"string"},"name":{"type":"string"},"direction":{"$ref":"#/components/schemas/DirectionRefDto"},"description":{"type":"string"},"memberCount":{"type":"integer","format":"int32"},"hasLogo":{"type":"boolean"},"joinMode":{"type":"string"},"myRole":{"type":"string"}}},"PageDtoCatalogClubDto":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/CatalogClubDto"}},"page":{"type":"integer","format":"int32"},"size":{"type":"integer","format":"int32"},"total":{"type":"integer","format":"int64"}}},"CatalogClubDetailDto":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"slug":{"type":"string"},"name":{"type":"string"},"direction":{"$ref":"#/components/schemas/DirectionRefDto"},"description":{"type":"string"},"purpose":{"type":"string"},"status":{"type":"string"},"memberCount":{"type":"integer","format":"int32"},"hasLogo":{"type":"boolean"},"head":{"$ref":"#/components/schemas/HeadDto"},"joinMode":{"type":"string"},"contactEmail":{"type":"string"},"contactPhone":{"type":"string"},"suspendReason":{"type":"string"},"planItems":{"type":"array","items":{"$ref":"#/components/schemas/ClubPlanItemDto"}},"my":{"$ref":"#/components/schemas/MyClubStateDto"},"upcomingEvents":{"type":"array","items":{"$ref":"#/components/schemas/CatalogEventDto"}}}},"TaskDto":{"type":"object","properties":{"id":{"type":"string"},"projectId":{"type":"string"},"projectTitle":{"type":"string"},"milestoneId":{"type":"string"},"milestoneTitle":{"type":"string"},"title":{"type":"string"},"description":{"type":"string"},"assigneeKeycloakId":{"type":"string"},"assigneeName":{"type":"string"},"dueOn":{"type":"string","format":"date"},"priority":{"type":"string"},"status":{"type":"string"},"supervisorComment":{"type":"string"},"mine":{"type":"boolean"},"doneAt":{"type":"string","format":"date-time"},"createdAt":{"type":"string","format":"date-time"}}},"MilestoneDto":{"type":"object","properties":{"id":{"type":"string"},"title":{"type":"string"},"orderIndex":{"type":"integer","format":"int32"},"dueOn":{"type":"string","format":"date"},"status":{"type":"string"},"resultText":{"type":"string"},"ownerKeycloakId":{"type":"string"},"doneAt":{"type":"string","format":"date-time"}}},"AdminOpportunityDto":{"type":"object","properties":{"id":{"type":"string"},"kind":{"type":"string"},"title":{"type":"string"},"problemText":{"type":"string"},"expectedResult":{"type":"string"},"selectionCriteria":{"type":"string"},"customerName":{"type":"string"},"labId":{"type":"string"},"labName":{"type":"string"},"projectId":{"type":"string"},"projectTitle":{"type":"string"},"compensationKind":{"type":"string"},"mentorProvided":{"type":"boolean"},"budget":{"$ref":"#/components/schemas/BudgetDto"},"budgetVisibleToStudents":{"type":"boolean"},"format":{"type":"string"},"headcount":{"type":"integer","format":"int32"},"startsOn":{"type":"string","format":"date"},"endsOn":{"type":"string","format":"date"},"applyDeadline":{"type":"string","format":"date"},"beginnerFriendly":{"type":"boolean"},"recruiting":{"type":"boolean"},"status":{"type":"string"},"authorKeycloakId":{"type":"string"},"authorName":{"type":"string"},"authorKind":{"type":"string"},"proposedSupervisorKeycloakId":{"type":"string"},"proposedSupervisorName":{"type":"string"},"supervisorKeycloakId":{"type":"string"},"supervisorName":{"type":"string"},"submittedAt":{"type":"string","format":"date-time"},"decidedAt":{"type":"string","format":"date-time"},"decidedBy":{"type":"string"},"decisionComment":{"type":"string"},"publishedAt":{"type":"string","format":"date-time"},"closedAt":{"type":"string","format":"date-time"},"viewsCount":{"type":"integer","format":"int64"},"applicationsCount":{"type":"integer","format":"int64"},"pendingApplicationsCount":{"type":"integer","format":"int64"},"skills":{"type":"array","items":{"$ref":"#/components/schemas/PROJECTS_SkillOptionDto"}},"desiredSkills":{"type":"array","items":{"$ref":"#/components/schemas/PROJECTS_SkillOptionDto"}},"roles":{"type":"array","items":{"$ref":"#/components/schemas/RoleSlotDto"}},"createdAt":{"type":"string","format":"date-time"}}},"BudgetDto":{"type":"object","properties":{"amount":{"type":"number"},"currency":{"type":"string"}}},"RoleSlotDto":{"type":"object","properties":{"code":{"type":"string"},"name":{"type":"string"},"headcount":{"type":"integer","format":"int32"},"filled":{"type":"integer","format":"int32"}}},"PROJECTS_SkillOptionDto":{"type":"object","properties":{"skillId":{"type":"string"},"code":{"type":"string"},"name":{"type":"string"}}},"ResourceDto":{"type":"object","properties":{"id":{"type":"string"},"kind":{"type":"string"},"name":{"type":"string"},"description":{"type":"string"},"labId":{"type":"string"},"labName":{"type":"string"},"specs":{"type":"object","additionalProperties":{}},"sensitive":{"type":"boolean"},"requiresApproval":{"type":"boolean"},"status":{"type":"string"}}},"ResourceRequestDto":{"type":"object","properties":{"id":{"type":"string"},"projectId":{"type":"string"},"projectTitle":{"type":"string"},"kind":{"type":"string"},"resourceId":{"type":"string"},"resourceName":{"type":"string"},"params":{"type":"object","additionalProperties":{}},"purpose":{"type":"string"},"justification":{"type":"string"},"periodFrom":{"type":"string","format":"date"},"periodTo":{"type":"string","format":"date"},"status":{"type":"string"},"stage":{"type":"string"},"requestedBy":{"type":"string"},"requestedByName":{"type":"string"},"submittedAt":{"type":"string","format":"date-time"},"endorsedBy":{"type":"string"},"endorsedByName":{"type":"string"},"endorsedAt":{"type":"string","format":"date-time"},"reviewerComment":{"type":"string"},"decidedAt":{"type":"string","format":"date-time"},"parentRequestId":{"type":"string"},"aiSuggested":{"type":"boolean"},"createdAt":{"type":"string","format":"date-time"}}},"AllocationDto":{"type":"object","properties":{"id":{"type":"string"},"requestId":{"type":"string"},"projectId":{"type":"string"},"projectTitle":{"type":"string"},"resourceId":{"type":"string"},"resourceName":{"type":"string"},"kind":{"type":"string"},"limits":{"type":"object","additionalProperties":{}},"accessFrom":{"type":"string","format":"date-time"},"accessUntil":{"type":"string","format":"date-time"},"workspaceUrl":{"type":"string"},"status":{"type":"string"},"expiringSoon":{"type":"boolean"},"grantedAt":{"type":"string","format":"date-time"},"releasedAt":{"type":"string","format":"date-time"}}},"ContributionDto":{"type":"object","properties":{"id":{"type":"string"},"projectId":{"type":"string"},"projectTitle":{"type":"string"},"keycloakId":{"type":"string"},"studentName":{"type":"string"},"title":{"type":"string"},"description":{"type":"string"},"tasks":{"type":"array","items":{"$ref":"#/components/schemas/TaskRefDto"}},"skills":{"type":"array","items":{"$ref":"#/components/schemas/PROJECTS_SkillOptionDto"}},"status":{"type":"string"},"evidenceState":{"type":"string"},"decisionComment":{"type":"string"},"submittedAt":{"type":"string","format":"date-time"},"confirmedAt":{"type":"string","format":"date-time"},"confirmedByName":{"type":"string"},"createdAt":{"type":"string","format":"date-time"}}},"DeliverableDto":{"type":"object","properties":{"id":{"type":"string"},"projectId":{"type":"string"},"milestoneId":{"type":"string"},"milestoneTitle":{"type":"string"},"kind":{"type":"string"},"title":{"type":"string"},"description":{"type":"string"},"linkUrl":{"type":"string"},"status":{"type":"string"},"version":{"type":"integer","format":"int32"},"submittedBy":{"type":"string"},"submittedByName":{"type":"string"},"submittedAt":{"type":"string","format":"date-time"},"decidedBy":{"type":"string"},"decidedByName":{"type":"string"},"decidedAt":{"type":"string","format":"date-time"},"decisionComment":{"type":"string"},"files":{"type":"array","items":{"$ref":"#/components/schemas/DeliverableFileDto"}}}},"DeliverableFileDto":{"type":"object","properties":{"fileId":{"type":"string"},"fileName":{"type":"string"}}},"PROJECTS_Item":{"type":"object","properties":{"code":{"type":"string"},"tier":{"type":"string"},"nameRu":{"type":"string"},"nameKk":{"type":"string"},"nameEn":{"type":"string"}}},"PROJECTS_MemberShowcaseDto":{"type":"object","properties":{"level":{"type":"integer","format":"int32"},"levelNameRu":{"type":"string"},"levelNameKk":{"type":"string"},"levelNameEn":{"type":"string"},"achievements":{"type":"array","items":{"$ref":"#/components/schemas/PROJECTS_Item"}}}},"ProjectMemberDto":{"type":"object","properties":{"keycloakId":{"type":"string"},"displayName":{"type":"string"},"roleCode":{"type":"string"},"roleName":{"type":"string"},"status":{"type":"string"},"joinedAt":{"type":"string","format":"date-time"},"taskCount":{"type":"integer","format":"int32"},"confirmedSkills":{"type":"array","items":{"$ref":"#/components/schemas/PROJECTS_SkillOptionDto"}},"showcase":{"$ref":"#/components/schemas/PROJECTS_MemberShowcaseDto"}}},"ProjectRightsDto":{"type":"object","properties":{"canEditTasks":{"type":"boolean"},"canDecideDeliverable":{"type":"boolean"},"canConfirmContribution":{"type":"boolean"},"canEndorseResource":{"type":"boolean"},"canSubmitDeliverable":{"type":"boolean"},"canClaimContribution":{"type":"boolean"},"canModerate":{"type":"boolean"}}},"SupervisorProjectDto":{"type":"object","properties":{"id":{"type":"string"},"kind":{"type":"string"},"title":{"type":"string"},"status":{"type":"string"},"expectedResult":{"type":"string"},"repositoryUrl":{"type":"string"},"customerName":{"type":"string"},"labId":{"type":"string"},"labName":{"type":"string"},"opportunityId":{"type":"string"},"startsOn":{"type":"string","format":"date"},"endsOn":{"type":"string","format":"date"},"closeComment":{"type":"string"},"team":{"type":"array","items":{"$ref":"#/components/schemas/ProjectMemberDto"}},"milestones":{"type":"array","items":{"$ref":"#/components/schemas/MilestoneDto"}},"tasks":{"type":"array","items":{"$ref":"#/components/schemas/TaskDto"}},"deliverables":{"type":"array","items":{"$ref":"#/components/schemas/DeliverableDto"}},"contributions":{"type":"array","items":{"$ref":"#/components/schemas/ContributionDto"}},"allocations":{"type":"array","items":{"$ref":"#/components/schemas/AllocationDto"}},"resourceRequests":{"type":"array","items":{"$ref":"#/components/schemas/ResourceRequestDto"}},"rights":{"$ref":"#/components/schemas/ProjectRightsDto"}}},"TaskRefDto":{"type":"object","properties":{"id":{"type":"string"},"title":{"type":"string"},"status":{"type":"string"}}},"ApplicationDto":{"type":"object","properties":{"id":{"type":"string"},"opportunityId":{"type":"string"},"opportunityTitle":{"type":"string"},"opportunityOwner":{"type":"string"},"kind":{"type":"string"},"status":{"type":"string"},"authorKeycloakId":{"type":"string"},"authorName":{"type":"string"},"desiredRoleCode":{"type":"string"},"desiredRoleName":{"type":"string"},"motivation":{"type":"string"},"availability":{"type":"string"},"portfolioLink":{"type":"string"},"relevantWorks":{"type":"string"},"confirmedSkills":{"type":"array","items":{"$ref":"#/components/schemas/PROJECTS_SkillOptionDto"}},"teamMembers":{"type":"array","items":{"$ref":"#/components/schemas/ApplicationMemberDto"}},"teamAnswered":{"type":"integer","format":"int32"},"teamSize":{"type":"integer","format":"int32"},"decisionComment":{"type":"string"},"decidedAt":{"type":"string","format":"date-time"},"createdAt":{"type":"string","format":"date-time"}}},"ApplicationMemberDto":{"type":"object","properties":{"keycloakId":{"type":"string"},"displayName":{"type":"string"},"roleCode":{"type":"string"},"roleName":{"type":"string"},"inviteStatus":{"type":"string"},"respondedAt":{"type":"string","format":"date-time"}}},"MyProposalDto":{"type":"object","properties":{"id":{"type":"string"},"title":{"type":"string"},"status":{"type":"string"},"decisionComment":{"type":"string"},"submittedAt":{"type":"string","format":"date-time"},"decidedAt":{"type":"string","format":"date-time"},"supervisorKeycloakId":{"type":"string"},"supervisorName":{"type":"string"},"projectId":{"type":"string"},"skills":{"type":"array","items":{"$ref":"#/components/schemas/PROJECTS_SkillOptionDto"}}}},"SupervisorProjectCardDto":{"type":"object","properties":{"id":{"type":"string"},"kind":{"type":"string"},"title":{"type":"string"},"status":{"type":"string"},"teamSize":{"type":"integer","format":"int32"},"pendingApplications":{"type":"integer","format":"int64"},"pendingContributions":{"type":"integer","format":"int64"},"pendingDeliverables":{"type":"integer","format":"int64"},"pendingResourceRequests":{"type":"integer","format":"int64"},"startsOn":{"type":"string","format":"date"},"endsOn":{"type":"string","format":"date"}}},"MyProjectCardDto":{"type":"object","properties":{"id":{"type":"string"},"kind":{"type":"string"},"title":{"type":"string"},"status":{"type":"string"},"myRoleCode":{"type":"string"},"myRoleName":{"type":"string"},"supervisorKeycloakId":{"type":"string"},"supervisorName":{"type":"string"},"teamSize":{"type":"integer","format":"int32"},"team":{"type":"array","items":{"$ref":"#/components/schemas/ProjectMemberDto"}},"nextTask":{"$ref":"#/components/schemas/TaskDto"},"tasksDone":{"type":"integer","format":"int32"},"tasksTotal":{"type":"integer","format":"int32"},"startsOn":{"type":"string","format":"date"},"endsOn":{"type":"string","format":"date"}}},"MyProjectDto":{"type":"object","properties":{"id":{"type":"string"},"kind":{"type":"string"},"title":{"type":"string"},"status":{"type":"string"},"expectedResult":{"type":"string"},"repositoryUrl":{"type":"string"},"customerName":{"type":"string"},"labId":{"type":"string"},"labName":{"type":"string"},"supervisorKeycloakId":{"type":"string"},"supervisorName":{"type":"string"},"myRoleCode":{"type":"string"},"myRoleName":{"type":"string"},"startsOn":{"type":"string","format":"date"},"endsOn":{"type":"string","format":"date"},"team":{"type":"array","items":{"$ref":"#/components/schemas/ProjectMemberDto"}},"milestones":{"type":"array","items":{"$ref":"#/components/schemas/MilestoneDto"}},"myTasks":{"type":"array","items":{"$ref":"#/components/schemas/TaskDto"}},"deliverables":{"type":"array","items":{"$ref":"#/components/schemas/DeliverableDto"}},"contributions":{"type":"array","items":{"$ref":"#/components/schemas/ContributionDto"}},"allocations":{"type":"array","items":{"$ref":"#/components/schemas/AllocationDto"}},"resourceRequests":{"type":"array","items":{"$ref":"#/components/schemas/ResourceRequestDto"}},"rights":{"$ref":"#/components/schemas/ProjectRightsDto"}}},"OpportunityCardDto":{"type":"object","properties":{"id":{"type":"string"},"kind":{"type":"string"},"title":{"type":"string"},"customerName":{"type":"string"},"labName":{"type":"string"},"projectId":{"type":"string"},"projectTitle":{"type":"string"},"expectedResult":{"type":"string"},"compensationKind":{"type":"string"},"paid":{"type":"boolean"},"budget":{"$ref":"#/components/schemas/BudgetDto"},"format":{"type":"string"},"headcount":{"type":"integer","format":"int32"},"applyDeadline":{"type":"string","format":"date"},"beginnerFriendly":{"type":"boolean"},"recruiting":{"type":"boolean"},"status":{"type":"string"},"publishedAt":{"type":"string","format":"date-time"},"supervisorKeycloakId":{"type":"string"},"supervisorName":{"type":"string"},"skills":{"type":"array","items":{"$ref":"#/components/schemas/PROJECTS_SkillOptionDto"}},"roles":{"type":"array","items":{"$ref":"#/components/schemas/RoleSlotDto"}},"bookmarked":{"type":"boolean"}}},"PageDtoOpportunityCardDto":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/OpportunityCardDto"}},"page":{"type":"integer","format":"int32"},"size":{"type":"integer","format":"int32"},"total":{"type":"integer","format":"int64"}}},"MyMembershipDto":{"type":"object","properties":{"projectId":{"type":"string"}}},"OpportunityDetailDto":{"type":"object","properties":{"id":{"type":"string"},"kind":{"type":"string"},"title":{"type":"string"},"problemText":{"type":"string"},"expectedResult":{"type":"string"},"selectionCriteria":{"type":"string"},"customerName":{"type":"string"},"labId":{"type":"string"},"labName":{"type":"string"},"projectId":{"type":"string"},"projectTitle":{"type":"string"},"compensationKind":{"type":"string"},"paid":{"type":"boolean"},"mentorProvided":{"type":"boolean"},"budget":{"$ref":"#/components/schemas/BudgetDto"},"format":{"type":"string"},"headcount":{"type":"integer","format":"int32"},"startsOn":{"type":"string","format":"date"},"endsOn":{"type":"string","format":"date"},"applyDeadline":{"type":"string","format":"date"},"beginnerFriendly":{"type":"boolean"},"recruiting":{"type":"boolean"},"status":{"type":"string"},"publishedAt":{"type":"string","format":"date-time"},"supervisorKeycloakId":{"type":"string"},"supervisorName":{"type":"string"},"skills":{"type":"array","items":{"$ref":"#/components/schemas/PROJECTS_SkillOptionDto"}},"desiredSkills":{"type":"array","items":{"$ref":"#/components/schemas/PROJECTS_SkillOptionDto"}},"roles":{"type":"array","items":{"$ref":"#/components/schemas/RoleSlotDto"}},"resources":{"type":"array","items":{"$ref":"#/components/schemas/ResourceDto"}},"myConfirmedSkills":{"type":"array","items":{"$ref":"#/components/schemas/PROJECTS_SkillOptionDto"}},"bookmarked":{"type":"boolean"},"teamAllowed":{"type":"boolean"},"applyBlocked":{"type":"boolean"},"applyBlockedCode":{"type":"string"},"myApplicationId":{"type":"string"},"myApplicationStatus":{"type":"string"},"myMembership":{"$ref":"#/components/schemas/MyMembershipDto"}}},"InviteCandidateDto":{"type":"object","properties":{"keycloakId":{"type":"string"},"fullName":{"type":"string"},"programCode":{"type":"string"},"courseYear":{"type":"integer","format":"int32"}}},"TeamInvitationDto":{"type":"object","properties":{"id":{"type":"string"},"applicationId":{"type":"string"},"opportunityId":{"type":"string"},"opportunityTitle":{"type":"string"},"authorKeycloakId":{"type":"string"},"authorName":{"type":"string"},"roleCode":{"type":"string"},"roleName":{"type":"string"},"inviteStatus":{"type":"string"},"applyDeadline":{"type":"string","format":"date"},"createdAt":{"type":"string","format":"date-time"}}},"PROJECTS_HealthDto":{"type":"object","properties":{"status":{"type":"string"},"service":{"type":"string"},"activeProjects":{"type":"integer","format":"int64"}}},"RoleOptionDto":{"type":"object","properties":{"code":{"type":"string"},"name":{"type":"string"},"orderIndex":{"type":"integer","format":"int32"}}},"LabOptionDto":{"type":"object","properties":{"id":{"type":"string"},"code":{"type":"string"},"name":{"type":"string"}}},"IdeaAiDto":{"type":"object","properties":{"status":{"type":"string"},"summary":{"type":"string"},"locale":{"type":"string"},"generatedAt":{"type":"string","format":"date-time"}}},"IdeaAuthorDto":{"type":"object","properties":{"keycloakId":{"type":"string"},"fullName":{"type":"string"},"username":{"type":"string"},"programCode":{"type":"string"},"programName":{"type":"string"},"courseYear":{"type":"integer","format":"int32"},"degreeLevel":{"type":"string"}}},"IdeaFileDto":{"type":"object","properties":{"id":{"type":"integer","format":"int64"},"fileId":{"type":"string"},"fileName":{"type":"string"},"mimeType":{"type":"string"},"sizeBytes":{"type":"integer","format":"int64"}}},"IdeaResponse":{"type":"object","properties":{"id":{"type":"integer","format":"int64"},"title":{"type":"string"},"body":{"type":"string"},"status":{"type":"string"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"},"author":{"$ref":"#/components/schemas/IdeaAuthorDto"},"files":{"type":"array","items":{"$ref":"#/components/schemas/IdeaFileDto"}},"responseText":{"type":"string"},"handledByName":{"type":"string"},"handledAt":{"type":"string","format":"date-time"},"ai":{"$ref":"#/components/schemas/IdeaAiDto"}}},"ComplaintAuthorDto":{"type":"object","properties":{"keycloakId":{"type":"string"},"fullName":{"type":"string"},"username":{"type":"string"},"roles":{"type":"array","items":{"type":"string"}},"programCode":{"type":"string"},"programName":{"type":"string"},"courseYear":{"type":"integer","format":"int32"}}},"ComplaintContextDto":{"type":"object","properties":{"app":{"type":"string"},"pageUrl":{"type":"string"},"pagePath":{"type":"string"},"pageTitle":{"type":"string"},"locale":{"type":"string"},"userAgent":{"type":"string"},"viewport":{"type":"string"},"screen":{"type":"string"},"timezone":{"type":"string"},"referrer":{"type":"string"},"clientTime":{"type":"string","format":"date-time"}}},"ComplaintFileDto":{"type":"object","properties":{"id":{"type":"integer","format":"int64"},"fileId":{"type":"string"},"fileName":{"type":"string"},"mimeType":{"type":"string"},"sizeBytes":{"type":"integer","format":"int64"}}},"ComplaintResponse":{"type":"object","properties":{"id":{"type":"integer","format":"int64"},"title":{"type":"string"},"body":{"type":"string"},"status":{"type":"string"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"},"author":{"$ref":"#/components/schemas/ComplaintAuthorDto"},"context":{"$ref":"#/components/schemas/ComplaintContextDto"},"files":{"type":"array","items":{"$ref":"#/components/schemas/ComplaintFileDto"}},"responseText":{"type":"string"},"handledByName":{"type":"string"},"handledAt":{"type":"string","format":"date-time"}}},"IdeaPageResponse":{"type":"object","properties":{"content":{"type":"array","items":{"$ref":"#/components/schemas/IdeaResponse"}},"page":{"type":"integer","format":"int32"},"size":{"type":"integer","format":"int32"},"totalElements":{"type":"integer","format":"int64"},"totalPages":{"type":"integer","format":"int32"}}},"ComplaintPageResponse":{"type":"object","properties":{"content":{"type":"array","items":{"$ref":"#/components/schemas/ComplaintResponse"}},"page":{"type":"integer","format":"int32"},"size":{"type":"integer","format":"int32"},"totalElements":{"type":"integer","format":"int64"},"totalPages":{"type":"integer","format":"int32"}}}}}}