# НТО 2025. II отборочный этап. Командные задания — Backend Решение
## 📖 Предыстория

В компании S есть возможность бронирования мест в пространствах, предназначенных под общее использование (open-space). На данный момент для бронирования места используются различные способы бронирования, разработанные в каждом офисе индивидуально.
Администрации компании S требуется мобильное приложение, как для рядовых сотрудников, так и для администрации с возможностью просмотра забронированных мест.

## 📑 Технологический стек

- Java 17
- Spring Boot
- H2
- Liquibase


## 🛠️ Техническое задание

Требуется разработать серверное приложение на Java с использованием Spring Boot, которое работает на основе протокола HTTP и взаимодействует с клиентами благодаря RESTful API.

Для хранения данных о сотрудниках и их посещениях должна использоваться реляционная база данных (H2). Схема БД должна создаваться liquibase-скриптами. ID-поля всех сущностей, сохраняемых в базе, должны выдаваться на уровне БД. Стратегия генерации ID - автоинкремент (1, 2, 3, 4…)

Сотрудникам не нужно регистрироваться, все данные в базе должны быть предзаполнены liquibase-скриптами при запуске серверного приложения. Данные для предзаполнения таблиц представлены ниже.

Картинки для аватаров пользователей не должны храниться в БД. Должны быть сохранены лишь URL-адреса на ресурсы, откуда в последующем мобильное приложение загрузит соответствующее изображение.

Сервер разрабатывается на основе предоставляемой заготовки проекта. Версии зависимостей и сами зависимости изменяться не должны.


## 📂 Правила работы с проектом-заготовкой

В предоставленном проекте необходимо изучить, но никак не модифицировать, не перемещать и не удалять следующие файлы:
- `pom.xml`
- `application.yml`
- все файлы из `db.changelog`

Кроме описанных выше файлов, в проекте уже созданы основные классы-сущности и добавлены пустые классы всех слоев. В этих классах необходимо будет написать программный код и добавить аннотации для реализации описанного задания. Наименования классов и прочий код уже написанный в предоставляемом проекте **изменять/удалять не нужно, необходимо их доработать**. Добавлять свои дополнительные классы в проект можно.

Создание таблиц в БД и предзаполнение их требуемыми данными уже реализовано в заготовке при помощи liquibase. В одной из сущностей добавлены аннотации для реализации связи “один ко многим”, обратите внимание, что в проекте потребуется еще связь данного типа.


## 🌐 Где необходимо разместить сервер

Серверное приложение должно быть разработано и протестировано локально (**не требуется** размещать сервер удаленно и осуществлять его функционирование 24/7).


## 📋 Технические требования к серверу и его ответам клиенту

Для конфигурирования Вашего сервера (его хоста/IP адреса) используйте константы из файла `Constants.kt`.

| **Тип запроса** | **Путь**              | **Описание**              | **Параметры/Тело**                                                                                     | **Ответы**                                                                                                                                                                                                                                                                                                                                                                                   |
|-----------------|-----------------------|---------------------------|--------------------------------------------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| **GET**         | `api/<CODE>/auth`   | Проверка авторизации   | `<CODE>` - код для входа                                                                               | `400` - что-то пошло не так<br>`401` - кода не существует<br>`200` - данный код существует - можно пользоваться приложением                                                                                                                                                                                                                                                                  |
| **GET**         | `api/<CODE>/info`   | Получение информации о пользователе   | `<CODE>` - код для входа                                                                               | `400` - что-то пошло не так<br>`401` - кода не существует<br>`200` - ОК<br><pre>{<br>  "name":"Иванов Петр Федорович",<br>  "photoUrl":"<https://funnyducks.ru/upload/iblock/0cd/0cdeb7ec3ed6fddda0f90fccee05557d.jpg>",<br>  "booking":{<br>    "2025-01-05": {"id":1,"place":"102"},<br>    "2025-01-06": {"id":2,"place":"209.13"},<br>    "2025-01-09": {"id":3,"place":"Зона 51. 50"}<br>  }<br>}</pre> |
| **GET**         | `api/<CODE>/booking`   | Получение доступных для бронирования мест   | `<CODE>` - код для входа                                                                               | `400` - что-то пошло не так<br>`401` - кода не существует<br>`200` - ОК<br><pre>{<br>  "2025-01-05": [{"id": 1, "place": "102"},{"id": 2, "place": "209.13"}],<br>  "2025-01-06": [{"id": 3, "place": "Зона 51. 50"}],<br>  "2025-01-07": [{"id": 1, "place": "102"},{"id": 2, "place": "209.13"}],<br>  "2025-01-08": [{"id": 2, "place": "209.13"}]<br>}</pre> **Список дат ограничен текущим + 3 днями** (ответ от сервера содержит 4 дня со свободными местами для каждого)                                                                                                                                                                                                                                                                                       
| **POST**        | `api/<CODE>/book`   | Создание нового бронирования   | `<CODE>` - код для входа<br>Тело: <br> <pre>{<br>  “date”: “2025-01-05”,<br>  “placeId”: 1 <br>}</pre> |`400` - что-то пошло не так<br>`401` - кода не существует<br>`409` - уже забронировано<br>`201` - бронирование успешно создано                                                                                                                                                                                                                                                                                        


## 📊 Пример данных

Таблица сотрудников:

| **id** | **name**  | **code**                        | **photo_url**                                                                                   | 
|--------|-----------|---------------------------------|---------------------------------------------------------------------------------------------|
| 1      | Ivanov Ivan | 1111          | https://catalog-cdn.detmir.st/media/2fe02057f9915e72a378795d32c79ea9.jpeg               | 
| 2      | Petrov Petr    | 2222      | https://catalog-cdn.detmir.st/media/2fe02057f9915e72a378795d32c79ea9.jpeg               | 
| 3      | Kozlov Oleg   | 3333   | https://catalog-cdn.detmir.st/media/2fe02057f9915e72a378795d32c79ea9.jpeg               | 
| 4      | Smirnova Anna   | 4444    | https://catalog-cdn.detmir.st/media/2fe02057f9915e72a378795d32c79ea9.jpeg               | 


Таблица мест для бронирования:

| **id** | **place_name**  |
|--------|-----------------|
| 1      | K-19    | 
| 2      | M-16    |
| 3      | T-1   |


Таблица бронирований:

| **id** | **date**  | **place_id** | **employee_id**  |
|--------|-----------|--------------|------------------|
| 1      | 2025-11-08 | 1 | 1 |
| 2      | 2025-11-10 | 2 | 2 |


# 📝 Решение

Работу необходимо осуществлять в предоставленном проекте-заготовке (шаблоне).
Когда завершите разработку, создайте пулреквест и запустите workflow в учебной системе.


## ✅ Особенности оценивания

При тестировании сервера на него поочередно отправляются команды, описанные в API и ожидаются определенные корректные ответы.
Сервер и приложение тестируются независимо.

