Skip to content

OlegProg2020/animal-chipization

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

11 Commits
 
 
 
 

Repository files navigation

RESTful API сервис, разработанный в рамках международной олимпиады «ИТ-Планета» 2023, конкурса «Прикладное программирование if...else» от компании SimbirSoft

С данным проектом прошел в финал конкурса, набрав 93 балла (функционал 65/70, архитектура 14/15, качество кода 14/15).

С заданием можете ознакомиться по ссылке: https://disk.yandex.ru/i/kjcDG19neVEV0A.

Использованные технологии и паттерны

  1. Spring Boot
  2. Spring Security
  3. Spring Web
  4. Spring Validator
  5. JPA
  6. JDBC
  7. PostgreSQL
  8. Liquibase
  9. SPGIST index
  10. Docker
  11. Specification
  12. Java Topology Suite
  13. Model Mapper
  14. Patterns: Builder, Factory, Proxy

Steps to Setup

1) Скопируйте приложение:

git clone https://github.com/OlegProg2020/animal-chipization.git

2) Перейдите в корневую папку проекта.

3) Создайте файл .jar:

mvnw.cmd clean package -DskipTests=true

4) Создайте Docker image:

docker build ./ -t webapi

5) Запустите приложение:

docker-compose up -d

Приложение начнет работать по адресу http://localhost:8080

API Declarations

1) Аутентификация пользователя

API 1: Регистрация нового аккаунта

POST - /registration

- request
Body {
    "firstName": "string", // Имя пользователя
    "lastName": "string", // Фамилия пользователя
    "email": "string", // Адрес электронной почты
    "password": "string" // Пароль от аккаунта пользователя
}

- response
Body {
    "id": "int", // Идентификатор аккаунта пользователя
    "firstName": "string", // Имя пользователя
    "lastName": "string", // Фамилия пользователя
    "email": "string", // Адрес электронной почты
    "role": "string", // Роль аккаунта пользователя, по умолчанию при регистрации "USER"
}
Условие Статус
Запрос успешно выполнен 201
firstName = null,
firstName = "" или состоит из пробелов,
lastName = null,
lastName = "" или состоит из пробелов,
email = null,
email = "" или состоит из пробелов,
email аккаунта не валидный,
password = null,
password = "" или состоит из пробелов
Неверные авторизационные данные
400
Запрос от авторизованного аккаунта 403
Аккаунт с таким email уже существует 409

2) Аккаунт пользователя

API 1: Получение информации об аккаунте пользователя

GET - /accounts/{accountId}
{accountId}: "int"	// Идентификатор аккаунта пользователя

- request
Body {
  empty
}

- response
Body {
    "id": "int", // Идентификатор аккаунта пользователя
    "firstName": "string", // Имя пользователя
    "lastName": "string", // Фамилия пользователя
    "email": "string" // Адрес электронной почты
    "role": "string", // Роль аккаунта пользователя, по умолчанию при регистрации "USER"
}
Условие Статус
Запрос успешно выполнен 200
accountId = null,
accountId <= 0
400
Запрос от неавторизованного аккаунта 401
Аккаунт с ролью "USER" или "CHIPPER" пытается получить информацию о чужом аккаунте
(даже если такого аккаунта нет)
403
Для аккаунтов с ролями "ADMIN":
Аккаунт с таким accountId не найден
404

API 2: Поиск аккаунтов пользователей по параметрам

GET - /accounts/search
  ?firstName={firstName}
  &lastName={lastName}
  &email={email}
  &from={from}
  &size={size}
{firstName}: "string",	// Имя пользователя, может использоваться только часть имени без учета регистра, если null - не учитывается
{lastName}: "string",	// Фамилия пользователя, может использоваться только часть фамилии без учета регистра, если null - не учитывается
{email}: "string",	// Адрес электронной почты, может использоваться только часть адреса электронной почты без учета регистра, если null - не учитывается
{from}: "int"		// Количество элементов, которое необходимо пропустить для формирования страницы с результатами (по умолчанию 0)
{size}: "int"		// Количество элементов на странице (по умолчанию 10)

- request
Body {
  empty
}

- response
Body [
      {
        "id”: "int", // Идентификатор аккаунта пользователя
        "firstName": "string", // Имя пользователя
        "lastName": "string", // Фамилия пользователя
        "email": "string" // Адрес электронной почты
        "role": "string", // Роль аккаунта пользователя, по умолчанию "USER"
      }
]

Результаты поиска сортируются по id аккаунта от наименьшего к наибольшему
Условие Статус
Запрос успешно выполнен 200
from < 0,
size <= 0
400
Запрос от неавторизованного аккаунта 401
У аккаунта нет роли "ADMIN" 403

API 3: Добавление аккаунта пользователя

POST - /accounts

- request
Body {
    "firstName": "string", // Имя пользователя
    "lastName": "string", // Фамилия пользователя
    "email": "string", // Адрес электронной почты
    "password": "string", // Пароль от аккаунта
    "role": "string", // Роль аккаунта пользователя, доступные значения "ADMIN", "CHIPPER", "USER"
}

- response
Body {
    "id": "int", // Идентификатор аккаунта пользователя
    "firstName": "string", // Новое имя пользователя
    "lastName": "string", // Новая фамилия пользователя
    "email": "string", // Новый адрес электронной почты
    "role": "string", // Роль аккаунта пользователя
}
Условие Статус
Запрос успешно выполнен 201
firstName = null,
firstName = "" или состоит из пробелов,
lastName = null,
lastName = "" или состоит из пробелов,
email = null,
email = "" или состоит из пробелов,
email аккаунта не валидный,
password = null,
password = "" или состоит из пробелов,
role != "ADMIN", "CHIPPER", "USER"
400
Запрос от неавторизованного аккаунта 401
У аккаунта нет роли "ADMIN" 403
Аккаунт с таким email уже существует 409

API 4: Обновление данных аккаунта пользователя

PUT - /accounts/{accountId}
{accountId}: "int"	// Идентификатор аккаунта пользователя

- request
Body {
    "firstName": "string", // Новое имя пользователя
    "lastName": "string", // Новая фамилия пользователя
    "email": "string", // Новый адрес электронной почты
    "password": "string" // Новый пароль от аккаунта
    "role": "string", // Роль аккаунта пользователя, доступные значения "ADMIN", "CHIPPER", "USER"
}

- response
Body {
    "id": "int", // Идентификатор аккаунта пользователя
    "firstName": "string", // Новое имя пользователя
    "lastName": "string", // Новая фамилия пользователя
    "email": "string", // Новый адрес электронной почты
    "role": "string", // Роль аккаунта пользователя
}
Условие Статус
Запрос успешно выполнен 200
accountId = null,
accountId <= 0,
firstName = null,
firstName = "" или состоит из пробелов,
lastName = null,
lastName = "" или состоит из пробелов,
email = null,
email = "" или состоит из пробелов,
email аккаунта не валидный,
password = null,
password = "" или состоит из пробелов,
role != "ADMIN", "CHIPPER", "USER"
400
Запрос от неавторизованного аккаунта 401
Для аккаунтов с ролями "CHIPPER" и "USER":
Обновление не своего аккаунта.
Аккаунт не найден
403
Для аккаунтов с ролью "ADMIN":
Аккаунт не найден
404
Аккаунт с таким email уже существует 409

API 5: Удаление аккаунта пользователя

DELETE - /accounts/{accountId}
{accountId}: "int"	// Идентификатор аккаунта пользователя

- request
Body {
  empty
}

- response
Body {
  empty
}
Условие Статус
Запрос успешно выполнен 200
accountId = null,
accountId <= 0,
Аккаунт связан с животным
400
Запрос от неавторизованного аккаунта 401
Для аккаунтов с ролями "CHIPPER" и "USER":
Удаление не своего аккаунта.
Аккаунт не найден
403
Для аккаунтов с ролью "ADMIN":
Аккаунт не найден
404

3) Точка локации животных

API 1: Получение информации о точке локации животных

GET - /locations/{pointId}
{pointId}: "long"	// Идентификатор точки локации

- request
Body {
  empty
}

- response
Body {
    "id": "long", // Идентификатор точки локации
    "latitude": "double", // Географическая широта в градусах
    "longitude": "double" // Географическая долгота в градусах
}
Условие Статус
Запрос успешно выполнен 200
pointId = null,
pointId <= 0
400
Запрос от неавторизованного аккаунта 401
Точка локации с таким pointId не найдена 404

API 2: Добавление точки локации животных

POST - /locations

- request
Body {
    "latitude": "double", // Географическая широта в градусах
    "longitude": "double" // Географическая долгота в градусах
}

- response
Body {
    "id": "long", // Идентификатор точки локации
    "latitude": "double", // Географическая широта в градусах
    "longitude": "double" // Географическая долгота в градусах
}
Условие Статус
Запрос успешно выполнен 201
latitude = null,
latitude < -90,
latitude > 90,
longitude = null,
longitude < -180,
longitude > 180
400
Запрос от неавторизованного аккаунта 401
У аккаунта нет роли "ADMIN" или "CHIPPER" 403
Точка локации с такими latitude и longitude уже существует 409

API 3: Изменение точки локации животных

PUT - /locations/{pointId}
{pointId}: "long"	// Идентификатор точки локации

- request
Body {
    "latitude": "double", // Новая географическая широта в градусах
    "longitude": "double" // Новая географическая долгота в градусах
}

- response
Body {
    "id": "long", // Идентификатор точки локации
    "latitude": "double", // Новая географическая широта в градусах
    "longitude": "double" // Новая географическая долгота в градусах
}
Условие Статус
Запрос успешно выполнен 200
pointId = null,
pointId <= 0,
latitude = null,
latitude < -90,
latitude > 90,
longitude = null,
longitude < -180,
longitude > 180
Если точка используется как точка чипирования или как посещенная точка, то её изменять нельзя
400
Запрос от неавторизованного аккаунта 401
У аккаунта нет роли "ADMIN" или "CHIPPER" 403
Точка локации с таким pointId не найдена 404
Точка локации с такими latitude и longitude уже существует 409

API 4: Удаление точки локации животных

DELETE - /locations/{pointId}
{pointId}: "long"	// Идентификатор точки локации

- request
Body {
  empty
}

- response
Body {
  empty
}
Условие Статус
Запрос успешно выполнен 200
pointId = null,
pointId <= 0,
Точка локации связана с животным
400
Запрос от неавторизованного аккаунта 401
У аккаунта нет роли "ADMIN" 403
Точка локации с таким pointId не найдена 404

4) Зоны

API 1: Получение информации о зоне

GET - /areas/{areaId}
{areaId}: "long"		// Идентификатор зоны

- request
Body {
  empty
}

- response
Body {
    "id": "long", // Идентификатор зоны
    "name": "string", // Название зоны
    "areaPoints": [
        {
            "longitude": "double", // Географическая долгота в градусах
            "latitude": "double" // Географическая широта в градусах
        },
        {
            "longitude": "double", // Географическая долгота в градусах
            "latitude": "double" // Географическая широта в градусах
        },
        {
            "longitude": "double", // Географическая долгота в градусах
            "latitude": "double" // Географическая широта в градусах
        }
    ]
}
Условие Статус
Запрос успешно выполнен 200
areaId = null,
areaId <= 0
400
Запрос от неавторизованного аккаунта 401
Зона с таким areaId не найдена 404

API 2: Добавление зоны

POST - /areas

- request
Body {
    "name": "string", // Название зоны
    "areaPoints": [
        {
            "longitude": "double", // Географическая долгота в градусах
            "latitude": "double" // Географическая широта в градусах
        },
        {
            "longitude": "double", // Географическая долгота в градусах
            "latitude": "double" // Географическая широта в градусах
        },
        {
            "longitude": "double", // Географическая долгота в градусах
            "latitude": "double" // Географическая широта в градусах
        }
    ]
}

- response
Body {
    "id": "long", // Идентификатор зоны
    "name": "string", // Название зоны
    "areaPoints": [
        {
            "longitude": "double", // Географическая долгота в градусах
            "latitude": "double" // Географическая широта в градусах
        },
        {
            "longitude": "double", // Географическая долгота в градусах
            "latitude": "double" // Географическая широта в градусах
        },
        {
            "longitude": "double", // Географическая долгота в градусах
            "latitude": "double" // Географическая широта в градусах
        }
    ]
}

ВНИМАНИЕ! Координаты точек в массиве указываются в порядке их соединения для образования замкнутого САМО НЕПЕРЕСЕКАЮЩЕГОСЯ многоугольника, то есть точки соединяются последовательно от первой к последней, последняя соединяется с первой, при этом полученные отрезки не должны пересекать друг друга
Условие Статус
Запрос успешно выполнен 201
name = null,
name = "" или состоит из пробелов,
areaPoints = null,
Одна или несколько точек из areaPoints = null,
longitude = null,
longitude < -180,
longitude > 180,
latitude = null,
latitude < -90,
latitude > 90,
areaPoints содержит меньше трех точек.
Все точки лежат на одной прямой.
Границы новой зоны пересекаются между собой.
Границы новой зоны пересекают границы уже существующей зоны.
Граница новой зоны находятся внутри границ существующей зоны.
Границы существующей зоны находятся внутри границ новой зоны.
Новая зона имеет дубликаты точек.
Новая зона состоит из части точек существующей зоны и находится на площади существующей зоны.
400
Запрос от неавторизованного аккаунта 401
У аккаунта нет роли "ADMIN" 403
Зона, состоящая из таких точек, уже существует. (При этом важен порядок, в котором указаны точки, но не важна начальная точка).
Зона с таким name уже существует
409

API 3: Обновление зоны

PUT - /areas/{areaId}
{areaId}: "long"		// Идентификатор зоны

- request
Body {
    "name": "string", // Название зоны
    "areaPoints": [
        {
            "longitude": "double", // Географическая долгота в градусах
            "latitude": "double" // Географическая широта в градусах
        },
        {
            "longitude": "double", // Географическая долгота в градусах
            "latitude": "double" // Географическая широта в градусах
        },
        {
            "longitude": "double", // Географическая долгота в градусах
            "latitude": "double" // Географическая широта в градусах
        }
    ]
}

- response
Body {
    "id": "long", // Идентификатор зоны
    "name": "string" // Название зоны
    "areaPoints": [
        {
            "longitude": "double", // Географическая долгота в градусах
            "latitude": "double" // Географическая широта в градусах
        },
        {
            "longitude": "double", // Географическая долгота в градусах
            "latitude": "double" // Географическая широта в градусах
        },
        {
            "longitude": "double", // Географическая долгота в градусах
            "latitude": "double" // Географическая широта в градусах
        }
    ]
}

ВНИМАНИЕ! Координаты точек в массиве указываются в порядке их соединения для образования замкнутого САМО НЕПЕРЕСЕКАЮЩЕГОСЯ многоугольника, то есть точки соединяются последовательно от первой к последней, последняя соединяется с первой, при этом полученные отрезки не должны пересекать друг друга
Условие Статус
Запрос успешно выполнен 200
areaId = null,
areaId <= 0,
name = null,
name = "" или состоит из пробелов,
areaPoints = null,
Одна или несколько точек из areaPoints = null,
longitude = null,
longitude < -180,
longitude > 180,
latitude = null,
latitude < -90,
latitude > 90
areaPoints содержит меньше трех точек.
Все точки лежат на одной прямой.
Границы новой зоны пересекаются между собой.
Границы новой зоны пересекают границы уже существующей зоны.
Новая зона имеет дубликаты точек.
Граница новой зоны находятся внутри границ существующей зоны.
Границы существующей зоны находятся внутри границ новой зоны.
Новая зона состоит из части точек существующей зоны и находится на площади существующей зоны.
400
Запрос от неавторизованного аккаунта 401
У аккаунта нет роли "ADMIN" 403
Зона, состоящая из таких точек, уже существует. (При этом важен порядок, в котором указаны точки, но не важна начальная точка).
Зона с таким name уже существует
409

API 4: Удаление зоны

DELETE - /areas/{areaId}
{areaId}: "long"		// Идентификатор зоны

- request
Body {
  empty
}

- response
Body {
  empty
}
Условие Статус
Запрос успешно выполнен 200
areaId = null,
areaId <= 0
400
Запрос от неавторизованного аккаунта 401
У аккаунта нет роли "ADMIN" 403
Зона с таким areaId не найдена 404

5) Типы животных

API 1: Получение информации о типе животного

GET - /animals/types/{typeId}
{typeId}: "long"		// Идентификатор типа животного

- request
Body {
  empty
}

- response
Body {
    "id": "long", // Идентификатор типа животного
    "type": "string" // Тип животного
}
Условие Статус
Запрос успешно выполнен 200
typeId = null,
typeId <= 0
400
Запрос от неавторизованного аккаунта 401
Тип животного с таким typeId не найден 404

API 2: Добавление типа животного

POST - /animals/types

- request
Body {
    "type": "string"		// Тип животного
}

- response
Body {
    "id": "long",		// Идентификатор типа животного
    "type": "string"		// Тип животного
}
Условие Статус
Запрос успешно выполнен 201
type = null,
type = "" или состоит из пробелов
400
Запрос от неавторизованного аккаунта 401
У аккаунта нет роли "ADMIN" или "CHIPPER" 403
Тип животного с таким type уже существует 409

API 3: Изменение типа животного

PUT - /animals/types/{typeId}
{typeId}: "long"		// Идентификатор типа животного

- request
Body {
    "type": "string"		// Новый тип животного
}

- response
Body {
		"id": "long",		// Идентификатор типа животного
    "type": "string"		// Новый тип животного
}
Условие Статус
Запрос успешно выполнен 200
typeId = null,
typeId <= 0,
type = null,
type = "" или состоит из пробелов
400
Запрос от неавторизованного аккаунта 401
У аккаунта нет роли "ADMIN" или "CHIPPER" 403
Тип животного с таким typeId не найден 404
Тип животного с таким type уже существует 409

API 4: Удаление типа животного

DELETE - /animals/types/{typeId}
{typeId}: "long"		// Идентификатор типа животного

- request
Body {
empty
}

- response
Body {
  empty
}
Условие Статус
Запрос успешно выполнен 200
typeId = null,
typeId <= 0
Есть животные с типом с typeId
400
Запрос от неавторизованного аккаунта 401
У аккаунта нет роли "ADMIN" 403
Тип животного с таким typeId не найден 404

6) Животное

API 1: Получение информации о животном

GET - /animals/{animalId}
{animalId}: "long"	// Идентификатор животного

- request
Body {
  empty
}

- response
Body {
    "id": "long", // Идентификатор животного
    "animalTypes": "[long]", // Массив идентификаторов типов животного
    "weight": "float", // Масса животного, кг
    "length": "float", // Длина животного, м
    "height": "float", // Высота животного, м
    "gender": "string", // Гендерный признак животного, доступные значения “MALE”, “FEMALE”, “OTHER”
    "lifeStatus": "string", // Жизненный статус животного, доступные значения “ALIVE”(устанавливается автоматически при добавлении нового животного), “DEAD”(можно установить при обновлении информации о животном)
    "chippingDateTime": "dateTime", // Дата и время чипирования в формате ISO-8601 (устанавливается автоматически на момент добавления животного)
    "chipperId": "int", // Идентификатор аккаунта с ролью "CHIPPER" или "ADMIN"
    "chippingLocationId": "long", // Идентификатор точки локации животных
    "visitedLocations": "[long]", // Массив идентификаторов объектов с информацией о посещенных точках локаций
    "deathDateTime": "dateTime" // Дата и время смерти животного в формате ISO-8601 (устанавливается автоматически при смене lifeStatus на “DEAD”). Равняется null, пока lifeStatus = “ALIVE”.
}
Условие Статус
Запрос успешно выполнен 200
animalId = null,
animalId <= 0
400
Запрос от неавторизованного аккаунта 401
Животное с animalId не найдено 404

API 2: Поиск животных по параметрам

GET - /animals/search?
  startDateTime={startDateTime}
  &endDateTime={endDateTime}
  &chipperId={chipperId}
  &chippingLocationId={chippingLocationId}
  &lifeStatus={lifeStatus}
  &gender={gender}
  &from=0
  &size=10
{startDateTime}: "dateTime",	// Дата и время, не раньше которых произошло чипирование животного в формате ISO-8601, если null - не учитывается
{endDateTime}: "dateTime",	// Дата и время, не позже которых произошло чипирование животного в формате ISO-8601, если null - не учитывается
{chipperId}: "int",		// Идентификатор аккаунта с ролью "CHIPPER" или "ADMIN", если null - не учитывается
{chippingLocationId}: "long",	// Идентификатор локации чипирования животного, если null - не учитывается
{lifeStatus}: "string",		// Жизненный статус животного, если null - не учитывается
{gender}:  "string",		// Гендерная принадлежность животного, если null - не учитывается
{from}: "int",			// Количество элементов, которое необходимо пропустить для формирования страницы с результатами (по умолчанию 0)
{size}: "int",			// Количество элементов на странице (по умолчанию 10)

- request
Body {
  empty
}

- response
Body [
      {
        "id": "long", // Идентификатор животного
        "animalTypes": "[long]", // Массив идентификаторов типов животного
        "weight": "float", // Масса животного, кг
        "length": "float", // Длина животного, м
        "height": "float", // Высота животного, м
        "gender": "string", // Гендерный признак животного, доступные значения “MALE”, “FEMALE”, “OTHER”
        "lifeStatus": "string", // Жизненный статус животного, доступные значения “ALIVE”(устанавливается автоматически при добавлении нового животного), “DEAD”(можно установить при обновлении информации о животном)
        "chippingDateTime": "dateTime", // Дата и время чипирования в формате ISO-8601 (устанавливается автоматически на момент добавления животного)
        "chipperId": "int", // Идентификатор аккаунта с ролью "CHIPPER" или "ADMIN"
        "chippingLocationId": "long", // Идентификатор точки локации животных
        "visitedLocations": "[long]", // Массив идентификаторов объектов с информацией о посещенных точках локаций
        "deathDateTime": "dateTime" // Дата и время смерти животного в формате ISO-8601 (устанавливается автоматически при смене lifeStatus на “DEAD”). Равняется null, пока lifeStatus = “ALIVE”.
      }
]

Результаты поиска сортируются по id животного от наименьшего к наибольшему
Условие Статус
Запрос успешно выполнен 200
from < 0,
size <= 0,
startDateTime - не в формате ISO-8601,
endDateTime - не в формате ISO-8601,
chipperId <= 0,
chippingLocationId <= 0,
lifeStatus != “ALIVE”, “DEAD”,
gender != “MALE”, “FEMALE”, “OTHER”
400
Запрос от неавторизованного аккаунта 401

API 3: Добавление нового животного

POST - /animals

- request
Body {
    "animalTypes": "[long]", // Массив идентификаторов типов животного
    "weight": "float", // Масса животного, кг
    "length": "float", // Длина животного, м
    "height": "float", // Высота животного, м
    "gender": "string", // Гендерный признак животного, доступные значения “MALE”, “FEMALE”, “OTHER”
    "chipperId": "int", // Идентификатор аккаунта с ролью "CHIPPER" или "ADMIN"
    "chippingLocationId": "long" // Идентификатор точки локации животных
}

- response
Body {
    "id": "long", // Идентификатор животного
    "animalTypes": "[long]", // Массив идентификаторов типов животного
    "weight": "float", // Масса животного, кг
    "length": "float", // Длина животного, м
    "height": "float", // Высота животного, м
    "gender": "string", // Гендерный признак животного, доступные значения “MALE”, “FEMALE”, “OTHER”
    "lifeStatus": "string", // Жизненный статус животного, доступные значения “ALIVE”(устанавливается автоматически при добавлении нового животного), “DEAD”(можно установить при обновлении информации о животном)
    "chippingDateTime": "dateTime", // Дата и время чипирования в формате ISO-8601 (устанавливается автоматически на момент добавления животного)
    "chipperId": "int", // Идентификатор аккаунта с ролью "CHIPPER" или "ADMIN"
    "chippingLocationId": "long", // Идентификатор точки локации животных
    "visitedLocations": "[long]", // Массив идентификаторов объектов с информацией о посещенных точках локаций
    "deathDateTime": "dateTime" // Дата и время смерти животного в формате ISO-8601 (устанавливается автоматически при смене lifeStatus на “DEAD”). Равняется null, пока lifeStatus = “ALIVE”.
}
Условие Статус
Запрос успешно выполнен 201
animalTypes = null,
animalTypes.size() <= 0
Элемент массива animalTypes = null
Элемент массива animalTypes <= 0
weight = null,
weight <=0,
length = null,
length <=0,
height = null,
height <=0,
gender = null,
gender != "MALE", "FEMALE", "OTHER",
chipperId = null,
chipperId <=0,
chippingLocationId = null,
chippingLocationId <=0
400
Запрос от неавторизованного аккаунта 401
У аккаунта нет роли "ADMIN" или "CHIPPER" 403
Тип животного не найден,
Аккаунт с chipperId не найден,
Точка локации с chippingLocationId не найдена
404

API 4: Обновление информации о животном

PUT - /animals/{animalId}
{animalId}: "long"	// Идентификатор животного

- request
Body {
    "weight": "float", // Масса животного, кг
    "length": "float", // Длина животного, м
    "height": "float", // Высота животного, м
    "gender": "string", // Гендерный признак животного, доступные значения “MALE”, “FEMALE”, “OTHER”
    "lifeStatus": "string", // Жизненный статус животного, доступные значения “ALIVE”(устанавливается автоматически при добавлении нового животного), “DEAD”(можно установить при обновлении информации о животном)
    "chipperId": "int", // Идентификатор аккаунта с ролью "CHIPPER" или "ADMIN"
    "chippingLocationId": "long" // Идентификатор точки локации животных
}

- response
Body {
    "id": "long", // Идентификатор животного
    "animalTypes": "[long]", // Массив идентификаторов типов животного
    "weight": "float", // Масса животного, кг
    "length": "float", // Длина животного, м
    "height": "float", // Высота животного, м
    "gender": "string", // Гендерный признак животного, доступные значения “MALE”, “FEMALE”, “OTHER”
    "lifeStatus": "string", // Жизненный статус животного, доступные значения “ALIVE”(устанавливается автоматически при добавлении нового животного), “DEAD”(можно установить при обновлении информации о животном)
    "chippingDateTime": "dateTime", // Дата и время чипирования в формате ISO-8601 (устанавливается автоматически на момент добавления животного)
    "chipperId": "int", // Идентификатор аккаунта с ролью "CHIPPER" или "ADMIN"
    "chippingLocationId": "long", // Идентификатор точки локации животных
    "visitedLocations": "[long]", // Массив идентификаторов объектов с информацией о посещенных точках локаций
    "deathDateTime": "dateTime" // Дата и время смерти животного в формате ISO-8601 (устанавливается автоматически при смене lifeStatus на “DEAD”). Равняется null, пока lifeStatus = “ALIVE”.
}
Условие Статус
Запрос успешно выполнен 200
animalId = null,
animalId <=0,
weight = null
weight <=0,
length = null
length <=0,
height = null
height <=0,
gender != “MALE”, “FEMALE”, “OTHER”,
lifeStatus != “ALIVE”, “DEAD”,
chipperId = null,
chipperId <=0,
chippingLocationId = null,
chippingLocationId <=0
Установка lifeStatus = “ALIVE”, если у животного
lifeStatus = “DEAD”
Новая точка чипирования совпадает с первой посещенной точкой локации
400
Запрос от неавторизованного аккаунта 401
У аккаунта нет роли "ADMIN" или "CHIPPER" 403
Животное с animalId не найдено
Аккаунт с chipperId не найден
Точка локации с chippingLocationId не найдена
404

API 5: Удаление животного

DELETE - /animals/{animalId}
{animalId}: "long"	// Идентификатор животного

- request
Body {
  empty
}

- response
Body {
  empty
}
Условие Статус
Запрос успешно выполнен 200
animalId = null,
animalId <=0
Животное покинуло локацию чипирования, при этом
есть другие посещенные точки
400
Запрос от неавторизованного аккаунта 401
У аккаунта нет роли "ADMIN" 403
Животное с animalId не найдено 404

API 6: Добавление типа животного к животному

POST - /animals/{animalId}/types/{typeId}
{animalId}: "long"	// Идентификатор животного
{typeId}: "long"		// Идентификатор типа животного

- request
Body {
  empty
}

- response
Body {
    "id": "long", // Идентификатор животного
    "animalTypes": "[long]", // Массив идентификаторов типов животного
    "weight": "float", // Масса животного, кг
    "length": "float", // Длина животного, м
    "height": "float", // Высота животного, м
    "gender": "string", // Гендерный признак животного, доступные значения “MALE”, “FEMALE”, “OTHER”
    "lifeStatus": "string", // Жизненный статус животного, доступные значения “ALIVE”(устанавливается автоматически при добавлении нового животного), “DEAD”(можно установить при обновлении информации о животном)
    "chippingDateTime": "dateTime", // Дата и время чипирования в формате ISO-8601 (устанавливается автоматически на момент добавления животного)
    "chipperId": "int", // Идентификатор аккаунта с ролью "CHIPPER" или "ADMIN"
    "chippingLocationId": "long", // Идентификатор точки локации животных
    "visitedLocations": "[long]", // Массив идентификаторов объектов с информацией о посещенных точках локаций
    "deathDateTime": "dateTime" // Дата и время смерти животного в формате ISO-8601 (устанавливается автоматически при смене lifeStatus на “DEAD”). Равняется null, пока lifeStatus = “ALIVE”.
}
Условие Статус
Запрос успешно выполнен 201
animalId = null,
animalId <= 0,
typeId = null,
typeId <= 0
400
Запрос от неавторизованного аккаунта 401
У аккаунта нет роли "ADMIN" или "CHIPPER" 403
Животное с animalId не найдено
Тип животного с typeId не найден
404

API 7: Изменение типа животного у животного

PUT - /animals/{animalId}/types
{animalId}: "long"	// Идентификатор животного

- request
Body {
  "oldTypeId": "long", 			// Идентификатор текущего типа животного
  "newTypeId": "long"  			// Идентификатор нового типа животного для замены
}

- response
Body {
    "id": "long", // Идентификатор животного
    "animalTypes": "[long]", // Массив идентификаторов типов животного
    "weight": "float", // Масса животного, кг
    "length": "float", // Длина животного, м
    "height": "float", // Высота животного, м
    "gender": "string", // Гендерный признак животного, доступные значения “MALE”, “FEMALE”, “OTHER”
    "lifeStatus": "string", // Жизненный статус животного, доступные значения “ALIVE”(устанавливается автоматически при добавлении нового животного), “DEAD”(можно установить при обновлении информации о животном)
    "chippingDateTime": "dateTime", // Дата и время чипирования в формате ISO-8601 (устанавливается автоматически на момент добавления животного)
    "chipperId": "int", // Идентификатор аккаунта с ролью "CHIPPER" или "ADMIN"
    "chippingLocationId": "long", // Идентификатор точки локации животных
    "visitedLocations": "[long]", // Массив идентификаторов объектов с информацией о посещенных точках локаций
    "deathDateTime": "dateTime" // Дата и время смерти животного в формате ISO-8601 (устанавливается автоматически при смене lifeStatus на “DEAD”). Равняется null, пока lifeStatus = “ALIVE”.
}
Условие Статус
Запрос успешно выполнен 200
animalId = null,
animalId <= 0,
oldTypeId = null,
oldTypeId <= 0,
newTypeId = null,
newTypeId <= 0
400
Запрос от неавторизованного аккаунта 401
У аккаунта нет роли "ADMIN" или "CHIPPER" 403
Животное с animalId не найдено
Тип животного с oldTypeId не найден
Тип животного с newTypeId не найден
Типа животного с oldTypeId нет у животного с animalId
404
Тип животного с newTypeId уже есть у животного с animalId
Животное с animalId уже имеет типы с oldTypeId и newTypeId
409

API 8: Удаление типа животного у животного

DELETE - /animals/{animalId}/types/{typeId}
{animalId}: "long"	// Идентификатор животного
{typeId}: "long"		// Идентификатор типа животного

- request
Body {
    empty
}

- response
Body {
    "id": "long", // Идентификатор животного
    "animalTypes": "[long]", // Массив идентификаторов типов животного
    "weight": "float", // Масса животного, кг
    "length": "float", // Длина животного, м
    "height": "float", // Высота животного, м
    "gender": "string", // Гендерный признак животного, доступные значения “MALE”, “FEMALE”, “OTHER”
    "lifeStatus": "string", // Жизненный статус животного, доступные значения “ALIVE”(устанавливается автоматически при добавлении нового животного), “DEAD”(можно установить при обновлении информации о животном)
    "chippingDateTime": "dateTime", // Дата и время чипирования в формате ISO-8601 (устанавливается автоматически на момент добавления животного)
    "chipperId": "int", // Идентификатор аккаунта с ролью "CHIPPER" или "ADMIN"
    "chippingLocationId": "long", // Идентификатор точки локации животных
    "visitedLocations": "[long]", // Массив идентификаторов объектов с информацией о посещенных точках локаций
    "deathDateTime": "dateTime" // Дата и время смерти животного в формате ISO-8601 (устанавливается автоматически при смене lifeStatus на “DEAD”). Равняется null, пока lifeStatus = “ALIVE”.
}
Условие Статус
Запрос успешно выполнен 200
animalId = null,
animalId <= 0,
typeId = null,
typeId <= 0
У животного только один тип и это тип с typeId
400
Запрос от неавторизованного аккаунта 401
У аккаунта нет роли "ADMIN" или "CHIPPER" 403
Животное с animalId не найдено
Тип животного с typeId не найден
У животного с animalId нет типа с typeId
404

7) Точка локации, посещенная животным

API 1: Просмотр точек локации, посещенных животным

GET - /animals/{animalId}/locations
  ?startDateTime=
  &endDateTime=
  &from={from}
  &size={size}
{animalId}: "long"		// Идентификатор животного
{startDateTime}: "dateTime"	// Дата и время, не раньше которых нужно искать посещенные точки локации животных в формате ISO-8601, если null - не учитывается
{endDateTime}: "dateTime"	// Дата и время, не позже которых нужно искать посещенные точки локации животных в формате ISO-8601, если null - не учитывается
{from}: "int"			// Количество элементов, которое необходимо пропустить для формирования страницы с результатами (по умолчанию 0)
{size}: "int"			// Количество элементов на странице (по умолчанию 10)

- request
Body {
    empty
}

- response
Body[
      {
          "id": "long", // Идентификатор объекта с информацией о посещенной точке локации
          "dateTimeOfVisitLocationPoint": "dateTime", // Дата и время посещения животным точки локации в формате ISO-8601
          "locationPointId": "long" // Идентификатор посещенной точки локации
      }
]

Результаты поиска сортируются по дате посещения точки от ранней к поздней
Условие Статус
Запрос успешно выполнен 200
animalId = null,
animalId <= 0,
from < 0,
size <= 0,
startDateTime - не в формате ISO-8601,
endDateTime - не в формате ISO-8601
400
Запрос от неавторизованного аккаунта 401
Животное с animalId не найдено 404

API 2: Добавление точки локации, посещенной животным

POST - /animals/{animalId}/locations/{pointId}
{animalId}: "long"	// Идентификатор животного
{pointId}: "long"	// Идентификатор точки локации

- request
Body {
    empty
}

- response
Body {
    "id": "long", // Идентификатор объекта с информацией о посещенной точке локации
    "dateTimeOfVisitLocationPoint": "dateTime", // Дата и время посещения животным точки локации в формате ISO-8601
    "locationPointId": "long" // Идентификатор посещенной точки локации
}
Условие Статус
Запрос успешно выполнен 201
animalId = null,
animalId <= 0,
pointId= null,
pointId <= 0,
У животного lifeStatus = "DEAD"
Животное находится в точке чипирования и никуда не перемещалось, попытка добавить точку локации, равную точке чипирования.
Попытка добавить точку локации, в которой уже находится животное
400
Запрос от неавторизованного аккаунта 401
У аккаунта нет роли "ADMIN" или "CHIPPER" 403
Животное с animalId не найдено
Точка локации с pointId не найдена
404

API 3: Изменение точки локации, посещенной животным

PUT - /animals/{animalId}/locations
{animalId}: "long"	// Идентификатор животного

- request
Body {
    "visitedLocationPointId": "long", // Идентификатор объекта с информацией о посещенной точке локации
    "locationPointId": "long" // Идентификатор посещенной точки локации
}

- response
Body {
    "id": "long", // Идентификатор объекта с информацией о посещенной точке локации
    "dateTimeOfVisitLocationPoint": "dateTime", // Дата и время посещения животным точки локации в формате ISO-8601
    "locationPointId": "long" // Идентификатор посещенной точки локации
}
Условие Статус
Запрос успешно выполнен 200
animalId = null,
animalId <= 0,
visitedLocationPointId = null,
visitedLocationPointId <= 0,
locationPointId = null,
locationPointId <= 0
Обновление первой посещенной точки на точку чипирования
Обновление точки на такую же точку
Обновление точки локации на точку, совпадающую со следующей и/или с предыдущей точками
400
Запрос от неавторизованного аккаунта 401
У аккаунта нет роли "ADMIN" или "CHIPPER" 403
Животное с animalId не найдено
Объект с информацией о посещенной точке локации
с visitedLocationPointId не найден.
У животного нет объекта с информацией о посещенной точке локации с visitedLocationPointId.
Точка локации с locationPointId не найдена
404

API 4: Удаление точки локации, посещенной животным

DELETE - /animals/{animalId}/locations/{visitedPointId}
{animalId}: "long"		// Идентификатор животного
{visitedPointId}: "long"		// Идентификатор объекта с информацией о посещенной     точке локации

- request
Body {
    empty
}

- response
Body {
    empty
}
Условие Статус
Запрос успешно выполнен
(Если удаляется первая посещенная точка локации, а вторая точка совпадает с точкой чипирования, то она удаляется автоматически)
200
animalId = null,
animalId <= 0
visitedPointId = null,
visitedPointId <= 0
400
Запрос от неавторизованного аккаунта 401
У аккаунта нет роли "ADMIN" 403
Животное с animalId не найдено
Объект с информацией о посещенной точке локации с visitedPointId не найден.
У животного нет объекта с информацией о посещенной точке локации с visitedPointId
404

8) Аналитика по зонам

API 1: Просмотр информации о перемещениях животных в зоне

GET - /areas/{areaId}/analytics
  ?startDate=
  &endDate=
{areaId}: "long",	// Идентификатор зоны
{startDate}: "date",	// Дата начала интервала в формате ISO-8601 (pattern "yyyy-MM-dd")
{endDate}: "date"	// Дата конца интервала в формате ISO-8601 (pattern "yyyy-MM-dd")

- request
Body {
    empty
}

- response
Body {
    "totalQuantityAnimals": "long", // Общее количество животных, находящихся в этой зоне в указанный интервал времени
    "totalAnimalsArrived": "long", // Общее количество посещений зоны в указанный интервал времени
    "totalAnimalsGone": "long", // Общее количество выходов из зоны в указанный интервал времени
    "animalsAnalytics": [
        {
            "animalType": "string", // Тип животных
            "animalTypeId": "long", // Идентификатор типа животных
            "quantityAnimals": "long", // Количество животных данного типа, находящихся в этой зоне в указанный интервал времени
            "animalsArrived": "long", // Количество животных данного типа, прибывших в эту зону в указанный интервал времени
            "animalsGone": "long", // Количество животных данного типа, покинувших эту зону в указанный интервал времени
        }
    ]
}

ВНИМАНИЕ! Одно и то же животное может несколько раз посетить и покинуть зону в указанный период. Для каждого животного учитывается только один вход в зону и один выход из нее.
Условие Статус
Запрос успешно выполнен 200
areaId = null,
areaId <= 0,
startDate - не в формате ISO-8601 (pattern "yyyy-MM-dd")
endDate - не в формате ISO-8601 (pattern "yyyy-MM-dd")
startDate >= endDate
400
Запрос от неавторизованного аккаунта 401
Зона с areaId не найдена 404

About

Restful animal chipization API for "IT-Planet 2023" contest

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published