{
  "openapi": "3.0.4",
  "info": {
    "title": "UniVerse API",
    "description": "REST API веб-платформы UniVerse.\n\nАутентификация: JWT Bearer (получить через `POST /api/v1/auth/login/microsoft` или `POST /api/v1/auth/login/dev` в Development).",
    "contact": {
      "name": "UniVerse Dev"
    },
    "version": "v1"
  },
  "paths": {
    "/api/v1/achievements": {
      "get": {
        "tags": [
          "Achievements"
        ],
        "summary": "Получить список всех достижений.",
        "description": "Возвращает определения достижений (без информации о получении конкретным пользователем).\n            Для достижений конкретного пользователя используйте GET /api/v1/users/{id}/achievements.\n\n**Required:** any authenticated user",
        "responses": {
          "200": {
            "description": "Список достижений.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/AchievementDto"
                  }
                }
              }
            }
          },
          "401": {
            "description": "Требуется аутентификация.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "Bearer": [ ]
          }
        ]
      },
      "post": {
        "tags": [
          "Achievements"
        ],
        "summary": "Создать новое достижение.",
        "description": "Только Admin. Достижения автоматически присваиваются студентам при выполнении условий.\n\n**Required roles:** Admin",
        "requestBody": {
          "description": "Название, описание, иконка, награда в XP/монетах и условие получения.",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateAchievementRequest"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateAchievementRequest"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/CreateAchievementRequest"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Достижение создано.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AchievementDto"
                }
              }
            }
          },
          "401": {
            "description": "Требуется аутентификация.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Требуется роль Admin.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "Bearer": [ ]
          }
        ]
      }
    },
    "/api/v1/achievements/{id}": {
      "get": {
        "tags": [
          "Achievements"
        ],
        "summary": "Получить достижение по ID.",
        "description": "**Required:** any authenticated user",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "ID достижения.",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Данные достижения.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AchievementDto"
                }
              }
            }
          },
          "401": {
            "description": "Требуется аутентификация.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Достижение не найдено.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "Bearer": [ ]
          }
        ]
      },
      "put": {
        "tags": [
          "Achievements"
        ],
        "summary": "Обновить достижение по ID.",
        "description": "Только Admin.\n\n**Required roles:** Admin",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "ID достижения.",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          }
        ],
        "requestBody": {
          "description": "Обновляемые поля достижения.",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateAchievementRequest"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateAchievementRequest"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateAchievementRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Обновлённые данные достижения.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AchievementDto"
                }
              }
            }
          },
          "401": {
            "description": "Требуется аутентификация.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Требуется роль Admin.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Достижение не найдено.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "Bearer": [ ]
          }
        ]
      },
      "delete": {
        "tags": [
          "Achievements"
        ],
        "summary": "Удалить достижение по ID.",
        "description": "Только Admin. Удаление не отзывает достижение у уже получивших его пользователей.\n\n**Required roles:** Admin",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "ID достижения.",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Достижение удалено."
          },
          "401": {
            "description": "Требуется аутентификация.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Требуется роль Admin.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Достижение не найдено.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "Bearer": [ ]
          }
        ]
      }
    },
    "/api/v1/auth/login/microsoft": {
      "post": {
        "tags": [
          "Auth"
        ],
        "summary": "Вход через Microsoft Entra ID (SPA/PKCE flow).",
        "description": "Фронтенд самостоятельно обрабатывает редирект к Microsoft и передаёт сюда\nполученный authorization code. В ответ возвращается пара JWT-токенов;\nrefresh token устанавливается в HttpOnly cookie.",
        "requestBody": {
          "description": "Authorization code и redirect URI из Microsoft OAuth2.",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/LoginMicrosoftRequest"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/LoginMicrosoftRequest"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/LoginMicrosoftRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Успешный вход — возвращает access token и данные пользователя.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AuthResponse"
                }
              }
            }
          },
          "400": {
            "description": "Неверный или просроченный authorization code.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        }
      },
      "get": {
        "tags": [
          "Auth"
        ],
        "summary": "Инициация server-driven входа через Microsoft (редирект-flow).",
        "description": "Браузер переходит на этот URL; backend строит Microsoft authorize URL с CSRF state\nи редиректит пользователя на `login.microsoftonline.com`.\nПосле успешного входа Microsoft редиректит на `GET /api/v1/auth/callback/microsoft`.",
        "parameters": [
          {
            "name": "returnUrl",
            "in": "query",
            "description": "URL для редиректа после успешного входа (опционально).",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "302": {
            "description": "Редирект на Microsoft authorize endpoint."
          },
          "500": {
            "description": "Microsoft authentication не настроен (AzureAd:TenantId/ClientId отсутствуют)."
          }
        }
      }
    },
    "/api/v1/auth/callback/microsoft": {
      "get": {
        "tags": [
          "Auth"
        ],
        "summary": "OAuth2 callback — обмен code на токены (server-driven flow).",
        "description": "Microsoft редиректит браузер сюда после успешного входа.\nBackend валидирует CSRF state, обменивает code на токены,\nустанавливает refresh token cookie и редиректит на `returnUrl` с access token в URL-фрагменте.",
        "parameters": [
          {
            "name": "code",
            "in": "query",
            "description": "Authorization code от Microsoft.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "state",
            "in": "query",
            "description": "CSRF state для верификации.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "error",
            "in": "query",
            "description": "Код ошибки от Microsoft (если вход не удался).",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "error_description",
            "in": "query",
            "description": "Описание ошибки от Microsoft.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Если returnUrl не задан — возвращает JSON с токенами (удобно для тестирования).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AuthResponse"
                }
              }
            }
          },
          "302": {
            "description": "Успешный вход — редирект на returnUrl с токеном в URL-фрагменте."
          },
          "400": {
            "description": "Отсутствует authorization code.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "Ошибка от Microsoft или невалидный CSRF state.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/auth/login/dev": {
      "post": {
        "tags": [
          "Auth"
        ],
        "summary": "Dev-only вход без OAuth (только в Development-окружении).",
        "description": "Создаёт или находит пользователя по email без реального OAuth flow.\nВозвращает 404 в Production и Staging.",
        "requestBody": {
          "description": "Email, отображаемое имя и роль тестового пользователя.",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DevLoginRequest"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/DevLoginRequest"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/DevLoginRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Успешный вход.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AuthResponse"
                }
              }
            }
          },
          "404": {
            "description": "Endpoint недоступен вне Development.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/auth/refresh": {
      "post": {
        "tags": [
          "Auth"
        ],
        "summary": "Обновление access token по refresh token из HttpOnly cookie.",
        "description": "Refresh token читается из HttpOnly cookie `refreshToken` (устанавливается при входе).\nВозвращает новую пару токенов и обновляет cookie.",
        "responses": {
          "200": {
            "description": "Новая пара токенов.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AuthResponse"
                }
              }
            }
          },
          "401": {
            "description": "Refresh token отсутствует, просрочен или отозван.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Аккаунт деактивирован или refresh token недействителен.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/auth/logout": {
      "post": {
        "tags": [
          "Auth"
        ],
        "summary": "Выход из системы — отзыв refresh token.",
        "description": "Инвалидирует текущий refresh token в БД и удаляет cookie.\nПосле этого вызова access token остаётся валидным до истечения его TTL (30 минут).\n\n**Required:** any authenticated user",
        "responses": {
          "204": {
            "description": "Выход выполнен успешно."
          },
          "401": {
            "description": "Требуется аутентификация.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "Bearer": [ ]
          }
        ]
      }
    },
    "/api/v1/auth/me": {
      "get": {
        "tags": [
          "Auth"
        ],
        "summary": "Получение профиля текущего авторизованного пользователя.",
        "description": "**Required:** any authenticated user",
        "responses": {
          "200": {
            "description": "Данные текущего пользователя.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CurrentUserDto"
                }
              }
            }
          },
          "401": {
            "description": "Требуется аутентификация.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Пользователь не найден в БД (рассинхронизация токена).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "Bearer": [ ]
          }
        ]
      }
    },
    "/api/v1/courses": {
      "get": {
        "tags": [
          "Courses"
        ],
        "summary": "Получить список курсов с фильтрацией и пагинацией.",
        "description": "**Required:** any authenticated user",
        "parameters": [
          {
            "name": "TagId",
            "in": "query",
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "Search",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "IsSynced",
            "in": "query",
            "schema": {
              "type": "boolean"
            }
          },
          {
            "name": "Page",
            "in": "query",
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "PageSize",
            "in": "query",
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Список курсов (пагинированный).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CourseDtoPagedResult"
                }
              }
            }
          },
          "401": {
            "description": "Требуется аутентификация.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "Bearer": [ ]
          }
        ]
      },
      "post": {
        "tags": [
          "Courses"
        ],
        "summary": "Создать новый курс.",
        "description": "Только Admin.\n\n**Required roles:** Admin",
        "requestBody": {
          "description": "Название и описание курса.",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateCourseRequest"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateCourseRequest"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/CreateCourseRequest"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Курс создан.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CourseDto"
                }
              }
            }
          },
          "401": {
            "description": "Требуется аутентификация.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Требуется роль Admin.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "Bearer": [ ]
          }
        ]
      }
    },
    "/api/v1/courses/{id}": {
      "get": {
        "tags": [
          "Courses"
        ],
        "summary": "Получить курс по ID (включая теги).",
        "description": "**Required:** any authenticated user",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "ID курса.",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Данные курса с тегами.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CourseDto"
                }
              }
            }
          },
          "401": {
            "description": "Требуется аутентификация.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Курс не найден.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "Bearer": [ ]
          }
        ]
      },
      "put": {
        "tags": [
          "Courses"
        ],
        "summary": "Обновить курс по ID.",
        "description": "Только Admin.\n\n**Required roles:** Admin",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "ID курса.",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          }
        ],
        "requestBody": {
          "description": "Новое название и/или описание.",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateCourseRequest"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateCourseRequest"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateCourseRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Обновлённые данные курса.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CourseDto"
                }
              }
            }
          },
          "401": {
            "description": "Требуется аутентификация.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Требуется роль Admin.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Курс не найден.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "Bearer": [ ]
          }
        ]
      },
      "delete": {
        "tags": [
          "Courses"
        ],
        "summary": "Удалить курс по ID.",
        "description": "Только Admin. Удаление курса каскадно удаляет связанные лекции.\n\n**Required roles:** Admin",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "ID курса.",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Курс удалён."
          },
          "401": {
            "description": "Требуется аутентификация.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Требуется роль Admin.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Курс не найден.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "Bearer": [ ]
          }
        ]
      }
    },
    "/api/v1/courses/{id}/tags": {
      "post": {
        "tags": [
          "Courses"
        ],
        "summary": "Привязать тег к курсу.",
        "description": "Только Admin. Тег должен существовать в системе.\n\n**Required roles:** Admin",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "ID курса.",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          }
        ],
        "requestBody": {
          "description": "ID тега.",
          "content": {
            "application/json": {
              "schema": {
                "type": "integer",
                "format": "int32"
              }
            },
            "text/json": {
              "schema": {
                "type": "integer",
                "format": "int32"
              }
            },
            "application/*+json": {
              "schema": {
                "type": "integer",
                "format": "int32"
              }
            }
          }
        },
        "responses": {
          "204": {
            "description": "Тег привязан."
          },
          "401": {
            "description": "Требуется аутентификация.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Требуется роль Admin.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Курс или тег не найден.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "409": {
            "description": "Тег уже привязан к курсу.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "Bearer": [ ]
          }
        ]
      }
    },
    "/api/v1/courses/{id}/tags/{tagId}": {
      "delete": {
        "tags": [
          "Courses"
        ],
        "summary": "Отвязать тег от курса.",
        "description": "Только Admin.\n\n**Required roles:** Admin",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "ID курса.",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "tagId",
            "in": "path",
            "description": "ID тега.",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Тег отвязан."
          },
          "401": {
            "description": "Требуется аутентификация.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Требуется роль Admin.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Курс или тег не найден, либо связь не существует.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "Bearer": [ ]
          }
        ]
      }
    },
    "/api/v1/lectures": {
      "get": {
        "tags": [
          "Lectures"
        ],
        "summary": "Получить каталог лекций с фильтрацией и пагинацией.",
        "description": "Включает флаг `isEnrolled` — записан ли текущий пользователь на лекцию.\n\n**Required:** any authenticated user",
        "parameters": [
          {
            "name": "DateFrom",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date"
            }
          },
          {
            "name": "DateTo",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date"
            }
          },
          {
            "name": "CourseId",
            "in": "query",
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "TeacherId",
            "in": "query",
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "Format",
            "in": "query",
            "schema": {
              "$ref": "#/components/schemas/LectureFormat"
            }
          },
          {
            "name": "IsOpen",
            "in": "query",
            "schema": {
              "type": "boolean"
            }
          },
          {
            "name": "TagId",
            "in": "query",
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "Search",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Page",
            "in": "query",
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "PageSize",
            "in": "query",
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Список лекций (пагинированный).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LectureDtoPagedResult"
                }
              }
            }
          },
          "401": {
            "description": "Требуется аутентификация.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "Bearer": [ ]
          }
        ]
      },
      "post": {
        "tags": [
          "Lectures"
        ],
        "summary": "Создать новую лекцию.",
        "description": "Только Admin. Курс задаётся при создании и не может быть изменён.\n\n**Required roles:** Admin",
        "requestBody": {
          "description": "Данные лекции: курс, преподаватель, локация, время, формат, вместимость.",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateLectureRequest"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateLectureRequest"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/CreateLectureRequest"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Лекция создана.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LectureDto"
                }
              }
            }
          },
          "401": {
            "description": "Требуется аутентификация.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Требуется роль Admin.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "Bearer": [ ]
          }
        ]
      }
    },
    "/api/v1/lectures/{id}": {
      "get": {
        "tags": [
          "Lectures"
        ],
        "summary": "Получить детальную карточку лекции по ID.",
        "description": "Включает флаг `isEnrolled` — записан ли текущий пользователь на эту лекцию.\n\n**Required:** any authenticated user",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "ID лекции.",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Детальные данные лекции.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LectureDetailDto"
                }
              }
            }
          },
          "401": {
            "description": "Требуется аутентификация.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Лекция не найдена.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "Bearer": [ ]
          }
        ]
      },
      "put": {
        "tags": [
          "Lectures"
        ],
        "summary": "Обновить лекцию по ID.",
        "description": "Admin или Teacher. CourseId изменить нельзя.\n\n**Required roles:** Admin, Teacher",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "ID лекции.",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          }
        ],
        "requestBody": {
          "description": "Обновляемые поля: преподаватель, локация, время, формат, описание.",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateLectureRequest"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateLectureRequest"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateLectureRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Обновлённые данные лекции.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LectureDto"
                }
              }
            }
          },
          "401": {
            "description": "Требуется аутентификация.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Требуется роль Admin или Teacher.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Лекция не найдена.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "Bearer": [ ]
          }
        ]
      },
      "delete": {
        "tags": [
          "Lectures"
        ],
        "summary": "Удалить лекцию по ID.",
        "description": "Только Admin. Каскадно удаляет записи и отзывы.\n\n**Required roles:** Admin",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "ID лекции.",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Лекция удалена."
          },
          "401": {
            "description": "Требуется аутентификация.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Требуется роль Admin.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Лекция не найдена.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "Bearer": [ ]
          }
        ]
      }
    },
    "/api/v1/lectures/{id}/enroll": {
      "post": {
        "tags": [
          "Lectures"
        ],
        "summary": "Записаться на лекцию.",
        "description": "Только Student. Проверяет наличие свободных мест и отсутствие повторной записи.\nПосле посещения начисляются монеты через gamification.\n\n**Required roles:** Student",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "ID лекции.",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Запись выполнена."
          },
          "401": {
            "description": "Требуется аутентификация.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Требуется роль Student.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Лекция не найдена.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "409": {
            "description": "Студент уже записан или мест нет.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "Bearer": [ ]
          }
        ]
      },
      "delete": {
        "tags": [
          "Lectures"
        ],
        "summary": "Отменить запись на лекцию.",
        "description": "Только Student. Отменить можно только свою запись.\n\n**Required roles:** Student",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "ID лекции.",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Запись отменена."
          },
          "401": {
            "description": "Требуется аутентификация.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Требуется роль Student.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Лекция или запись не найдена.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "Bearer": [ ]
          }
        ]
      }
    },
    "/api/v1/lectures/{id}/attendance/{userId}": {
      "patch": {
        "tags": [
          "Lectures"
        ],
        "summary": "Отметить посещение студента на лекции.",
        "description": "Admin или Teacher. При отметке `attended=true` начисляются монеты за посещение\nчерез gamification service.\n\n**Required roles:** Admin, Teacher",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "ID лекции.",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "userId",
            "in": "path",
            "description": "ID студента.",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          }
        ],
        "requestBody": {
          "description": "true — посетил, false — не посетил.",
          "content": {
            "application/json": {
              "schema": {
                "type": "boolean"
              }
            },
            "text/json": {
              "schema": {
                "type": "boolean"
              }
            },
            "application/*+json": {
              "schema": {
                "type": "boolean"
              }
            }
          }
        },
        "responses": {
          "204": {
            "description": "Посещение отмечено."
          },
          "401": {
            "description": "Требуется аутентификация.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Требуется роль Admin или Teacher.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Лекция или запись студента не найдена.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "Bearer": [ ]
          }
        ]
      }
    },
    "/api/v1/lectures/{id}/enrollments": {
      "get": {
        "tags": [
          "Lectures"
        ],
        "summary": "Получить список записавшихся студентов на лекцию.",
        "description": "Только Admin или Teacher. Включает флаг посещения (`attended`).\n\n**Required roles:** Admin, Teacher",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "ID лекции.",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "Page",
            "in": "query",
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "PageSize",
            "in": "query",
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Список записей (пагинированный).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EnrollmentDtoPagedResult"
                }
              }
            }
          },
          "401": {
            "description": "Требуется аутентификация.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Требуется роль Admin или Teacher.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Лекция не найдена.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "Bearer": [ ]
          }
        ]
      }
    },
    "/api/v1/lectures/{id}/reviews": {
      "get": {
        "tags": [
          "Lectures"
        ],
        "summary": "Получить отзывы к лекции.",
        "description": "Только Admin или Teacher.\n\n**Required roles:** Admin, Teacher",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "ID лекции.",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "Page",
            "in": "query",
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "PageSize",
            "in": "query",
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Список отзывов (пагинированный).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ReviewDtoPagedResult"
                }
              }
            }
          },
          "401": {
            "description": "Требуется аутентификация.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Требуется роль Admin или Teacher.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Лекция не найдена.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "Bearer": [ ]
          }
        ]
      }
    },
    "/api/v1/locations": {
      "get": {
        "tags": [
          "Locations"
        ],
        "summary": "Получить список всех локаций.",
        "description": "**Required:** any authenticated user",
        "responses": {
          "200": {
            "description": "Список локаций.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/LocationDto"
                  }
                }
              }
            }
          },
          "401": {
            "description": "Требуется аутентификация.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "Bearer": [ ]
          }
        ]
      },
      "post": {
        "tags": [
          "Locations"
        ],
        "summary": "Создать новую локацию.",
        "description": "Только Admin. Локации также создаются автоматически при синхронизации с Modeus.\n\n**Required roles:** Admin",
        "requestBody": {
          "description": "Название, корпус, аудитория и/или адрес.",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateLocationRequest"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateLocationRequest"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/CreateLocationRequest"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Локация создана.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LocationDto"
                }
              }
            }
          },
          "401": {
            "description": "Требуется аутентификация.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Требуется роль Admin.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "Bearer": [ ]
          }
        ]
      }
    },
    "/api/v1/locations/{id}": {
      "get": {
        "tags": [
          "Locations"
        ],
        "summary": "Получить локацию по ID.",
        "description": "**Required:** any authenticated user",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "ID локации.",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Данные локации.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LocationDto"
                }
              }
            }
          },
          "401": {
            "description": "Требуется аутентификация.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Локация не найдена.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "Bearer": [ ]
          }
        ]
      },
      "put": {
        "tags": [
          "Locations"
        ],
        "summary": "Обновить локацию по ID.",
        "description": "Только Admin.\n\n**Required roles:** Admin",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "ID локации.",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          }
        ],
        "requestBody": {
          "description": "Обновляемые поля: название, корпус, аудитория, адрес.",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateLocationRequest"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateLocationRequest"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateLocationRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Обновлённые данные локации.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LocationDto"
                }
              }
            }
          },
          "401": {
            "description": "Требуется аутентификация.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Требуется роль Admin.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Локация не найдена.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "Bearer": [ ]
          }
        ]
      },
      "delete": {
        "tags": [
          "Locations"
        ],
        "summary": "Удалить локацию по ID.",
        "description": "Только Admin. При удалении локации у связанных лекций поле `locationId` становится null.\n\n**Required roles:** Admin",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "ID локации.",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Локация удалена."
          },
          "401": {
            "description": "Требуется аутентификация.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Требуется роль Admin.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Локация не найдена.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "Bearer": [ ]
          }
        ]
      }
    },
    "/api/v1/notifications": {
      "get": {
        "tags": [
          "Notifications"
        ],
        "summary": "Получить уведомления текущего пользователя.",
        "description": "**Required:** any authenticated user",
        "parameters": [
          {
            "name": "Page",
            "in": "query",
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "PageSize",
            "in": "query",
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Список уведомлений.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UserNotificationDtoPagedResult"
                }
              }
            }
          },
          "401": {
            "description": "Требуется аутентификация.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "Bearer": [ ]
          }
        ]
      }
    },
    "/api/v1/notifications/read-all": {
      "patch": {
        "tags": [
          "Notifications"
        ],
        "summary": "Отметить все уведомления текущего пользователя как прочитанные.",
        "description": "**Required:** any authenticated user",
        "responses": {
          "204": {
            "description": "Уведомления отмечены прочитанными."
          },
          "401": {
            "description": "Требуется аутентификация.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "Bearer": [ ]
          }
        ]
      }
    },
    "/api/v1/notifications/send": {
      "post": {
        "tags": [
          "Notifications"
        ],
        "summary": "Отправить уведомление немедленно.",
        "description": "Канал задаётся строкой, например `email`. Новые провайдеры добавляются через `INotificationProvider`.\n\n**Required roles:** Admin",
        "requestBody": {
          "description": "Канал, получатель, тема и текст уведомления.",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SendNotificationRequest"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/SendNotificationRequest"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/SendNotificationRequest"
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "Уведомление принято к отправке."
          },
          "401": {
            "description": "Требуется аутентификация.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Требуется роль Admin.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "Bearer": [ ]
          }
        ]
      }
    },
    "/api/v1/notifications/schedule": {
      "post": {
        "tags": [
          "Notifications"
        ],
        "summary": "Запланировать отложенную отправку уведомления через Quartz.NET.",
        "description": "**Required roles:** Admin",
        "requestBody": {
          "description": "Уведомление и момент отправки.",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ScheduleNotificationRequest"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/ScheduleNotificationRequest"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/ScheduleNotificationRequest"
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "Уведомление поставлено в очередь Quartz.NET.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ScheduledNotificationResponse"
                }
              }
            }
          },
          "401": {
            "description": "Требуется аутентификация.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Требуется роль Admin.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "Bearer": [ ]
          }
        ]
      }
    },
    "/api/v1/reviews": {
      "post": {
        "tags": [
          "Reviews"
        ],
        "summary": "Создать отзыв к лекции.",
        "description": "Только Student. После создания отзыв отправляется на LLM-анализ\n(статус `Pending`). LLM оценивает содержательность и начисляет монеты\nскрытно от пользователя.\n\n**Required roles:** Student",
        "requestBody": {
          "description": "ID лекции, оценка (Like/Neutral/Dislike) и текст отзыва.",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateReviewRequest"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateReviewRequest"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/CreateReviewRequest"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Отзыв создан и поставлен в очередь на LLM-анализ.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ReviewDto"
                }
              }
            }
          },
          "401": {
            "description": "Требуется аутентификация.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Требуется роль Student.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Лекция не найдена.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "409": {
            "description": "Студент уже оставил отзыв к этой лекции.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "Bearer": [ ]
          }
        ]
      },
      "get": {
        "tags": [
          "Reviews"
        ],
        "summary": "Получить список всех отзывов.",
        "description": "Только Admin. Возвращает все отзывы независимо от LLM-статуса.\n\n**Required roles:** Admin",
        "parameters": [
          {
            "name": "LlmStatus",
            "in": "query",
            "schema": {
              "$ref": "#/components/schemas/ReviewLlmStatus"
            }
          },
          {
            "name": "Page",
            "in": "query",
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "PageSize",
            "in": "query",
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Список всех отзывов (пагинированный).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ReviewDtoPagedResult"
                }
              }
            }
          },
          "401": {
            "description": "Требуется аутентификация.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Требуется роль Admin.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "Bearer": [ ]
          }
        ]
      }
    },
    "/api/v1/reviews/llm-prompt": {
      "get": {
        "tags": [
          "Reviews"
        ],
        "summary": "Получить текущий промпт LLM-анализа отзывов.",
        "description": "Только Admin. Если настройка ещё не сохранена, возвращает базовый промпт.\n\n**Required roles:** Admin",
        "responses": {
          "200": {
            "description": "Текущий шаблон промпта.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ReviewPromptDto"
                }
              }
            }
          },
          "401": {
            "description": "Требуется аутентификация.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Требуется роль Admin.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "Bearer": [ ]
          }
        ]
      },
      "put": {
        "tags": [
          "Reviews"
        ],
        "summary": "Обновить промпт LLM-анализа отзывов.",
        "description": "Только Admin. Промпт применяется к следующим анализам и ручным повторам.\n\n**Required roles:** Admin",
        "requestBody": {
          "description": "Новый шаблон с плейсхолдерами {lectureContext} и {reviewText}.",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateReviewPromptRequest"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateReviewPromptRequest"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateReviewPromptRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Сохранённый шаблон промпта.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ReviewPromptDto"
                }
              }
            }
          },
          "400": {
            "description": "Промпт пустой или не содержит обязательные плейсхолдеры.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "Требуется аутентификация.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Требуется роль Admin.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "Bearer": [ ]
          }
        ]
      }
    },
    "/api/v1/reviews/{id}": {
      "get": {
        "tags": [
          "Reviews"
        ],
        "summary": "Получить отзыв по ID.",
        "description": "Только Admin или Teacher.\n\n**Required roles:** Admin, Teacher",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "ID отзыва.",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Данные отзыва (включая LLM-статус и сентимент).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ReviewDto"
                }
              }
            }
          },
          "401": {
            "description": "Требуется аутентификация.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Требуется роль Admin или Teacher.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Отзыв не найден.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "Bearer": [ ]
          }
        ]
      },
      "put": {
        "tags": [
          "Reviews"
        ],
        "summary": "Обновить отзыв.",
        "description": "Разрешено любому авторизованному пользователю, но сервис проверяет владельца.\nИзменение текста сбрасывает LLM-статус в `Pending` (повторный анализ).\n\n**Required:** any authenticated user",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "ID отзыва.",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          }
        ],
        "requestBody": {
          "description": "Новая оценка и/или текст.",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateReviewRequest"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateReviewRequest"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateReviewRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Обновлённые данные отзыва.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ReviewDto"
                }
              }
            }
          },
          "401": {
            "description": "Требуется аутентификация.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Отзыв принадлежит другому пользователю.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Отзыв не найден.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "Bearer": [ ]
          }
        ]
      },
      "delete": {
        "tags": [
          "Reviews"
        ],
        "summary": "Удалить отзыв.",
        "description": "Владелец может удалить свой отзыв. Admin может удалить любой.\n\n**Required:** any authenticated user",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "ID отзыва.",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Отзыв удалён."
          },
          "401": {
            "description": "Требуется аутентификация.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Нет прав на удаление (не владелец и не Admin).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Отзыв не найден.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "Bearer": [ ]
          }
        ]
      }
    },
    "/api/v1/reviews/{id}/reanalyze": {
      "post": {
        "tags": [
          "Reviews"
        ],
        "summary": "Запустить повторный LLM-анализ отзыва.",
        "description": "Только Admin. Сбрасывает статус отзыва на `Pending` и отправляет его\nна повторную обработку.\n\n**Required roles:** Admin",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "ID отзыва.",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Повторный анализ запланирован."
          },
          "401": {
            "description": "Требуется аутентификация.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Требуется роль Admin.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Отзыв не найден.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "Bearer": [ ]
          }
        ]
      }
    },
    "/api/v1/sync/schedule": {
      "post": {
        "tags": [
          "Sync"
        ],
        "summary": "Запустить синхронизацию расписания лекций из Modeus.",
        "description": "Только Admin. Выполняет upsert лекций и связанных курсов на основе данных\nиз внешнего API `schedule.rdcenter.ru`. Поддерживает фильтрацию по периоду,\nразмеру выборки, аудиториям, участникам, реализациям курсов/циклов,\nспециальностям, годам набора, профилям, учебным планам и типам занятий.\n\n**Required roles:** Admin",
        "requestBody": {
          "description": "Параметры поиска событий во внешнем сервисе расписания.",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SyncScheduleRequest"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/SyncScheduleRequest"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/SyncScheduleRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Результат синхронизации: кол-во созданных, обновлённых и пропущенных записей.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SyncResultDto"
                }
              }
            }
          },
          "401": {
            "description": "Требуется аутентификация.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Требуется роль Admin.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "Bearer": [ ]
          }
        ]
      }
    },
    "/api/v1/sync/status": {
      "get": {
        "tags": [
          "Sync"
        ],
        "summary": "Получить статус последней синхронизации.",
        "description": "Только Admin. Возвращает время и результат последней успешной синхронизации.\n\n**Required roles:** Admin",
        "responses": {
          "200": {
            "description": "Статус синхронизации.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SyncStatusDto"
                }
              }
            }
          },
          "401": {
            "description": "Требуется аутентификация.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Требуется роль Admin.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "Bearer": [ ]
          }
        ]
      }
    },
    "/api/v1/sync/rooms": {
      "post": {
        "tags": [
          "Sync"
        ],
        "summary": "Синхронизировать аудитории (локации) из Modeus.",
        "description": "Только Admin. Импортирует аудитории из `schedule.rdcenter.ru` и создаёт\nсоответствующие записи в таблице locations.\n\n**Required roles:** Admin",
        "responses": {
          "200": {
            "description": "Результат синхронизации аудиторий.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SyncResultDto"
                }
              }
            }
          },
          "401": {
            "description": "Требуется аутентификация.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Требуется роль Admin.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "Bearer": [ ]
          }
        ]
      }
    },
    "/api/v1/sync/employees": {
      "post": {
        "tags": [
          "Sync"
        ],
        "summary": "Поиск преподавателей в Modeus по ФИО.",
        "description": "Только Admin. Ищет преподавателей через внешнее API и возвращает список\nдля ручного импорта. Найденные преподаватели не создаются автоматически.\n\n**Required roles:** Admin",
        "parameters": [
          {
            "name": "fullname",
            "in": "query",
            "description": "Полное имя или часть имени преподавателя для поиска.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Список найденных преподавателей.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/EmployeeDto"
                  }
                }
              }
            }
          },
          "401": {
            "description": "Требуется аутентификация.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Требуется роль Admin.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "Bearer": [ ]
          }
        ]
      }
    },
    "/api/v1/tags": {
      "get": {
        "tags": [
          "Tags"
        ],
        "summary": "Получить список тегов с опциональной фильтрацией по типу и родителю.",
        "description": "**Required:** any authenticated user",
        "parameters": [
          {
            "name": "type",
            "in": "query",
            "description": "Тип тега: Institute, Faculty, Subject, Organization, Topic, Other.",
            "schema": {
              "$ref": "#/components/schemas/TagType"
            }
          },
          {
            "name": "parentId",
            "in": "query",
            "description": "ID родительского тега (фильтрация дочерних).",
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Список тегов.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/TagDto"
                  }
                }
              }
            }
          },
          "401": {
            "description": "Требуется аутентификация.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "Bearer": [ ]
          }
        ]
      },
      "post": {
        "tags": [
          "Tags"
        ],
        "summary": "Создать новый тег.",
        "description": "Только Admin.\n\n**Required roles:** Admin",
        "requestBody": {
          "description": "Название, тип и опциональный родительский тег.",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateTagRequest"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateTagRequest"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/CreateTagRequest"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Тег создан.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TagDto"
                }
              }
            }
          },
          "401": {
            "description": "Требуется аутентификация.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Требуется роль Admin.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "Bearer": [ ]
          }
        ]
      }
    },
    "/api/v1/tags/{id}": {
      "get": {
        "tags": [
          "Tags"
        ],
        "summary": "Получить тег по ID.",
        "description": "**Required:** any authenticated user",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "ID тега.",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Данные тега.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TagDto"
                }
              }
            }
          },
          "401": {
            "description": "Требуется аутентификация.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Тег не найден.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "Bearer": [ ]
          }
        ]
      },
      "put": {
        "tags": [
          "Tags"
        ],
        "summary": "Обновить тег по ID.",
        "description": "Только Admin.\n\n**Required roles:** Admin",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "ID тега.",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          }
        ],
        "requestBody": {
          "description": "Новое название, тип и/или родительский тег.",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateTagRequest"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateTagRequest"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateTagRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Обновлённые данные тега.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TagDto"
                }
              }
            }
          },
          "401": {
            "description": "Требуется аутентификация.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Требуется роль Admin.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Тег не найден.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "Bearer": [ ]
          }
        ]
      },
      "delete": {
        "tags": [
          "Tags"
        ],
        "summary": "Удалить тег по ID.",
        "description": "Только Admin. Удаление тега каскадно удаляет привязки к курсам (`course_tags`).\nДочерние теги остаются, но их `parentId` становится null.\n\n**Required roles:** Admin",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "ID тега.",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Тег удалён."
          },
          "401": {
            "description": "Требуется аутентификация.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Требуется роль Admin.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Тег не найден.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "Bearer": [ ]
          }
        ]
      }
    },
    "/api/v1/tags/tree": {
      "get": {
        "tags": [
          "Tags"
        ],
        "summary": "Получить иерархическое дерево всех тегов.",
        "description": "Возвращает корневые теги с вложенными дочерними тегами.\nПолезно для построения фильтрующих UI-компонентов.\n\n**Required:** any authenticated user",
        "responses": {
          "200": {
            "description": "Иерархический список тегов.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/TagTreeDto"
                  }
                }
              }
            }
          },
          "401": {
            "description": "Требуется аутентификация.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "Bearer": [ ]
          }
        ]
      }
    },
    "/api/v1/users/me": {
      "get": {
        "tags": [
          "Users"
        ],
        "summary": "Получить профиль текущего пользователя.",
        "description": "**Required:** any authenticated user",
        "responses": {
          "200": {
            "description": "Данные текущего пользователя.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CurrentUserDto"
                }
              }
            }
          },
          "401": {
            "description": "Требуется аутентификация.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Пользователь не найден.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "Bearer": [ ]
          }
        ]
      },
      "put": {
        "tags": [
          "Users"
        ],
        "summary": "Обновить профиль текущего пользователя (displayName, avatarUrl).",
        "description": "**Required:** any authenticated user",
        "requestBody": {
          "description": "Обновляемые поля профиля.",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateUserRequest"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateUserRequest"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateUserRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Обновлённые данные текущего пользователя.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CurrentUserDto"
                }
              }
            }
          },
          "401": {
            "description": "Требуется аутентификация.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Пользователь не найден.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "Bearer": [ ]
          }
        ]
      }
    },
    "/api/v1/users/me/stats": {
      "get": {
        "tags": [
          "Users"
        ],
        "summary": "Получить статистику текущего пользователя.",
        "description": "**Required:** any authenticated user",
        "responses": {
          "200": {
            "description": "Статистика текущего пользователя.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UserStatsDto"
                }
              }
            }
          },
          "401": {
            "description": "Требуется аутентификация.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Пользователь не найден.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "Bearer": [ ]
          }
        ]
      }
    },
    "/api/v1/users/me/enrollments": {
      "get": {
        "tags": [
          "Users"
        ],
        "summary": "Получить список записей текущего пользователя на лекции.",
        "description": "**Required:** any authenticated user",
        "parameters": [
          {
            "name": "Page",
            "in": "query",
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "PageSize",
            "in": "query",
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Список записей (пагинированный).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LectureDtoPagedResult"
                }
              }
            }
          },
          "401": {
            "description": "Требуется аутентификация.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Пользователь не найден.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "Bearer": [ ]
          }
        ]
      }
    },
    "/api/v1/users/me/reviews": {
      "get": {
        "tags": [
          "Users"
        ],
        "summary": "Получить отзывы текущего пользователя.",
        "description": "**Required:** any authenticated user",
        "parameters": [
          {
            "name": "Page",
            "in": "query",
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "PageSize",
            "in": "query",
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Список отзывов (пагинированный).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ReviewDtoPagedResult"
                }
              }
            }
          },
          "401": {
            "description": "Требуется аутентификация.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "Bearer": [ ]
          }
        ]
      }
    },
    "/api/v1/users/me/achievements": {
      "get": {
        "tags": [
          "Users"
        ],
        "summary": "Получить достижения текущего пользователя.",
        "description": "**Required:** any authenticated user",
        "responses": {
          "200": {
            "description": "Список полученных достижений.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/UserAchievementDto"
                  }
                }
              }
            }
          },
          "401": {
            "description": "Требуется аутентификация.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "Bearer": [ ]
          }
        ]
      }
    },
    "/api/v1/users/me/transactions": {
      "get": {
        "tags": [
          "Users"
        ],
        "summary": "Получить историю транзакций монет текущего пользователя.",
        "description": "**Required:** any authenticated user",
        "parameters": [
          {
            "name": "Page",
            "in": "query",
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "PageSize",
            "in": "query",
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "История транзакций (пагинированная).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CoinTransactionDtoPagedResult"
                }
              }
            }
          },
          "401": {
            "description": "Требуется аутентификация.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "Bearer": [ ]
          }
        ]
      }
    },
    "/api/v1/users/{id}": {
      "get": {
        "tags": [
          "Users"
        ],
        "summary": "Получить профиль пользователя по ID.",
        "description": "Только Admin. Для текущего пользователя используйте GET /api/v1/users/me.\n\n**Required roles:** Admin",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "ID пользователя.",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Данные пользователя.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UserDto"
                }
              }
            }
          },
          "401": {
            "description": "Требуется аутентификация.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Требуется роль Admin.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Пользователь не найден.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "Bearer": [ ]
          }
        ]
      },
      "put": {
        "tags": [
          "Users"
        ],
        "summary": "Обновить профиль пользователя (displayName, avatarUrl).",
        "description": "Только Admin. Для текущего пользователя используйте PUT /api/v1/users/me.\n\n**Required roles:** Admin",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "ID пользователя.",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          }
        ],
        "requestBody": {
          "description": "Обновляемые поля профиля.",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateUserRequest"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateUserRequest"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateUserRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Обновлённые данные пользователя.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UserDto"
                }
              }
            }
          },
          "401": {
            "description": "Требуется аутентификация.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Требуется роль Admin.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Пользователь не найден.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "Bearer": [ ]
          }
        ]
      }
    },
    "/api/v1/users/{id}/stats": {
      "get": {
        "tags": [
          "Users"
        ],
        "summary": "Получить статистику пользователя (XP, монеты, уровень, посещения).",
        "description": "Только Admin. Для текущего пользователя используйте GET /api/v1/users/me/stats.\n\n**Required roles:** Admin",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "ID пользователя.",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Статистика пользователя.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UserStatsDto"
                }
              }
            }
          },
          "401": {
            "description": "Требуется аутентификация.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Требуется роль Admin.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Пользователь не найден.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "Bearer": [ ]
          }
        ]
      }
    },
    "/api/v1/users/{id}/enrollments": {
      "get": {
        "tags": [
          "Users"
        ],
        "summary": "Получить список записей пользователя на лекции.",
        "description": "Только Admin. Для текущего пользователя используйте GET /api/v1/users/me/enrollments.\n\n**Required roles:** Admin",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "ID пользователя.",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "Page",
            "in": "query",
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "PageSize",
            "in": "query",
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Список записей (пагинированный).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LectureDtoPagedResult"
                }
              }
            }
          },
          "401": {
            "description": "Требуется аутентификация.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Требуется роль Admin.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Пользователь не найден.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "Bearer": [ ]
          }
        ]
      }
    },
    "/api/v1/users/{id}/reviews": {
      "get": {
        "tags": [
          "Users"
        ],
        "summary": "Получить отзывы пользователя.",
        "description": "Только Admin. Для текущего пользователя используйте GET /api/v1/users/me/reviews.\n\n**Required roles:** Admin",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "ID пользователя.",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "Page",
            "in": "query",
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "PageSize",
            "in": "query",
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Список отзывов (пагинированный).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ReviewDtoPagedResult"
                }
              }
            }
          },
          "401": {
            "description": "Требуется аутентификация.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Требуется роль Admin.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "Bearer": [ ]
          }
        ]
      }
    },
    "/api/v1/users/{id}/achievements": {
      "get": {
        "tags": [
          "Users"
        ],
        "summary": "Получить достижения пользователя.",
        "description": "Только Admin. Для текущего пользователя используйте GET /api/v1/users/me/achievements.\n\n**Required roles:** Admin",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "ID пользователя.",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Список полученных достижений.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/UserAchievementDto"
                  }
                }
              }
            }
          },
          "401": {
            "description": "Требуется аутентификация.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Требуется роль Admin.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "Bearer": [ ]
          }
        ]
      }
    },
    "/api/v1/users/{id}/transactions": {
      "get": {
        "tags": [
          "Users"
        ],
        "summary": "Получить историю транзакций монет пользователя.",
        "description": "Только Admin. Для текущего пользователя используйте GET /api/v1/users/me/transactions.\n\n**Required roles:** Admin",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "ID пользователя.",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "Page",
            "in": "query",
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "PageSize",
            "in": "query",
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "История транзакций (пагинированная).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CoinTransactionDtoPagedResult"
                }
              }
            }
          },
          "401": {
            "description": "Требуется аутентификация.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Требуется роль Admin.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "Bearer": [ ]
          }
        ]
      }
    },
    "/api/v1/users": {
      "get": {
        "tags": [
          "Users"
        ],
        "summary": "Получить список всех пользователей с фильтрацией и пагинацией.",
        "description": "Только Admin.\n\n**Required roles:** Admin",
        "parameters": [
          {
            "name": "Search",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Role",
            "in": "query",
            "schema": {
              "$ref": "#/components/schemas/UserRole"
            }
          },
          {
            "name": "IsActive",
            "in": "query",
            "schema": {
              "type": "boolean"
            }
          },
          {
            "name": "Page",
            "in": "query",
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "PageSize",
            "in": "query",
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Список пользователей (пагинированный).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UserDtoPagedResult"
                }
              }
            }
          },
          "401": {
            "description": "Требуется аутентификация.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Требуется роль Admin.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "Bearer": [ ]
          }
        ]
      }
    },
    "/api/v1/users/{id}/role": {
      "patch": {
        "tags": [
          "Users"
        ],
        "summary": "Изменить набор ролей пользователя.",
        "description": "Только Admin. Доступные роли: Student, Teacher, Admin.\n\n**Required roles:** Admin",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "ID пользователя.",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          }
        ],
        "requestBody": {
          "description": "Новый набор ролей пользователя.",
          "content": {
            "application/json": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/UserRole"
                }
              }
            },
            "text/json": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/UserRole"
                }
              }
            },
            "application/*+json": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/UserRole"
                }
              }
            }
          }
        },
        "responses": {
          "204": {
            "description": "Роли успешно изменены."
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "Требуется аутентификация.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Требуется роль Admin.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Пользователь не найден.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "Bearer": [ ]
          }
        ]
      }
    },
    "/api/v1/users/{id}/active": {
      "patch": {
        "tags": [
          "Users"
        ],
        "summary": "Активировать или деактивировать аккаунт пользователя.",
        "description": "Только Admin. Деактивированный пользователь не может войти в систему.\n\n**Required roles:** Admin",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "ID пользователя.",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          }
        ],
        "requestBody": {
          "description": "true — активировать, false — деактивировать.",
          "content": {
            "application/json": {
              "schema": {
                "type": "boolean"
              }
            },
            "text/json": {
              "schema": {
                "type": "boolean"
              }
            },
            "application/*+json": {
              "schema": {
                "type": "boolean"
              }
            }
          }
        },
        "responses": {
          "204": {
            "description": "Статус успешно изменён."
          },
          "401": {
            "description": "Требуется аутентификация.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Требуется роль Admin.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Пользователь не найден.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "Bearer": [ ]
          }
        ]
      }
    }
  },
  "components": {
    "schemas": {
      "AchievementDto": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer",
            "format": "int32"
          },
          "name": {
            "type": "string",
            "nullable": true
          },
          "description": {
            "type": "string",
            "nullable": true
          },
          "iconUrl": {
            "type": "string",
            "nullable": true
          },
          "xpReward": {
            "type": "integer",
            "format": "int32"
          },
          "coinReward": {
            "type": "integer",
            "format": "int32"
          },
          "condition": {
            "type": "string",
            "nullable": true
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "additionalProperties": false
      },
      "AuthResponse": {
        "type": "object",
        "properties": {
          "accessToken": {
            "type": "string",
            "nullable": true
          },
          "expiresAt": {
            "type": "string",
            "format": "date-time"
          },
          "user": {
            "$ref": "#/components/schemas/UserAuthDto"
          }
        },
        "additionalProperties": false
      },
      "CoinTransactionDto": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer",
            "format": "int32"
          },
          "amount": {
            "type": "integer",
            "format": "int32"
          },
          "type": {
            "$ref": "#/components/schemas/CoinTransactionType"
          },
          "reviewId": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "achievementId": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "description": {
            "type": "string",
            "nullable": true
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "additionalProperties": false
      },
      "CoinTransactionDtoPagedResult": {
        "type": "object",
        "properties": {
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CoinTransactionDto"
            },
            "nullable": true
          },
          "totalCount": {
            "type": "integer",
            "format": "int32"
          },
          "page": {
            "type": "integer",
            "format": "int32"
          },
          "pageSize": {
            "type": "integer",
            "format": "int32"
          },
          "totalPages": {
            "type": "integer",
            "format": "int32"
          }
        },
        "additionalProperties": false
      },
      "CoinTransactionType": {
        "enum": [
          "ReviewReward",
          "AchievementReward",
          "AttendanceReward",
          "AdminAdjustment"
        ],
        "type": "string"
      },
      "CourseDto": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer",
            "format": "int32"
          },
          "name": {
            "type": "string",
            "nullable": true
          },
          "description": {
            "type": "string",
            "nullable": true
          },
          "isSynced": {
            "type": "boolean"
          },
          "tags": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/TagDto"
            },
            "nullable": true
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "additionalProperties": false
      },
      "CourseDtoPagedResult": {
        "type": "object",
        "properties": {
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CourseDto"
            },
            "nullable": true
          },
          "totalCount": {
            "type": "integer",
            "format": "int32"
          },
          "page": {
            "type": "integer",
            "format": "int32"
          },
          "pageSize": {
            "type": "integer",
            "format": "int32"
          },
          "totalPages": {
            "type": "integer",
            "format": "int32"
          }
        },
        "additionalProperties": false
      },
      "CreateAchievementRequest": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "nullable": true
          },
          "description": {
            "type": "string",
            "nullable": true
          },
          "iconUrl": {
            "type": "string",
            "nullable": true
          },
          "xpReward": {
            "type": "integer",
            "format": "int32"
          },
          "coinReward": {
            "type": "integer",
            "format": "int32"
          },
          "condition": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "CreateCourseRequest": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "nullable": true
          },
          "description": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "CreateLectureRequest": {
        "type": "object",
        "properties": {
          "courseId": {
            "type": "integer",
            "format": "int32"
          },
          "teacherId": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "locationId": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "title": {
            "type": "string",
            "nullable": true
          },
          "description": {
            "type": "string",
            "nullable": true
          },
          "format": {
            "$ref": "#/components/schemas/LectureFormat"
          },
          "startsAt": {
            "type": "string",
            "format": "date-time"
          },
          "endsAt": {
            "type": "string",
            "format": "date-time"
          },
          "isOpen": {
            "type": "boolean"
          },
          "maxEnrollments": {
            "type": "integer",
            "format": "int32"
          },
          "onlineUrl": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "CreateLocationRequest": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "nullable": true
          },
          "building": {
            "type": "string",
            "nullable": true
          },
          "room": {
            "type": "string",
            "nullable": true
          },
          "address": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "CreateReviewRequest": {
        "type": "object",
        "properties": {
          "lectureId": {
            "type": "integer",
            "format": "int32"
          },
          "rating": {
            "$ref": "#/components/schemas/ReviewRating"
          },
          "text": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "CreateTagRequest": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "nullable": true
          },
          "type": {
            "$ref": "#/components/schemas/TagType"
          },
          "parentId": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "CurrentUserDto": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer",
            "format": "int32"
          },
          "email": {
            "type": "string",
            "nullable": true
          },
          "displayName": {
            "type": "string",
            "nullable": true
          },
          "avatarUrl": {
            "type": "string",
            "nullable": true
          },
          "roles": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/UserRole"
            },
            "nullable": true
          },
          "xp": {
            "type": "integer",
            "format": "int32"
          },
          "coins": {
            "type": "integer",
            "format": "int32"
          },
          "level": {
            "type": "integer",
            "format": "int32"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "additionalProperties": false
      },
      "DevLoginRequest": {
        "type": "object",
        "properties": {
          "email": {
            "type": "string",
            "nullable": true
          },
          "displayName": {
            "type": "string",
            "nullable": true
          },
          "roles": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/UserRole"
            },
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "EmployeeDto": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "nullable": true
          },
          "fullName": {
            "type": "string",
            "nullable": true
          },
          "department": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "EnrollmentDto": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer",
            "format": "int32"
          },
          "userId": {
            "type": "integer",
            "format": "int32"
          },
          "userName": {
            "type": "string",
            "nullable": true
          },
          "userEmail": {
            "type": "string",
            "nullable": true
          },
          "attended": {
            "type": "boolean"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "additionalProperties": false
      },
      "EnrollmentDtoPagedResult": {
        "type": "object",
        "properties": {
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/EnrollmentDto"
            },
            "nullable": true
          },
          "totalCount": {
            "type": "integer",
            "format": "int32"
          },
          "page": {
            "type": "integer",
            "format": "int32"
          },
          "pageSize": {
            "type": "integer",
            "format": "int32"
          },
          "totalPages": {
            "type": "integer",
            "format": "int32"
          }
        },
        "additionalProperties": false
      },
      "EnrollmentSlotRuleDto": {
        "type": "object",
        "properties": {
          "level": {
            "type": "integer",
            "format": "int32"
          },
          "slots": {
            "type": "integer",
            "format": "int32"
          }
        },
        "additionalProperties": false
      },
      "LectureDetailDto": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer",
            "format": "int32"
          },
          "courseId": {
            "type": "integer",
            "format": "int32"
          },
          "courseName": {
            "type": "string",
            "nullable": true
          },
          "teacherId": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "teacherName": {
            "type": "string",
            "nullable": true
          },
          "locationId": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "locationName": {
            "type": "string",
            "nullable": true
          },
          "title": {
            "type": "string",
            "nullable": true
          },
          "description": {
            "type": "string",
            "nullable": true
          },
          "format": {
            "$ref": "#/components/schemas/LectureFormat"
          },
          "startsAt": {
            "type": "string",
            "format": "date-time"
          },
          "endsAt": {
            "type": "string",
            "format": "date-time"
          },
          "isOpen": {
            "type": "boolean"
          },
          "maxEnrollments": {
            "type": "integer",
            "format": "int32"
          },
          "enrollmentsCount": {
            "type": "integer",
            "format": "int32"
          },
          "onlineUrl": {
            "type": "string",
            "nullable": true
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "isEnrolled": {
            "type": "boolean"
          }
        },
        "additionalProperties": false
      },
      "LectureDto": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer",
            "format": "int32"
          },
          "courseId": {
            "type": "integer",
            "format": "int32"
          },
          "courseName": {
            "type": "string",
            "nullable": true
          },
          "teacherId": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "teacherName": {
            "type": "string",
            "nullable": true
          },
          "locationId": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "locationName": {
            "type": "string",
            "nullable": true
          },
          "title": {
            "type": "string",
            "nullable": true
          },
          "description": {
            "type": "string",
            "nullable": true
          },
          "format": {
            "$ref": "#/components/schemas/LectureFormat"
          },
          "startsAt": {
            "type": "string",
            "format": "date-time"
          },
          "endsAt": {
            "type": "string",
            "format": "date-time"
          },
          "isOpen": {
            "type": "boolean"
          },
          "maxEnrollments": {
            "type": "integer",
            "format": "int32"
          },
          "enrollmentsCount": {
            "type": "integer",
            "format": "int32"
          },
          "onlineUrl": {
            "type": "string",
            "nullable": true
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "isEnrolled": {
            "type": "boolean"
          }
        },
        "additionalProperties": false
      },
      "LectureDtoPagedResult": {
        "type": "object",
        "properties": {
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/LectureDto"
            },
            "nullable": true
          },
          "totalCount": {
            "type": "integer",
            "format": "int32"
          },
          "page": {
            "type": "integer",
            "format": "int32"
          },
          "pageSize": {
            "type": "integer",
            "format": "int32"
          },
          "totalPages": {
            "type": "integer",
            "format": "int32"
          }
        },
        "additionalProperties": false
      },
      "LectureFormat": {
        "enum": [
          "Online",
          "Offline"
        ],
        "type": "string"
      },
      "LocationDto": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer",
            "format": "int32"
          },
          "name": {
            "type": "string",
            "nullable": true
          },
          "building": {
            "type": "string",
            "nullable": true
          },
          "room": {
            "type": "string",
            "nullable": true
          },
          "address": {
            "type": "string",
            "nullable": true
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "additionalProperties": false
      },
      "LoginMicrosoftRequest": {
        "type": "object",
        "properties": {
          "authorizationCode": {
            "type": "string",
            "nullable": true
          },
          "redirectUri": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "ProblemDetails": {
        "type": "object",
        "properties": {
          "type": {
            "type": "string",
            "nullable": true
          },
          "title": {
            "type": "string",
            "nullable": true
          },
          "status": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "detail": {
            "type": "string",
            "nullable": true
          },
          "instance": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": { }
      },
      "ReviewDto": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer",
            "format": "int32"
          },
          "lectureId": {
            "type": "integer",
            "format": "int32"
          },
          "lectureTitle": {
            "type": "string",
            "nullable": true
          },
          "userId": {
            "type": "integer",
            "format": "int32"
          },
          "userName": {
            "type": "string",
            "nullable": true
          },
          "rating": {
            "$ref": "#/components/schemas/ReviewRating"
          },
          "text": {
            "type": "string",
            "nullable": true
          },
          "llmStatus": {
            "$ref": "#/components/schemas/ReviewLlmStatus"
          },
          "sentiment": {
            "$ref": "#/components/schemas/ReviewSentiment"
          },
          "qualityScore": {
            "type": "number",
            "format": "double",
            "nullable": true
          },
          "isInformative": {
            "type": "boolean",
            "nullable": true
          },
          "llmTags": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "nullable": true
          },
          "llmRawOutput": {
            "type": "string",
            "nullable": true
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "additionalProperties": false
      },
      "ReviewDtoPagedResult": {
        "type": "object",
        "properties": {
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ReviewDto"
            },
            "nullable": true
          },
          "totalCount": {
            "type": "integer",
            "format": "int32"
          },
          "page": {
            "type": "integer",
            "format": "int32"
          },
          "pageSize": {
            "type": "integer",
            "format": "int32"
          },
          "totalPages": {
            "type": "integer",
            "format": "int32"
          }
        },
        "additionalProperties": false
      },
      "ReviewLlmStatus": {
        "enum": [
          "Pending",
          "Analyzed",
          "Rejected"
        ],
        "type": "string"
      },
      "ReviewPromptDto": {
        "type": "object",
        "properties": {
          "prompt": {
            "type": "string",
            "nullable": true
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "ReviewRating": {
        "enum": [
          "Like",
          "Neutral",
          "Dislike"
        ],
        "type": "string"
      },
      "ReviewSentiment": {
        "enum": [
          "Positive",
          "Neutral",
          "Negative"
        ],
        "type": "string"
      },
      "ScheduleNotificationRequest": {
        "type": "object",
        "properties": {
          "channel": {
            "type": "string",
            "nullable": true
          },
          "recipient": {
            "type": "string",
            "nullable": true
          },
          "subject": {
            "type": "string",
            "nullable": true
          },
          "body": {
            "type": "string",
            "nullable": true
          },
          "sendAt": {
            "type": "string",
            "format": "date-time"
          },
          "recipientName": {
            "type": "string",
            "nullable": true
          },
          "metadata": {
            "type": "object",
            "additionalProperties": {
              "type": "string"
            },
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "ScheduledNotificationResponse": {
        "type": "object",
        "properties": {
          "jobId": {
            "type": "string",
            "nullable": true
          },
          "sendAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "additionalProperties": false
      },
      "SendNotificationRequest": {
        "type": "object",
        "properties": {
          "channel": {
            "type": "string",
            "nullable": true
          },
          "recipient": {
            "type": "string",
            "nullable": true
          },
          "subject": {
            "type": "string",
            "nullable": true
          },
          "body": {
            "type": "string",
            "nullable": true
          },
          "recipientName": {
            "type": "string",
            "nullable": true
          },
          "metadata": {
            "type": "object",
            "additionalProperties": {
              "type": "string"
            },
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "SyncResultDto": {
        "type": "object",
        "properties": {
          "created": {
            "type": "integer",
            "format": "int32"
          },
          "updated": {
            "type": "integer",
            "format": "int32"
          },
          "skipped": {
            "type": "integer",
            "format": "int32"
          },
          "error": {
            "type": "string",
            "nullable": true
          },
          "details": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "SyncScheduleRequest": {
        "type": "object",
        "properties": {
          "specialtyCode": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "nullable": true
          },
          "timeMin": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "timeMax": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "typeId": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "nullable": true
          },
          "size": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "roomId": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "nullable": true
          },
          "attendeePersonId": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "nullable": true
          },
          "courseUnitRealizationId": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "nullable": true
          },
          "cycleRealizationId": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "nullable": true
          },
          "learningStartYear": {
            "type": "array",
            "items": {
              "type": "integer",
              "format": "int32"
            },
            "nullable": true
          },
          "profileName": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "nullable": true
          },
          "curriculumId": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "SyncStatusDto": {
        "type": "object",
        "properties": {
          "lastSyncAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "status": {
            "type": "string",
            "nullable": true
          },
          "lastResult": {
            "$ref": "#/components/schemas/SyncResultDto"
          }
        },
        "additionalProperties": false
      },
      "TagDto": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer",
            "format": "int32"
          },
          "name": {
            "type": "string",
            "nullable": true
          },
          "type": {
            "$ref": "#/components/schemas/TagType"
          },
          "parentId": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "additionalProperties": false
      },
      "TagTreeDto": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer",
            "format": "int32"
          },
          "name": {
            "type": "string",
            "nullable": true
          },
          "type": {
            "$ref": "#/components/schemas/TagType"
          },
          "children": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/TagTreeDto"
            },
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "TagType": {
        "enum": [
          "Institute",
          "Faculty",
          "Subject",
          "Organization",
          "Topic",
          "Other"
        ],
        "type": "string"
      },
      "UpdateAchievementRequest": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "nullable": true
          },
          "description": {
            "type": "string",
            "nullable": true
          },
          "iconUrl": {
            "type": "string",
            "nullable": true
          },
          "xpReward": {
            "type": "integer",
            "format": "int32"
          },
          "coinReward": {
            "type": "integer",
            "format": "int32"
          },
          "condition": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "UpdateCourseRequest": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "nullable": true
          },
          "description": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "UpdateLectureRequest": {
        "type": "object",
        "properties": {
          "teacherId": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "locationId": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "title": {
            "type": "string",
            "nullable": true
          },
          "description": {
            "type": "string",
            "nullable": true
          },
          "format": {
            "$ref": "#/components/schemas/LectureFormat"
          },
          "startsAt": {
            "type": "string",
            "format": "date-time"
          },
          "endsAt": {
            "type": "string",
            "format": "date-time"
          },
          "isOpen": {
            "type": "boolean"
          },
          "maxEnrollments": {
            "type": "integer",
            "format": "int32"
          },
          "onlineUrl": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "UpdateLocationRequest": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "nullable": true
          },
          "building": {
            "type": "string",
            "nullable": true
          },
          "room": {
            "type": "string",
            "nullable": true
          },
          "address": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "UpdateReviewPromptRequest": {
        "type": "object",
        "properties": {
          "prompt": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "UpdateReviewRequest": {
        "type": "object",
        "properties": {
          "rating": {
            "$ref": "#/components/schemas/ReviewRating"
          },
          "text": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "UpdateTagRequest": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "nullable": true
          },
          "type": {
            "$ref": "#/components/schemas/TagType"
          },
          "parentId": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "UpdateUserRequest": {
        "type": "object",
        "properties": {
          "displayName": {
            "type": "string",
            "nullable": true
          },
          "avatarUrl": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "UserAchievementDto": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer",
            "format": "int32"
          },
          "achievement": {
            "$ref": "#/components/schemas/AchievementDto"
          },
          "awardedAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "additionalProperties": false
      },
      "UserAuthDto": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer",
            "format": "int32"
          },
          "email": {
            "type": "string",
            "nullable": true
          },
          "displayName": {
            "type": "string",
            "nullable": true
          },
          "roles": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/UserRole"
            },
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "UserDto": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer",
            "format": "int32"
          },
          "email": {
            "type": "string",
            "nullable": true
          },
          "displayName": {
            "type": "string",
            "nullable": true
          },
          "avatarUrl": {
            "type": "string",
            "nullable": true
          },
          "roles": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/UserRole"
            },
            "nullable": true
          },
          "isActive": {
            "type": "boolean"
          },
          "xp": {
            "type": "integer",
            "format": "int32"
          },
          "coins": {
            "type": "integer",
            "format": "int32"
          },
          "level": {
            "type": "integer",
            "format": "int32"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "additionalProperties": false
      },
      "UserDtoPagedResult": {
        "type": "object",
        "properties": {
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/UserDto"
            },
            "nullable": true
          },
          "totalCount": {
            "type": "integer",
            "format": "int32"
          },
          "page": {
            "type": "integer",
            "format": "int32"
          },
          "pageSize": {
            "type": "integer",
            "format": "int32"
          },
          "totalPages": {
            "type": "integer",
            "format": "int32"
          }
        },
        "additionalProperties": false
      },
      "UserNotificationDto": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer",
            "format": "int32"
          },
          "type": {
            "type": "string",
            "nullable": true
          },
          "title": {
            "type": "string",
            "nullable": true
          },
          "body": {
            "type": "string",
            "nullable": true
          },
          "isRead": {
            "type": "boolean"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "additionalProperties": false
      },
      "UserNotificationDtoPagedResult": {
        "type": "object",
        "properties": {
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/UserNotificationDto"
            },
            "nullable": true
          },
          "totalCount": {
            "type": "integer",
            "format": "int32"
          },
          "page": {
            "type": "integer",
            "format": "int32"
          },
          "pageSize": {
            "type": "integer",
            "format": "int32"
          },
          "totalPages": {
            "type": "integer",
            "format": "int32"
          }
        },
        "additionalProperties": false
      },
      "UserRole": {
        "enum": [
          "Student",
          "Teacher",
          "Admin"
        ],
        "type": "string"
      },
      "UserStatsDto": {
        "type": "object",
        "properties": {
          "totalLectures": {
            "type": "integer",
            "format": "int32"
          },
          "attendedLectures": {
            "type": "integer",
            "format": "int32"
          },
          "totalReviews": {
            "type": "integer",
            "format": "int32"
          },
          "xp": {
            "type": "integer",
            "format": "int32"
          },
          "coins": {
            "type": "integer",
            "format": "int32"
          },
          "level": {
            "type": "integer",
            "format": "int32"
          },
          "achievementsCount": {
            "type": "integer",
            "format": "int32"
          },
          "currentLevelXp": {
            "type": "integer",
            "format": "int32"
          },
          "nextLevelXp": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "activeEnrollments": {
            "type": "integer",
            "format": "int32"
          },
          "enrollmentSlotLimit": {
            "type": "integer",
            "format": "int32"
          },
          "enrollmentSlotRules": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/EnrollmentSlotRuleDto"
            },
            "nullable": true
          }
        },
        "additionalProperties": false
      }
    },
    "securitySchemes": {
      "Bearer": {
        "type": "http",
        "description": "Введите JWT access token, полученный из `/api/v1/auth/login/microsoft`.\n\nПример: `eyJhbGci...`",
        "scheme": "bearer",
        "bearerFormat": "JWT"
      }
    }
  },
  "tags": [
    {
      "name": "Achievements"
    },
    {
      "name": "Auth"
    },
    {
      "name": "Courses"
    },
    {
      "name": "Lectures"
    },
    {
      "name": "Locations"
    },
    {
      "name": "Notifications"
    },
    {
      "name": "Reviews"
    },
    {
      "name": "Sync"
    },
    {
      "name": "Tags"
    },
    {
      "name": "Users"
    }
  ]
}