openapi: "3.0.1" info: title: Pulse API version: "1.0" servers: - url: http://localhost:8080/v1/api paths: /ping: get: summary: Проверка сервера на готовность принимать запросы description: | Данный эндпоинт позволяет понять, что сервер готов принимать входящие запросы. Программа-чекер будет дожидаться первого успешного ответа от сервера на данный эндпоинт, после чего будет запускать проверку тестовый сценариев. operationId: ping responses: "200": description: | Если сервер успешно отвечает на данный запрос, считается, что он готов обрабатывать входящие запросы в API. Содержимое ответа при этом не валидируется, можно возвращать "ok". content: text/plain: schema: type: string example: ok "500": description: Если сервер отвечает любым отличным от 200 кодом ответа, считается, что он не готов принимать запросы. /countries: get: summary: Получить список стран description: | Получение списка стран с возможной фильтрацией. Используется на странице регистрации для предоставления возможности выбора страны, к которой относится пользователь. Если никакие из фильтров не переданы, необходимо вернуть все страны. operationId: listCountries parameters: - name: region description: | Возвращаемые страны должны относиться только к тем регионам, которые переданы в данном списке. Если передан пустой список, считайте, что фильтр по региону отсутствует. in: query schema: type: array items: $ref: "#/components/schemas/countryRegion" responses: "200": description: Список стран, соответствующих указанному фильтру. Страны должны быть отсортированы лексикографически по двухбуквенному коду. content: application/json: schema: type: array items: $ref: "#/components/schemas/country" /countries/{alpha2}: get: summary: Получить страну по alpha2 коду description: | Получение одной страны по её уникальному двухбуквенному коду. Используется для получения информации по определенной стране. operationId: getCountry parameters: - name: alpha2 description: | Возвращаемая страна должна иметь указанный alpha2 код. required: true in: path schema: $ref: "#/components/schemas/countryAlpha2" responses: "200": description: Страна, найденная по указанному коду. content: application/json: schema: $ref: "#/components/schemas/country" "404": description: Страна с указанным кодом не найдена. content: application/json: schema: $ref: "#/components/schemas/errorResponse" /auth/register: post: summary: Регистрация нового пользователя description: | Используется для регистрации нового пользователя по логину и паролю. operationId: authRegister requestBody: description: Данные для регистрации пользователя. required: true content: application/json: schema: type: object properties: login: $ref: "#/components/schemas/userLogin" email: $ref: "#/components/schemas/userEmail" password: $ref: "#/components/schemas/userPassword" countryCode: $ref: "#/components/schemas/countryAlpha2" isPublic: $ref: "#/components/schemas/userIsPublic" phone: $ref: "#/components/schemas/userPhone" image: $ref: "#/components/schemas/userImage" required: - login - email - password - countryCode - isPublic responses: "201": description: В случае успеха возвращается профиль зарегистрированного пользователя content: application/json: schema: type: object properties: profile: $ref: "#/components/schemas/userProfile" required: - profile "400": description: | Регистрационные данные не соответствуют ожидаемому формату и требованиям. Например, данную ошибку необходимо возвращать в следующих ситуациях (это не полный список): - Недостаточно "надежный" пароль. - Страна с указанным кодом не найдена. - Длина ссылки на аватар пользователя превышает допустимый лимит. Для ознакомления с форматом и требованиями к регистрационным данным обратите внимание на описание моделей в Open API спецификации. content: application/json: schema: $ref: "#/components/schemas/errorResponse" "409": description: | Нарушено требование на уникальность авторизационных данных пользователей. Данный код ответа должен использоваться, если пользователь с таким e-mail, номером телефона или логином уже зарегистрирован. content: application/json: schema: $ref: "#/components/schemas/errorResponse" /auth/sign-in: post: summary: Аутентификация для получения токена description: | Процедура аутентификации по логину и паролю позволяет получить токен, который в дальнейшем будет использоваться пользователем для выполнения операций, требующих авторизацию. Сервер должен генерировать уникальные токены, имеющие время жизни (в рамках задачи это будет 24 часа). После истечения времени действия токен должен быть недействительным и не может использоваться для аутентификации. Токен является уникальным строковым значением с высокой энтропией (злоумышленник не сможет его "подобрать" перебором). При каждой новой аутентификации генерируется новый уникальный токен, который ранее не был использован. Можно использовать JWT. В дальнейшем полученный токен будет использоваться для авторизации пользовательских запросов. Значение токена будет подставляться в заголовок `Authorization` в формате `Bearer {token}`. Следовательно, сервер должен уметь идентифицировать пользователя по токену. operationId: authSignIn responses: "200": description: Успешная аутентификация content: application/json: schema: type: object properties: token: type: string description: Сгенерированный токен пользователя minLength: 20 example: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c required: - token "401": description: Пользователь с указанным логином и паролем не найден content: application/json: schema: $ref: "#/components/schemas/errorResponse" /me/profile: get: summary: Получение собственного профиля description: | Используется для получения пользователем его собственного профиля. Сервер должен идентифицировать пользователя по переданному токену. Значение токена будет подставляться в заголовок `Authorization` в формате `Bearer {token}`. security: - bearerAuth: [] operationId: getMyProfile responses: "200": description: Передан действительный токен, в ответе возвращается профиль пользователя. content: application/json: schema: $ref: "#/components/schemas/userProfile" "401": description: Переданный токен не существует либо некорректен. content: application/json: schema: $ref: "#/components/schemas/errorResponse" patch: summary: Редактирование собственного профиля description: | Используется для редактирования параметров профиля пользователя. Сервер должен идентифицировать пользователя по переданному токену. Значение токена будет подставляться в заголовок `Authorization` в формате `Bearer {token}`. security: - bearerAuth: [] operationId: patchMyProfile requestBody: description: | В теле запроса перечисляются названия параметров, которые необходимо обновить, и новые значения. Если значение передано, данное изменение должно быть отражено в профиле пользователя. Если значение не передано, необходимо оставить прежнее значение параметра. required: true content: application/json: schema: type: object properties: countryCode: $ref: "#/components/schemas/countryAlpha2" isPublic: $ref: "#/components/schemas/userIsPublic" phone: $ref: "#/components/schemas/userPhone" image: $ref: "#/components/schemas/userImage" responses: "200": description: Передан действительный токен, в ответе возвращается профиль пользователя с примененными изменениями. content: application/json: schema: $ref: "#/components/schemas/userProfile" "401": description: Переданный токен не существует либо некорректен. content: application/json: schema: $ref: "#/components/schemas/errorResponse" /profiles/{login}: get: summary: Получение профиля пользователя по логину description: | Используется для получения профиля другого пользователя по логину. Если профиль пользователя публичен (`isPublic: true`), его может получить любой другой пользователь. Иначе профиль пользователя получить нельзя. При этом собственный профиль пользователь может получить всегда. Сервер должен идентифицировать пользователя по переданному токену в заголовке `Authorization`. security: - bearerAuth: [] parameters: - name: login description: Логин пользователя, чей профиль необходимо получить. required: true in: path schema: $ref: "#/components/schemas/userLogin" operationId: getProfile responses: "200": description: Пользователь с указанным логином существует и его профиль может быть получен пользователем, осуществившим запрос. content: application/json: schema: $ref: "#/components/schemas/userProfile" "401": description: Переданный токен не существует либо некорректен. content: application/json: schema: $ref: "#/components/schemas/errorResponse" "403": description: | Профиль не может быть получен: либо пользователь с указанным логином не существует, либо у отправителя запроса нет доступа к запрашиваемому профилю. content: application/json: schema: $ref: "#/components/schemas/errorResponse" /me/updatePassword: post: summary: Обновление пароля description: | Используется для обновления пароля. Сервер должен идентифицировать пользователя по переданному токену. Значение токена будет подставляться в заголовок `Authorization` в формате `Bearer {token}`. Важно: после успешного обновления пароля ранее выписанные токены должны быть деактивированы. Как только сервер вернет успешный ответ на данный запрос, пользователь не сможет совершить какие-либо операции с ранее созданными токенами (запросы со старыми токенами должны получать соответствующий ошибочный статус код). security: - bearerAuth: [] operationId: updatePassword requestBody: description: | В теле запроса передается старый и новый пароли. Пароль может быть обновлен только в случае передачи правильного значения старого пароля. required: true content: application/json: schema: type: object properties: oldPassword: $ref: "#/components/schemas/userPassword" newPassword: $ref: "#/components/schemas/userPassword" required: - oldPassword - newPassword responses: "200": description: Пароль успешно обновлен и ранее выпущенные токены отозваны. content: application/json: schema: type: object properties: status: type: string description: Должно принимать значение `ok`. example: ok required: - status "400": description: Новый пароль не соответствует требованиям безопасности. content: application/json: schema: $ref: "#/components/schemas/errorResponse" "401": description: Переданный токен не существует либо некорректен. content: application/json: schema: $ref: "#/components/schemas/errorResponse" "403": description: Указанный пароль не совпадает с действительным. content: application/json: schema: $ref: "#/components/schemas/errorResponse" /friends/add: post: summary: Добавить пользователя в друзья description: | Позволяет добавить другого пользователя к себе в друзья. Если указанный пользователь уже добавлен в друзья, верните успешный ответ. Сервер должен идентифицировать пользователя по переданному токену. Значение токена будет подставляться в заголовок `Authorization` в формате `Bearer {token}`. security: - bearerAuth: [] operationId: friendsAdd requestBody: description: | В теле запроса передается логин пользователя. required: true content: application/json: schema: type: object properties: login: $ref: "#/components/schemas/userLogin" required: - login responses: "200": description: Операция завершилась успешно. content: application/json: schema: type: object properties: status: type: string description: Должно принимать значение `ok`. example: ok required: - status "401": description: Переданный токен не существует либо некорректен. content: application/json: schema: $ref: "#/components/schemas/errorResponse" "404": description: Пользователь с указанным логином не найден. content: application/json: schema: $ref: "#/components/schemas/errorResponse" /friends/remove: post: summary: Удалить пользователя из друзей description: | Позволяет удалить пользователя из друзей. Если указанного пользователя нет в друзьях, верните успешный ответ. Сервер должен идентифицировать пользователя по переданному токену. Значение токена будет подставляться в заголовок `Authorization` в формате `Bearer {token}`. security: - bearerAuth: [] operationId: friendsRemove requestBody: description: | В теле запроса передается логин пользователя. required: true content: application/json: schema: type: object properties: login: $ref: "#/components/schemas/userLogin" required: - login responses: "200": description: Операция завершилась успешно. content: application/json: schema: type: object properties: status: type: string description: Должно принимать значение `ok`. example: ok required: - status "401": description: Переданный токен не существует либо некорректен. content: application/json: schema: $ref: "#/components/schemas/errorResponse" /friends: get: summary: Получение списка друзей description: | Используется для получения списка своих друзей. Для плавной работы приложения используется пагинация. Сервер должен идентифицировать пользователя по переданному токену. Значение токена будет подставляться в заголовок `Authorization` в формате `Bearer {token}`. security: - bearerAuth: [] operationId: friendsList parameters: - $ref: "#/components/parameters/paginationLimit" - $ref: "#/components/parameters/paginationOffset" responses: "200": description: | Список друзей пользователя, отсортированный по убыванию по дате последнего добавления в друзья. В начале идут друзья, которые были добавлены совсем недавно. content: application/json: schema: type: array items: type: object description: Описание друга. properties: login: $ref: "#/components/schemas/userLogin" addedAt: type: string description: | Время и дата, когда данный пользователь был добавлен в друзья в последний раз. Передается в формате RFC3339. example: 2006-01-02T15:04:05Z07:00 required: - login - addedAt "401": description: Переданный токен не существует либо некорректен. content: application/json: schema: $ref: "#/components/schemas/errorResponse" /posts/new: post: summary: Отправить публикацию description: | Используется для отправки публикации в ленту. Сервер должен идентифицировать пользователя по переданному токену. Значение токена будет подставляться в заголовок `Authorization` в формате `Bearer {token}`. security: - bearerAuth: [] operationId: submitPost requestBody: description: Информация о публикации. required: true content: application/json: schema: type: object properties: content: $ref: "#/components/schemas/postContent" tags: $ref: "#/components/schemas/postTags" required: - content - tags responses: "200": description: Публикация сохранена. Сервер назначает уникальный идентификатор и время создания публикации. content: application/json: schema: $ref: "#/components/schemas/post" "401": description: Переданный токен не существует либо некорректен. content: application/json: schema: $ref: "#/components/schemas/errorResponse" /posts/{postId}: get: summary: Получить ленту со своими постами description: | Используется для получения публикации по её идентификатору. Если публикация принадлежит пользователю с публичным профилем, её может получить любой другой аутентифицированный пользователь. Если профиль автора закрыт, только автор может получить публикацию по ID. Сервер должен идентифицировать пользователя по переданному токену. Значение токена будет подставляться в заголовок `Authorization` в формате `Bearer {token}`. security: - bearerAuth: [] operationId: getPostById parameters: - name: postId description: ID публикации. required: true in: path schema: $ref: "#/components/schemas/postId" responses: "200": description: Публикация найдена. content: application/json: schema: $ref: "#/components/schemas/post" "401": description: Переданный токен не существует либо некорректен. content: application/json: schema: $ref: "#/components/schemas/errorResponse" "404": description: Указанный пост не найден либо к нему нет доступа. content: application/json: schema: $ref: "#/components/schemas/errorResponse" /posts/feed/my: get: summary: Получить ленту со своими постами description: | Используется для получения списка своих постов. Для плавной работы приложения используется пагинация. Сервер должен идентифицировать пользователя по переданному токену. Значение токена будет подставляться в заголовок `Authorization` в формате `Bearer {token}`. security: - bearerAuth: [] operationId: getMyFeed parameters: - $ref: "#/components/parameters/paginationLimit" - $ref: "#/components/parameters/paginationOffset" responses: "200": description: | Список публикаций пользователя, отсортированных по убыванию по дате публикации. В начале идут публикации, которые были добавлены совсем недавно. content: application/json: schema: $ref: "#/components/schemas/post" "401": description: Переданный токен не существует либо некорректен. content: application/json: schema: $ref: "#/components/schemas/errorResponse" /posts/feed/{login}: get: summary: Получить ленту с постами другого пользователя description: | Используется для получения списка публикаций другого пользователя. Если профиль пользователя открыт, его посты доступны всем. Если профиль пользователя закрыт, его посты доступны самому пользователю и пользователям, на кого он подписан. Для плавной работы приложения используется пагинация. Сервер должен идентифицировать пользователя по переданному токену. Значение токена будет подставляться в заголовок `Authorization` в формате `Bearer {token}`. security: - bearerAuth: [] operationId: getFeedByOthers parameters: - name: login description: Логин пользователя. required: true in: path schema: $ref: "#/components/schemas/userLogin" - $ref: "#/components/parameters/paginationLimit" - $ref: "#/components/parameters/paginationOffset" responses: "200": description: | Список публикаций пользователя, отсортированных по убыванию по дате публикации. В начале идут публикации, которые были добавлены совсем недавно. content: application/json: schema: $ref: "#/components/schemas/post" "401": description: Переданный токен не существует либо некорректен. content: application/json: schema: $ref: "#/components/schemas/errorResponse" "404": description: Пользователь не найден либо к нему нет доступа. content: application/json: schema: $ref: "#/components/schemas/errorResponse" /posts/{postId}/like: post: summary: Лайк поста description: | Лайк поста. Сервер должен идентифицировать пользователя по переданному токену. Значение токена будет подставляться в заголовок `Authorization` в формате `Bearer {token}`. security: - bearerAuth: [] operationId: likstPost parameters: - name: postId description: ID публикации. required: true in: path schema: $ref: "#/components/schemas/postId" responses: "200": description: Лайк засчитан. content: application/json: schema: $ref: "#/components/schemas/post" "401": description: Переданный токен не существует либо некорректен. content: application/json: schema: $ref: "#/components/schemas/errorResponse" "404": description: Указанный пост не найден либо к нему нет доступа. content: application/json: schema: $ref: "#/components/schemas/errorResponse" /posts/{postId}/dislike: post: summary: Дизлайк поста description: | Дизлайк поста. Сервер должен идентифицировать пользователя по переданному токену. Значение токена будет подставляться в заголовок `Authorization` в формате `Bearer {token}`. security: - bearerAuth: [] operationId: dislikePost parameters: - name: postId description: ID публикации. required: true in: path schema: $ref: "#/components/schemas/postId" responses: "200": description: Дизлайк засчитан. content: application/json: schema: $ref: "#/components/schemas/post" "401": description: Переданный токен не существует либо некорректен. content: application/json: schema: $ref: "#/components/schemas/errorResponse" "404": description: Указанный пост не найден либо к нему нет доступа. content: application/json: schema: $ref: "#/components/schemas/errorResponse" components: schemas: countryAlpha2: type: string description: Двухбуквенный код, уникально идентифицирующий страну maxLength: 2 pattern: "[a-zA-Z]{2}" example: RU countryRegion: type: string description: Географический регион, к которому относится страна enum: - Europe - Africa - Americas - Oceania - Asia country: type: object description: Информация о стране из стандарта ISO 3166 properties: name: type: string description: Полное название страны maxLength: 100 alpha2: $ref: "#/components/schemas/countryAlpha2" alpha3: type: string description: Трехбуквенный код страны maxLength: 3 pattern: "[a-zA-Z]{3}" region: $ref: "#/components/schemas/countryRegion" required: - name - alpha2 - alpha3 example: name: Burkina Faso alpha2: BF alpha3: BFA region: Africa userLogin: type: string description: Логин пользователя maxLength: 30 pattern: "[a-zA-Z0-9-]+" example: yellowMonkey userEmail: type: string description: E-mail пользователя maxLength: 50 example: yellowstone1980@you.ru userPassword: type: string description: | Пароль пользователя, к которому предъявляются следующие требования: - Длина пароля не менее 6 символов. - Присутствуют латинские символы в нижнем и верхнем регистре. - Присутствует минимум одна цифра. minLength: 6 maxLength: 100 example: $aba4821FWfew01#.fewA$ userIsPublic: type: boolean description: | Является ли данный профиль публичным. Публичные профили доступны другим пользователям: если профиль публичный, любой пользователь платформы сможет получить информацию о пользователе. example: true userPhone: type: string description: Номер телефона пользователя в формате +123456789 pattern: \+[\d]+ example: "+74951239922" userImage: type: string description: Ссылка на фото для аватара пользователя example: https://http.cat/images/100.jpg maxLength: 200 userProfile: type: object description: Информация о профиле пользователя properties: login: $ref: "#/components/schemas/userLogin" email: $ref: "#/components/schemas/userEmail" countryCode: $ref: "#/components/schemas/countryAlpha2" isPublic: $ref: "#/components/schemas/userIsPublic" phone: $ref: "#/components/schemas/userPhone" image: $ref: "#/components/schemas/userImage" required: - login - email - countryCode - isPublic postId: type: string description: Уникальный идентификатор публикации, присвоенный сервером. example: 550e8400-e29b-41d4-a716-446655440000 postContent: type: string description: Текст публикации. example: Свеча на 400! Покупаем, докупаем и фиксируем прибыль. maxLength: 1000 postTags: type: array description: Список тегов публикации. items: type: string description: Значение тега. example: тинькофф maxLength: 20 example: - тинькофф - спббиржа - moex post: type: object description: Пользовательская публикация. properties: id: $ref: "#/components/schemas/postId" content: $ref: "#/components/schemas/postContent" author: $ref: "#/components/schemas/userLogin" tags: $ref: "#/components/schemas/postTags" createdAt: type: string description: | Серверная дата и время в момент, когда пользователь отправил данную публикацию. Передается в формате RFC3339. example: 2006-01-02T15:04:05Z07:00 likesCount: type: integer minimum: 0 default: 0 description: Число лайков, набранное публикацией. dislikesCount: type: integer minimum: 0 default: 0 description: Число дизлайков, набранное публикацией. required: - id - content - author - tags - createdAt - likesCount - dislikesCount errorResponse: type: object description: Используется для возвращения ошибки пользователю properties: reason: type: string description: Описание ошибки в свободной форме minLength: 5 required: - reason example: reason: <объяснение, почему запрос пользователя не может быть обработан> parameters: paginationLimit: in: query name: limit required: false description: | Максимальное число возвращаемых объектов. Используется для запросов с пагинацией. Сервер должен возвращать максимальное допустимое число объектов. schema: type: integer format: int32 minimum: 0 maximum: 50 default: 5 paginationOffset: in: query name: offset required: false description: | Какое количество объектов должно быть пропущено с начала. Используется для запросов с пагинацией. schema: type: integer format: int32 default: 0 securitySchemes: bearerAuth: type: http scheme: bearer