> For the complete documentation index, see [llms.txt](https://endpoint-docs.gitbook.io/docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://endpoint-docs.gitbook.io/docs/geo-point/rest-api.md).

# REST API

## Архитектурные особенности

Система безопасности

* Многоуровневая аутентификация: Токены авторизации для большинства операций
* Иерархия прав доступа:
  * публичный доступ
  * для авторизованных пользователей
  * администраторы компаний
  * директора компаний
  * суперпользователи
* Шифрование данных: Конфиденциальная информация (телефон, e-mail) шифруется
* Валидация паролей: Проверка сложности

Работа с данными

* Хранимые процедуры: Все операции с БД через SQL-процедуры
* Пост-обработка: Фильтрация, сортировка и пагинация через ArrayManager
* Транзакционность: Сложные операции выполняются атомарно

## Общий пример кода запроса к REST API на PHP

Код для выполнения запроса написан на PHP с использованием cURL. Этот пример будет использоваться для отображения запроса к серверу с REST API и его ответа. Сейчас для REST API нет разницы, где и как будут переданы параметры запроса, поэтому все данные можно передавать в URI строке, но это допускается только на этапе разработки.

```php
<?php

// Данные для cURL
$method = '';
$action = '';
$data = array();
$headers = array();
$url = "";

// Инициализация cURL
$ch = curl_init();

// Настройка cURL
curl_setopt($ch, CURLOPT_URL, $url . $action . '?' . http_build_query($data));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

// Выполнение запроса
$response = curl_exec($ch);

// Проверка на ошибки
if (curl_errno($ch)) {
    echo 'Ошибка cURL: ' . curl_error($ch);
}

// Получение информации о запросе
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
echo "HTTP код: " . $httpCode . "\n";

// Закрытие cURL
curl_close($ch);

// Вывод ответа
echo "Ответ сервера:\n";
print_r(json_decode($response, true));

?>
```

## Класс Codifer

### Общее описание

Класс `Codifer` является контроллером для работы с геодезическим кодификатором - системой классификации и кодирования геодезических объектов. Наследуется от базового класса `Controller` и предоставляет функционал для загрузки, обновления и поиска кодов объектов в системе. Класс специализируется на обработке семантических данных и предоставлении релевантных кодов на основе поисковых фраз.

***

### Методы класса

#### 1. Метод `upload`

**Назначение:** Загружает и обновляет данные кодификатора в базе данных из внешнего XML-файла. Выполняет полный цикл обработки: чтение файла, парсинг семантических данных и загрузку в базу данных.

**Параметры запроса:**

* **Обязательные:**
  * `path` (string) - путь до файла кодификатора для анализа и загрузки
  * `auth` (string) - токен авторизации пользователя

**Требуемый уровень доступа:** `ACCESS_ROOT` (только для root-пользователей)

**Используемый HTTP-метод:** `POST`

**Требуемые права доступа к БД:**

* `SELECT`, `INSERT`, `UPDATE` для таблиц:
  * `gp_object`
  * `gp_object_field`
  * `gp_object_field_value`

Пример запроса:

```php
$method = 'POST';
$action = 'codifer.upload';
$data = array(
    'path' => 'https://gkyw.ru/Dop.semantic'
);
$headers = array(
    'AUTH: ' . USER_TOKEN
);
```

Ответ:

```php
HTTP код: 200
Ответ сервера:
Array
(
    [result] => 
    [message] => 1
    [time] => 11:44:17 12.11.2025
    [timezone] => Etc/GMT-3
    [timestamp] => 1762937057
)
```

**Бизнес-логика:**

1. **Чтение файла:** Загружает содержимое XML-файла через `file_get_contents($path)`
2. **Парсинг данных:** Вызывает метод `parseSemanticString($xmlString)` для обработки семантической структуры
3. **Загрузка в БД:** Вызывает метод `databaseUpload()` для сохранения данных в базу данных
4. **Ответ:** Возвращает успешный результат с кодом `OK`

**Особенности:**

* Работает с XML-форматом данных кодификатора
* Выполняет полную синхронизацию данных кодификатора
* Требует повышенных привилегий (root-доступ)

***

#### 2. Метод `get`

**Назначение:** Выполняет поиск кодов объектов в кодификаторе на основе произносимой фразы. Возвращает релевантные результаты с расчетом степени соответствия.

**Параметры запроса:**

* **Обязательные:**
  * `phrase` (string) - произносимая фраза для поиска подходящих кодов
  * `auth` (string) - токен авторизации пользователя

**Требуемый уровень доступа:** `ACCESS_ALL` (доступно всем пользователям, включая неавторизованных)

**Используемый HTTP-метод:** `GET`

Пример запроса:

```php
$method = 'GET';
$action = 'codifer.get';
$data = array(
    'phrase' => 'опора фонарная с четыремя фонарями'
);
$headers = array();
```

Ответ:

```php
HTTP код: 200
Ответ сервера:
Array
(
    [result] => Array
        (
            [0] => Array
                (
                    [CODE] => 100156
                    [NAME] => Опора с фонарём
                    [DESCRIPTION] => Стальная круглая опора с четыремя фонарями ;
                    [RELEVANCE] => 5.3
                    [FIELDS] => Array
                        (
                            [Материал] => Array
                                (
                                    [0] => Array
                                        (
                                            [TAG] => MATERIAL
                                            [TYPE] => enum
                                            [VALUE] => Сталь
                                        )

                                )

                            [Назначение ] => Array
                                (
                                    [0] => Array
                                        (
                                            [TAG] => TYPE1
                                            [TYPE] => enum
                                            [VALUE] => Столб фонарный
                                        )

                                )

                            [Форма] => Array
                                (
                                    [0] => Array
                                        (
                                            [TAG] => 
                                            [TYPE] => enum
                                            [VALUE] => Круглая
                                        )

                                )

                            [Число фонарей] => Array
                                (
                                    [0] => Array
                                        (
                                            [TAG] => 
                                            [TYPE] => enum
                                            [VALUE] => Четыре
                                        )

                                )

                        )

                )

            [1] => Array
                (
                    [CODE] => 100157
                    [NAME] => Опора с фонарём
                    [DESCRIPTION] => Стальная квадратная опора с четыремя фонарями ;
                    [RELEVANCE] => 5.3
                    [FIELDS] => Array
                        (
                            [Материал] => Array
                                (
                                    [0] => Array
                                        (
                                            [TAG] => MATERIAL
                                            [TYPE] => enum
                                            [VALUE] => Сталь
                                        )

                                )

                            [Назначение ] => Array
                                (
                                    [0] => Array
                                        (
                                            [TAG] => TYPE1
                                            [TYPE] => enum
                                            [VALUE] => Столб фонарный
                                        )

                                )

                            [Форма] => Array
                                (
                                    [0] => Array
                                        (
                                            [TAG] => 
                                            [TYPE] => enum
                                            [VALUE] => Квадратная
                                        )

                                )

                            [Число фонарей] => Array
                                (
                                    [0] => Array
                                        (
                                            [TAG] => 
                                            [TYPE] => enum
                                            [VALUE] => Четыре
                                        )

                                )

                        )

                )
          ...
        )

    [message] => Operation is successful
    [time] => 11:38:33 12.11.2025
    [timezone] => Etc/GMT-3
    [timestamp] => 1762936713
)
```

**Бизнес-логика:**

1. **Поиск данных:** Вызывает хранимую процедуру `get_codifer` с передачей поисковой фразы
2. **Обработка результатов:**
   * Группирует данные по кодам объектов
   * Формирует структурированный ответ с полями объекта
   * Вычисляет релевантность через метод `calculateRelevance()`
3. **Сортировка:** Сортирует результаты по релевантности через метод `sortByRelevance()`
4. **Ответ:** Возвращает отсортированные данные или ошибку выполнения

**Структура ответа:**

```php

[
    'CODE' => string,        // Код объекта
    'NAME' => string,        // Название объекта
    'DESCRIPTION' => string, // Описание объекта
    'RELEANVANCE' => float,  // Коэффициент релевантности
    'FIELDS' => [           // Поля объекта
        'FIELD_NAME' => [
            [
                'TAG' => string,   // Тег поля
                'TYPE' => string,  // Тип данных
                'VALUE' => mixed   // Значение поля
            ]
        ]
    ]
]
```

***

### Особенности реализации

#### Архитектура данных:

* **Трех уровневая структура:** Объекты → Поля объектов → Значения полей
* **XML-источник:** Внешний XML-файл как источник данных кодификатора
* **Семантический поиск:** Поиск по нечеткому соответствию с расчетом релевантности

#### Безопасность и доступ:

* **Разделение прав:** Root-доступ для загрузки данных, общий доступ для поиска
* **Работа через процедуры:** Использование хранимых процедур для доступа к данным
* **Широкая доступность:** Поиск доступен всем пользователям системы

#### Производительность:

* **Предварительная обработка:** Данные кодификатора загружаются заранее
* **Эффективный поиск:** Использование SQL-процедур для быстрого поиска
* **Клиентская сортировка:** Пост-обработка результатов для релевантности

#### Использование в системе:

* **Интеграция с голосовыми командами:** Поиск по "произносимым фразам"
* **Геодезическая специфика:** Специализированная система кодирования объектов
* **Расширяемость:** Поддержка произвольных полей и атрибутов объектов

### Требования к данным

#### Формат XML-файла:

* Должен содержать структурированные данные об объектах
* Поддерживает иерархию объектов, полей и значений
* Обеспечивает семантическую связь между элементами

#### Структура базы данных:

* **gp\_object** - основные объекты кодификатора
* **gp\_object\_field** - поля и атрибуты объектов
* **gp\_object\_field\_value** - значения полей объектов

## Класс Command

### Общее описание

Класс `Command` является контроллером для управления голосовыми командами в системе. Наследуется от базового класса `Controller` и предоставляет REST API для работы с произносимыми командами, включая их добавление, получение, обновление и удаление. Все методы взаимодействуют с базой данных через хранимые процедуры.

***

### Методы класса

#### 1. Метод `add`

**Назначение:** Добавляет новую произносимую команду в систему. Может использоваться для создания точек по сказанной фразе.

**Параметры запроса:**

* **Обязательные:**
  * `phrase` (string) - произносимая фраза для сопоставления
  * `auth` (string) - токен авторизации пользователя
* **Необязательные:**
  * `active` (bool) - флаг активности команды (по умолчанию `true`)
  * `create` (bool) - флаг создания точки по сказанной фразе (по умолчанию `false`)

**Требуемый уровень доступа:** `ACCESS_ROOT` (только для root-пользователей)

**Используемый HTTP-метод:** `POST`

Пример запроса:

```php
$method = 'POST';
$action = 'command.add';
$data = array(
    'phrase' => 'Testing',
    'active' => false,
    'create' => true
);
$headers = array(
    'AUTH: ' . USER_TOKEN
);
```

Ответ:

```php
HTTP код: 200
Ответ сервера:
Array
(
    [result] => 5
    [message] => Команда добавлена
    [time] => 11:50:09 12.11.2025
    [timezone] => Etc/GMT-3
    [timestamp] => 1762937409
)
```

**Бизнес-логика:**

* Вызывает хранимую процедуру `add_command` с передачей параметров активности, фразы и флага создания
* Обрабатывает результат через родительский метод `procedureResponce`

***

#### 2. Метод `get`

**Назначение:** Получает данные о сказанных фразах в рамках конкретного проекта.

**Параметры запроса:**

* **Обязательные:**
  * `project` (int) - идентификатор проекта
  * `auth` (string) - токен авторизации пользователя

**Требуемый уровень доступа:** `ACCESS_AUTH` (для авторизованных пользователей)

**Используемый HTTP-метод:** `GET`

Пример запроса:

```php
$method = 'GET';
$action = 'command.get';
$data = array(
    'project' => 3
);
$headers = array(
    'AUTH: ' . USER_TOKEN
);
```

Ответ:

```php
HTTP код: 200
Ответ сервера:
Array
(
    [result] => Array
        (
            [0] => Array
                (
                    [USER_ID] => 1
                    [PROJECT_ID] => 3
                    [COMMAND_ID] => 4
                    [PHRASE] => test
                    [TIMESTAMP] => 2025-10-31 09:43:42
                    [MAC] => 
                    [DEVICE] => 
                    [GNSS_MESSAGE] => 
                )

            [1] => Array
                (
                    [USER_ID] => 1
                    [PROJECT_ID] => 3
                    [COMMAND_ID] => 5
                    [PHRASE] => Testing
                    [TIMESTAMP] => 2025-11-12 12:50:00
                    [MAC] => 
                    [DEVICE] => 
                    [GNSS_MESSAGE] => 
                )

        )

    [message] => Operation is successful
    [time] => 12:50:17 12.11.2025
    [timezone] => Etc/GMT-3
    [timestamp] => 1762941017
)
```

**Бизнес-логика:**

* Вызывает хранимую процедуру `get_project_phrase` с передачей идентификатора проекта
* Отправляет результат в формате JSON с кодом ответа `OK`

***

#### 3. Метод `list`

**Назначение:** Получает список всех доступных команд в системе.

**Параметры запроса:**

* **Обязательные:**
  * `auth` (string) - токен авторизации пользователя

**Требуемый уровень доступа:** `ACCESS_AUTH` (для авторизованных пользователей)

**Используемый HTTP-метод:** `GET`

Пример запроса:

```php
$method = 'GET';
$action = 'command.list';
$data = array();
$headers = array(
    'AUTH: ' . USER_TOKEN
);
```

Ответ:

```php
HTTP код: 200
Ответ сервера:
Array
(
    [result] => Array
        (
            [0] => Array
                (
                    [ID] => 4
                    [ACTIVE] => 1
                    [PHRASE] => test2
                    [CREATE_POINT] => 0
                )

            [1] => Array
                (
                    [ID] => 5
                    [ACTIVE] => 0
                    [PHRASE] => Testing
                    [CREATE_POINT] => 1
                )

        )

    [message] => Operation is successful
    [time] => 12:11:25 12.11.2025
    [timezone] => Etc/GMT-3
    [timestamp] => 1762938685
)
```

**Бизнес-логика:**

* Вызывает хранимую процедуру `get_command` без параметров
* Отправляет результат в формате JSON с кодом ответа `OK`

***

#### 4. Метод `tell`

**Назначение:** Добавляет информацию о произнесенной фразе в системе. Может использоваться для создания точек с привязкой к устройству.

**Параметры запроса:**

* **Обязательные:**
  * `project` (int) - идентификатор проекта
  * `phrase` (string) - произнесенная фраза
  * `auth` (string) - токен авторизации пользователя
* **Необязательные:**
  * `mac` (string) - MAC-адрес устройства (обязателен при создании точки)
  * `device` (string) - название устройства (обязателен при создании точки)
  * `gnss` (string) - сообщение от GNSS-приёмника (обязателен при создании точки)

**Требуемый уровень доступа:** `ACCESS_AUTH` (для авторизованных пользователей)

**Используемый HTTP-метод:** `POST`

Пример запроса:

```php
$method = 'POST';
$action = 'command.tell';
$data = array(
    'project' => 3,
    'PHRASE' => 'опора фонарная с четыремя фонарями',
    'MAC' => 'df:57:df:68:8s',
    'DEVICE' => 'fsa',
    'gnss' => '$GNGGA,102522.00,5308.47049009,N,04501.87156702,E,1,11,2.0,160.796,M,4.728,M,,*41',
);
$headers = array(
    'Authorization: ' . AUTH
);
```

Ответ:

```php
HTTP код: 200
Ответ сервера:
Array
(
    [result] => Array
        (
            [0] => Array
                (
                    [ID] => 1
                    [USER_ID] => 1
                    [PROJECT_ID] => 3
                    [PHRASE] => опора фонарная с четыремя фонарями
                    [GNSS_MESSAGE] => $GNGGA,102522.00,5308.47049009,N,04501.87156702,E,1,11,2.0,160.796,M,4.728,M,,*41
                    [ACTIVE] => 1
                    [LATITUDE] => 53.141174834833
                    [LONGITUDE] => 45.031192783667
                    [HEIGHT] => 160.796
                    [X] => 
                    [Y] => 
                    [Z] => 
                    [CODE] => Array
                        (
                            [CODE] => 100156
                            [NAME] => Опора с фонарём
                            [DESCRIPTION] => Стальная круглая опора с четыремя фонарями ;
                            [RELEVANCE] => 5.3
                            [FIELDS] => Array
                                (
                                    [Материал] => Array
                                        (
                                            [0] => Array
                                                (
                                                    [TAG] => MATERIAL
                                                    [TYPE] => enum
                                                    [VALUE] => Сталь
                                                )

                                        )

                                    [Назначение ] => Array
                                        (
                                            [0] => Array
                                                (
                                                    [TAG] => TYPE1
                                                    [TYPE] => enum
                                                    [VALUE] => Столб фонарный
                                                )

                                        )

                                    [Форма] => Array
                                        (
                                            [0] => Array
                                                (
                                                    [TAG] => 
                                                    [TYPE] => enum
                                                    [VALUE] => Круглая
                                                )

                                        )

                                    [Число фонарей] => Array
                                        (
                                            [0] => Array
                                                (
                                                    [TAG] => 
                                                    [TYPE] => enum
                                                    [VALUE] => Четыре
                                                )

                                        )

                                )

                        )

                    [REFERENCE_ID] => 
                    [TIMESTAMP] => 2025-12-09 16:21:32
                    [UPDATED] => 2025-12-09 16:21:33
                )

        )

    [message] => По сказанной фразе создана точка
    [time] => 16:21:24 09.12.2025
    [timezone] => Etc/GMT-3
    [timestamp] => 1765286484
)
```

**Бизнес-логика:**

* Вызывает хранимую процедуру `add_phrase` с передачей параметров проекта, фразы и данных устройства
* Обрабатывает результат через родительский метод `procedureResponce`

***

#### 5. Метод `update`

**Назначение:** Обновляет данные существующей команды в таблице `gp_command`.

**Параметры запроса:**

* **Обязательные:**
  * `id` (int) - идентификатор команды
  * `phrase` (string) - фраза сопоставления команды
  * `create` (bool) - флаг создания точки по команде (0 или 1)
  * `auth` (string) - токен авторизации пользователя

**Требуемый уровень доступа:** `ACCESS_ROOT` (только для root-пользователей)

**Используемый HTTP-метод:** `PUT`

Пример запроса:

```php
$method = 'PUT';
$action = 'command.update';
$data = array(
    'id' => 5,
    'active' => true,
    'create' => true,
    'phrase' => 'Testing'
);
$headers = array(
    'AUTH: ' . USER_TOKEN
);
```

Ответ:

```php
HTTP код: 200
Ответ сервера:
Array
(
    [result] => 1
    [message] => Operation is successful
    [time] => 12:45:14 12.11.2025
    [timezone] => Etc/GMT-3
    [timestamp] => 1762940714
)
```

**Бизнес-логика:**

* Вызывает хранимую процедуру `update_command` с передачей идентификатора, фразы и флага создания
* Обрабатывает результат через родительский метод `procedureResponce`

***

#### 6. Метод `delete`

**Назначение:** Удаляет команду из системы по идентификатору.

**Параметры запроса:**

* **Обязательные:**
  * `id` (int) - идентификатор команды
  * `auth` (string) - токен авторизации пользователя

**Требуемый уровень доступа:** `ACCESS_ROOT` (только для root-пользователей)

**Используемый HTTP-метод:** `DELETE`

Пример запроса:

```php
$method = 'DELETE';
$action = 'command.delete';
$data = array(
    'id' => 5
);
$headers = array(
    'AUTH: ' . USER_TOKEN
);
```

Ответ:

```php
HTTP код: 200
Ответ сервера:
Array
(
    [result] => 1
    [message] => Команда перемещена в корзину
    [time] => 12:51:27 12.11.2025
    [timezone] => Etc/GMT-3
    [timestamp] => 1762941087
)
```

**Бизнес-логика:**

* Вызывает хранимую процедуру `delete_command` с передачей идентификатора команды
* Обрабатывает результат через родительский метод `procedureResponce`

***

### Особенности реализации

* Все методы используют атрибуты для указания уровня доступа и типов параметров
* Работа с базой данных осуществляется через абстракцию `DB->procedure()`
* Для ответов используется либо родительский метод `procedureResponce()`, либо статический метод `Response::send()`
* Класс следует принципам RESTful API с рекомендациями по HTTP-методам
* Обязательная аутентификация через параметр `auth` для всех методов  

## Класс Company

### Общее описание

Класс `Company` является финальным (`final`) контроллером для управления компаниями в системе. Наследуется от базового класса `Controller` и предоставляет REST API для работы с пользовательскими компаниями, включая их создание, получение данных, обновление и удаление. Все методы взаимодействуют с базой данных через хранимые процедуры.

***

### Методы класса

#### 1. Метод `add`

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

**Параметры запроса:**

* **Обязательные:**
  * `name` (string) - название компании
  * `director` (int) - идентификатор директора компании
  * `district` (string) - название региона, где располагается компания
  * `auth` (string) - токен авторизации пользователя

**Требуемый уровень доступа:** `ACCESS_ALL` (доступно всем пользователям)

**Используемый HTTP-метод:** `POST`

Пример запроса:

```php
$method = 'POST';
$action = 'company.add';
$data = array(
    'name' => 'TestingTest',
    'director' => 5,
    'district' => ''
);
$headers = array();
```

Ответ:

```php
HTTP код: 200
Ответ сервера:
Array
(
    [result] => 3
    [message] => Компания добавлена
    [time] => 11:07:21 12.11.2025
    [timezone] => Etc/GMT-3
    [timestamp] => 1762934841
)
```

**Бизнес-логика:**

* Вызывает хранимую процедуру `add_company` с передачей параметров названия, идентификатора директора и региона
* Обрабатывает результат через родительский метод `procedureResponce`
* Возвращает результат операции создания компании

***

#### 2. Метод `get`

**Назначение:** Получает данные о компании текущего авторизованного пользователя.

**Параметры запроса:**

* **Обязательные:**
  * `auth` (string) - токен авторизации пользователя

**Требуемый уровень доступа:** `ACCESS_AUTH` (для авторизованных пользователей)

**Используемый HTTP-метод:** `GET`

Пример запроса:

```php
$method = 'GET';
$action = 'company.get';
$data = array();
$headers = array(
    'AUTH: ' . USER_TOKEN
);
```

Ответ:

```php
HTTP код: 200
Ответ сервера:
Array
(
    [result] => Array
        (
            [0] => Array
                (
                    [ID] => 3
                    [NAME] => TestingTest
                    [DIRECTOR_ID] => 5
                    [DISTRICT] => 
                    [ACTIVE] => 1
                )

        )

    [message] => Operation is successful
    [time] => 11:30:58 12.11.2025
    [timezone] => Etc/GMT-3
    [timestamp] => 1762936258
)
```

**Бизнес-логика:**

* Вызывает хранимую процедуру `get_company` без параметров (вероятно, использует контекст авторизации)
* Отправляет результат в формате JSON с кодом ответа `OK`
* Возвращает данные о компании, связанной с текущим пользователем

***

#### 3. Метод `update`

**Назначение:** Обновляет данные существующей компании. Позволяет изменить название компании, назначить нового директора или изменить регион расположения.

**Параметры запроса:**

* **Обязательные:**
  * `name` (string) - название компании
  * `director` (int) - идентификатор директора компании
  * `district` (string) - название региона, где располагается компания
  * `auth` (string) - токен авторизации пользователя

**Требуемый уровень доступа:** `ACCESS_DIRECTOR` (только для директоров компаний)

**Используемый HTTP-метод:** `PATCH`

Пример запроса:

```php
$method = 'PATCH';
$action = 'company.update';
$data = array(
    'district' => 'District'
);
$headers = array(
    'AUTH: ' . USER_TOKEN
);
```

Ответ:

```php
HTTP код: 200
Ответ сервера:
Array
(
    [result] => 1
    [message] => Operation is successful
    [time] => 11:34:19 12.11.2025
    [timezone] => Etc/GMT-3
    [timestamp] => 1762936459
)
```

**Бизнес-логика:**

* **Валидация:** Проверяет, что хотя бы один из параметров для обновления не пустой
* **Ошибка:** Если все параметры пустые, возвращает код ответа `INCORRECT_DATA`
* **Основная логика:** Вызывает хранимую процедуру `update_company` с передачей обновленных данных
* **Обработка результата:** Использует родительский метод `procedureResponce` для формирования ответа

**Примечание:** В текущей реализации есть ошибка - параметры запроса извлекаются с пустыми ключами (`self::$data->request['']`), что требует исправления.

***

#### 4. Метод `delete`

**Назначение:** Полностью удаляет компанию и все связанные с ней данные из системы.

**Параметры запроса:**

* **Обязательные:**
  * `auth` (string) - токен авторизации пользователя

**Требуемый уровень доступа:** `ACCESS_DIRECTOR` (только для директоров компаний)

**Используемый HTTP-метод:** `DELETE`

Пример запроса:

```php
$method = 'DELETE';
$action = 'company.delete';
$data = array();
$headers = array(
    'AUTH: ' . USER_TOKEN
);
```

Ответ:

```php
HTTP код: 200
Ответ сервера:
Array
(
    [result] => 1
    [message] => Компания успешно удалена
    [time] => 11:35:24 12.11.2025
    [timezone] => Etc/GMT-3
    [timestamp] => 1762936524
)
```

**Бизнес-логика:**

* **Определение компании:** Использует родительский метод `userCompany()` для получения идентификатора компании текущего пользователя
* **Удаление:** Вызывает хранимую процедуру `delete_company` с передачей идентификатора компании
* **Обработка результата:** Использует родительский метод `procedureResponce` для формирования ответа
* **Каскадное удаление:** Удаляет все данные, связанные с компанией

***

### Особенности реализации

* Класс объявлен как `final`, что запрещает его дальнейшее наследование
* Использует систему атрибутов для указания уровня доступа и типов параметров
* Работа с базой данных осуществляется через абстракцию `DB->procedure()`
* Для ответов используется либо родительский метод `procedureResponce()`, либо статический метод `Response::send()`
* Реализована многоуровневая система доступа:
  * `ACCESS_ALL` - для создания компаний
  * `ACCESS_AUTH` - для просмотра данных компании
  * `ACCESS_DIRECTOR` - для управления компанией
* Метод `update` включает базовую валидацию входных данных
* Метод `delete` использует контекст пользователя для определения компании  

## Класс Datum

### Общее описание

Класс `Datum` является контроллером для управления системами координат (датумами) в геодезической системе. Наследуется от базового класса `Controller` и предоставляет REST API для работы с датумами, включая их создание, получение, обновление, удаление и применение в проектах. Особенностью класса является работа с файлами датумов, загружаемыми из внешних источников.

***

### Методы класса

#### 1. Метод `add`

**Назначение:** Добавляет новую систему координат (датум) в систему с загрузкой данных из внешнего файла.

**Параметры запроса:**

* **Обязательные:**
  * `name` (string) - название датума
  * `path` (string) - путь до файла с датумом
  * `auth` (string) - токен авторизации пользователя
* **Необязательные:**
  * `global` (bool) - флаг доступности датума другим компаниям (0 или 1, по умолчанию 0)

**Требуемый уровень доступа:** `ACCESS_ADMIN` (только для администраторов)

**Используемый HTTP-метод:** `POST`

Пример запроса:

```php
```

Ответ:

```php
```

**Бизнес-логика:**

* **Проверка прав:** Для root-пользователей автоматически устанавливает флаг `global = 1`
* **Загрузка файла:**
  * Кодирует пробелы в URL через `str_replace(' ', '%20', $path)`
  * Загружает содержимое файла через `file_get_contents($url)`
  * Проверяет, что файл не пустой, иначе выбрасывает исключение с кодом 400
* **Сохранение:** Вызывает хранимую процедуру `add_datum` с передачей названия, данных файла и флага глобальности
* **Обработка ответа:** Использует стандартную обработку через `parent::procedureResponce()`

**Исключения:**

* `Exception` с кодом 400 при попытке загрузить пустой файл

***

#### 2. Метод `get`

**Назначение:** Получает список доступных систем координат с поддержкой расширенной фильтрации, сортировки и пагинации.

**Параметры запроса:**

* **Обязательные:**
  * `auth` (string) - токен авторизации пользователя
* **Необязательные:**
  * `select` (array) - массив полей выборки данных
  * `filter` (array) - массив полей отбора данных
  * `order` (array) - массив пар ключ-значение для сортировки данных
  * `limit` (int) - число больше 0 для ограничения количества отбираемых данных
  * `start` (int) - смещение для пагинации (извлекается из родительского класса)

**Требуемый уровень доступа:** `ACCESS_AUTH` (для авторизованных пользователей)

**Используемый HTTP-метод:** `GET`

Пример запроса:

```php
```

Ответ:

```php
```

**Бизнес-логика:**

* Вызывает хранимую процедуру `get_datum` для получения всех датумов
* **Нормализация данных:** Приводит ключи и значения фильтров и сортировки к верхнему регистру
* **Пост-обработка:**
  * Применяет фильтрацию через `ArrayManager::filter()`
  * Выполняет сортировку через `ArrayManager::sort()`
  * Реализует пагинацию через `ArrayManager::limit()` с поддержкой `START` и `LIMIT`
* Возвращает обработанные данные в формате JSON

***

#### 3. Метод `change`

**Назначение:** Изменяет систему координат для указанного проекта пользователя.

**Параметры запроса:**

* **Обязательные:**
  * `datum` (int) - идентификатор датума
  * `project` (int) - идентификатор проекта
  * `auth` (string) - токен авторизации пользователя

**Требуемый уровень доступа:** `ACCESS_AUTH` (для авторизованных пользователей)

**Используемый HTTP-метод:** `PATCH`

Пример запроса:

```php
```

Ответ:

```php
```

**Бизнес-логика:**

* Вызывает хранимую процедуру `change_datum` с передачей идентификаторов проекта и датума
* Использует стандартную обработку ответа через `parent::procedureResponce()`
* Позволяет динамически изменять систему координат для существующего проекта

**Примечание:** В коде присутствует опечатка в параметре `PTOJECT` вместо `PROJECT`

***

#### 4. Метод `update`

**Назначение:** Обновляет данные существующей системы координат, включая возможность замены файла датума.

**Параметры запроса:**

* **Обязательные:**
  * `id` (int) - идентификатор датума
  * `name` (string) - название датума
  * `path` (string) - путь до файла с датумом
  * `auth` (string) - токен авторизации пользователя

**Требуемый уровень доступа:** `ACCESS_ADMIN` (только для администраторов)

**Используемый HTTP-метод:** `PUT`

Пример запроса:

```php
```

Ответ:

```php
```

**Бизнес-логика:**

* **Валидация:** Проверяет, что указано хотя бы одно поле для обновления (название или путь)
* **Загрузка файла:**
  * Кодирует пробелы в URL через `str_replace(' ', '%20', $path)`
  * Загружает содержимое файла через `file_get_contents($url)`
  * Проверяет, что файл не пустой, иначе выбрасывает исключение с кодом 400
* **Обновление:** Вызывает хранимую процедуру `update_datum` с передачей идентификатора, названия и данных файла
* **Обработка ответа:** Использует стандартную обработку через `parent::procedureResponce()`

**Исключения:**

* `Exception` с кодом 400 при попытке загрузить пустой файл
* Возвращает `INCORRECT_DATA` если не указаны поля для обновления

***

#### 5. Метод `delete`

**Назначение:** Удаляет систему координат из компании.

**Параметры запроса:**

* **Обязательные:**
  * `id` (int) - идентификатор датума
  * `auth` (string) - токен авторизации пользователя

**Требуемый уровень доступа:** `ACCESS_ADMIN` (только для администраторов)

**Используемый HTTP-метод:** `DELETE`

Пример запроса:

```php
```

Ответ:

```php
```

**Бизнес-логика:**

* Вызывает хранимую процедуру `delete_datum` с передачей идентификатора датума
* Использует стандартную обработку ответа через `parent::procedureResponce()`
* Выполняет удаление системы координат и всех связанных данных

***

### Особенности реализации

#### Работа с файлами:

* **Внешние источники:** Загрузка файлов датумов из URL-адресов
* **Кодирование URL:** Автоматическое преобразование пробелов в `%20`
* **Валидация:** Проверка на пустые файлы с генерацией исключений
* **Хранение:** Вероятно, сохранение содержимого файлов в базе данных

#### Управление доступом:

* **Двухуровневая система:** `ACCESS_AUTH` для базовых операций, `ACCESS_ADMIN` для управления датумами
* **Глобальные датумы:** Специальная логика для root-пользователей с автоматической установкой глобального доступа

#### Обработка данных:

* **Гибкая фильтрация:** Поддержка сложных условий отбора через `ArrayManager`
* **Пагинация:** Реализация ограничения выборки через `START` и `LIMIT` параметры
* **Нормализация:** Автоматическое приведение ключей фильтров и сортировки к верхнему регистру

#### Безопасность:

* Все методы требуют аутентификации
* Разграничение прав между обычными пользователями и администраторами
* Работа через хранимые процедуры обеспечивает контроль доступа на уровне БД  

## Класс Point

### Общее описание

Класс `Point` является контроллером для управления геодезическими точками в проектах. Наследуется от базового класса `Controller` и предоставляет REST API для работы с точками, включая их получение, обновление координат, управление полями и удаление. Класс специализируется на работе с пространственными данными и координатами.

***

### Методы класса

#### 1. Метод `add`

**Назначение:** Метод предназначен для добавления точек в проект, но в настоящее время отключен из-за ограничений базы данных.

**Параметры запроса:**

* **Обязательные:**
  * `auth` (string) - токен авторизации пользователя

**Требуемый уровень доступа:** `ACCESS_ADMIN` (только для администраторов)

**Используемый HTTP-метод:** `POST`

Пример запроса:

```php
---
```

Ответ:

```php
---
```

**Бизнес-логика:**

* Всегда возвращает код ответа `NOT_ALLOWED`
* Отключен из-за ограничений внешних ключей в базе данных
* Требует переработки архитектуры базы данных для активации

***

#### 2. Метод `get`

**Назначение:** Получает данные о точках проекта с применением фильтров. Выполняет сложную обработку структуры данных для нормализации полей.

**Параметры запроса:**

* **Обязательные:**
  * `project` (int) - идентификатор проекта
  * `point` (int) - идентификатор точки
  * `auth` (string) - токен авторизации пользователя

**Требуемый уровень доступа:** `ACCESS_AUTH` (для авторизованных пользователей)

**Используемый HTTP-метод:** `GET`

Пример запроса:

```php
```

Ответ:

```php
```

**Бизнес-логика:**

* Вызывает хранимую процедуру `get_project_point` с передачей идентификаторов проекта и точки
* Выполняет сложную обработку результата:
  * Группирует точки по идентификатору `POINT_ID`
  * Нормализует поля с подчеркиванием в названии (кроме `USER_ID`)
  * Создает иерархическую структуру для полей с префиксами
  * Объединяет обработанные данные в результирующий массив
* Отправляет нормализованные данные в формате JSON

***

#### 3. Метод `field`

**Назначение:** Получает все поля точки (как заполненные, так и пустые) для указанного проекта.

**Параметры запроса:**

* **Обязательные:**
  * `project` (int) - идентификатор проекта
  * `point` (int) - идентификатор точки
  * `auth` (string) - токен авторизации пользователя

**Требуемый уровень доступа:** `ACCESS_AUTH` (для авторизованных пользователей)

**Используемый HTTP-метод:** `GET`

Пример запроса:

```php
```

Ответ:

```php
```

**Бизнес-логика:**

* Получает идентификатор пользователя через родительский метод `userId()`
* Вызывает хранимую процедуру `get_project_point_field` с передачей идентификаторов пользователя, проекта и точки
* Возвращает полный список полей точки

**Примечание:** В текущей реализации есть ошибка - параметры запроса извлекаются с пустыми ключами, что требует исправления.

***

#### 4. Метод `update`

**Назначение:** Обновляет геодезические данные и атрибуты точки в проекте. Поддерживает различные системы координат.

**Параметры запроса:**

* **Обязательные:**
  * `project` (int) - идентификатор проекта
  * `point` (int) - идентификатор точки
  * `auth` (string) - токен авторизации пользователя
* **Необязательные:**
  * `b` (double) - долгота в градусах (значение по умолчанию: 2147483647)
  * `l` (double) - широта в градусах (значение по умолчанию: 2147483647)
  * `h` (double) - высота в метрах (значение по умолчанию: 2147483647)
  * `x` (double) - координата X (восточное направление) в метрах (значение по умолчанию: 2147483647)
  * `y` (double) - координата Y (северное направление) в метрах (значение по умолчанию: 2147483647)
  * `z` (double) - координата Z (высота) в метрах (значение по умолчанию: 2147483647)
  * `code` (string) - код точки по кодификатору (значение по умолчанию: '')
  * `reference` (bool) - флаг опорной точки (значение по умолчанию: 0)

**Требуемый уровень доступа:** `ACCESS_AUTH` (для авторизованных пользователей)

**Используемый HTTP-метод:** `PUT`

Пример запроса:

```php
```

Ответ:

```php
```

**Бизнес-логика:**

* Использует специальное значение `2147483647` для обозначения отсутствующих координатных данных
* Вызывает хранимую процедуру `update_datum` с передачей всех геодезических параметров
* Обрабатывает результат через родительский метод `procedureResponce`

***

#### 5. Метод `edit`

**Назначение:** Предназначен для редактирования пользовательских полей точки проекта. В настоящее время не реализован.

**Параметры запроса:**

* **Обязательные:**
  * `auth` (string) - токен авторизации пользователя
* **Ожидаемые:**
  * `field` (array) - массив пар ключ-значение для обновления полей

**Требуемый уровень доступа:** `ACCESS_AUTH` (для авторизованных пользователей)

**Используемый HTTP-метод:** `PATCH`

Пример запроса:

```php
```

Ответ:

```php
```

**Бизнес-логика:**

* **Требует реализации** - метод в настоящее время пустой
* Предполагается для массового обновления пользовательских полей точки

***

#### 6. Метод `delete`

**Назначение:** Удаляет точку из указанного проекта.

**Параметры запроса:**

* **Обязательные:**
  * `point` (int) - идентификатор точки
  * `project` (int) - идентификатор проекта
  * `auth` (string) - токен авторизации пользователя

**Требуемый уровень доступа:** `ACCESS_ADMIN` (только для администраторов)

**Используемый HTTP-метод:** `DELETE`

Пример запроса:

```php
```

Ответ:

```php
```

**Бизнес-логика:**

* Вызывает хранимую процедуру `delete_point` с передачей идентификаторов проекта и точки
* Обрабатывает результат через родительский метод `procedureResponce`
* Выполняет удаление точки из системы

***

### Особенности реализации

#### Система координат:

* Поддерживает географические координаты (B, L, H) в градусах и метрах
* Поддерживает прямоугольные координаты (X, Y, Z) в метрах
* Использует специальное значение `2147483647` для обозначения "не установлено"

#### Обработка данных:

* Сложная логика нормализации полей в методе `get`
* Использование хранимых процедур для всех операций с БД
* Многоуровневая система доступа:
  * `ACCESS_AUTH` - для просмотра и обновления
  * `ACCESS_ADMIN` - для удаления и создания

#### Проблемы качества кода:

1. **Метод `add` отключен** - требует решения проблемы внешних ключей в БД
2. **Ошибка в методе `field`** - неправильное извлечение параметров запроса
3. **Метод `edit` не реализован** - требует разработки логики обновления полей
4. **Магические числа** - использование `2147483647` требует констант

#### Безопасность:

* Все методы требуют аутентификации
* Разграничение прав доступа между обычными пользователями и администраторами
* Работа через хранимые процедуры обеспечивает дополнительный уровень безопасности  

## Класс Project

### Общее описание

Класс `Project` является контроллером для управления проектами пользователей в системе. Наследуется от базового класса `Controller` и предоставляет REST API для полного жизненного цикла проектов, включая создание, получение, обновление, удаление, а также управление связями пользователей с проектами.

***

### Методы класса

#### 1. Метод `add`

**Назначение:** Создает новый проект для компании пользователя с возможностью указания названия, описания и системы координат (датума).

**Параметры запроса:**

* **Обязательные:**
  * `name` (string) - название проекта
  * `auth` (string) - токен авторизации пользователя
* **Необязательные:**
  * `description` (string) - описание проекта (по умолчанию: '')
  * `datum` (int) - идентификатор датума (системы координат) (по умолчанию: 0)

**Требуемый уровень доступа:** `ACCESS_ADMIN` (только для администраторов)

**Используемый HTTP-метод:** `POST`

Пример запроса:

```php
$method = 'POST';
$action = 'project.add';
$data = array(
    'name' => 'test',
    'description' => 'test project'
);
$headers = array(
    'AUTH: ' . USER_TOKEN
);
```

Ответ:

```php
HTTP код: 200
Ответ сервера:
Array
(
    [result] => 4
    [message] => Проект создан
    [time] => 12:23:17 12.11.2025
    [timezone] => Etc/GMT-3
    [timestamp] => 1762939397
)
```

**Бизнес-логика:**

* Автоматически определяет компанию пользователя через `parent::userCompany()`
* Вызывает хранимую процедуру `add_project` с передачей названия, описания, датума и компании
* **Расширенная обработка ответа:**
  * При успешном создании (`RESULT > 0`) возвращает код 200 с идентификатором проекта
  * При ошибке возвращает соответствующие коды состояния (424, 520) с сообщениями об ошибках
  * Обрабатывает случаи частичного успеха и полного отказа

***

#### 2. Метод `get`

**Назначение:** Получает список проектов с поддержкой расширенной фильтрации, сортировки и пагинации на стороне сервера.

**Параметры запроса:**

* **Обязательные:**
  * `auth` (string) - токен авторизации пользователя
* **Необязательные:**
  * `select` (array) - массив полей выборки данных
  * `filter` (array) - массив полей отбора данных
  * `order` (array) - массив пар ключ-значение для сортировки данных
  * `limit` (int) - число больше 0 для ограничения количества отбираемых данных
  * `start` (int) - смещение для пагинации (извлекается из родительского класса)

**Требуемый уровень доступа:** `ACCESS_AUTH` (для авторизованных пользователей)

**Используемый HTTP-метод:** `GET`

Пример запроса:

```php
$method = 'GET';
$action = 'project.get';
$data = array();
$headers = array(
    'AUTH: ' . USER_TOKEN
);
```

Ответ:

```php
HTTP код: 200
Ответ сервера:
Array
(
    [result] => Array
        (
            [0] => Array
                (
                    [ID] => 3
                    [ACTIVE] => 1
                    [NAME] => test
                    [DESCRIPTION] => test_description
                    [COMPANY_ID] => 2
                    [DATUM_ID] => 
                )

            [1] => Array
                (
                    [ID] => 4
                    [ACTIVE] => 1
                    [NAME] => test
                    [DESCRIPTION] => test project
                    [COMPANY_ID] => 2
                    [DATUM_ID] => 
                )

        )

    [message] => Operation is successful
    [time] => 12:23:54 12.11.2025
    [timezone] => Etc/GMT-3
    [timestamp] => 1762939434
)
```

**Бизнес-логика:**

* Вызывает хранимую процедуру `get_project` для получения всех проектов
* **Нормализация данных:** Приводит ключи и значения фильтров и сортировки к верхнему регистру
* **Пост-обработка:**
  * Применяет фильтрацию через `ArrayManager::filter()`
  * Выполняет сортировку через `ArrayManager::sort()`
  * Реализует пагинацию через `ArrayManager::limit()` с поддержкой `START` и `LIMIT`
* Возвращает обработанные данные в формате JSON

***

#### 3. Метод `update`

**Назначение:** Обновляет основные атрибуты существующего проекта (название и описание).

**Параметры запроса:**

* **Обязательные:**
  * `id` (int) - идентификатор проекта
  * `auth` (string) - токен авторизации пользователя
* **Необязательные:**
  * `name` (string) - новое название проекта
  * `description` (string) - новое описание проекта

**Требуемый уровень доступа:** `ACCESS_ADMIN` (только для администраторов)

**Используемый HTTP-метод:** `PATCH`

Пример запроса:

```php
$method = 'PATCH';
$action = 'project.update';
$data = array(
    'id' => 4,
    'description' => 'name'
);
$headers = array(
    'AUTH: ' . USER_TOKEN
);
```

Ответ:

```php
HTTP код: 200
Ответ сервера:
Array
(
    [result] => 1
    [message] => Operation is successful
    [time] => 12:24:58 12.11.2025
    [timezone] => Etc/GMT-3
    [timestamp] => 1762939498
)
```

**Бизнес-логика:**

* Вызывает хранимую процедуру `update_project` с передачей идентификатора проекта и обновляемых полей
* Использует стандартную обработку ответа через `parent::procedureResponce()`
* Поддерживает частичное обновление - можно обновлять только название или только описание

***

#### 4. Метод `delete`

**Назначение:** Полностью удаляет проект и все связанные с ним данные из системы.

**Параметры запроса:**

* **Обязательные:**
  * `id` (int) - идентификатор проекта
  * `auth` (string) - токен авторизации пользователя

**Требуемый уровень доступа:** `ACCESS_ADMIN` (только для администраторов)

**Используемый HTTP-метод:** `DELETE`

Пример запроса:

```php
$method = 'DELETE';
$action = 'project.delete';
$data = array(
    'id' => 4
);
$headers = array(
    'AUTH: ' . USER_TOKEN
);
```

Ответы:

```php
HTTP код: 200
Ответ сервера:
Array
(
    [result] => 1
    [message] => Проект перемещён в корзину
    [time] => 12:25:33 12.11.2025
    [timezone] => Etc/GMT-3
    [timestamp] => 1762939533
)
```

```php
HTTP код: 200
Ответ сервера:
Array
(
    [result] => 1
    [message] => Проект удален безвозвратно
    [time] => 12:26:06 12.11.2025
    [timezone] => Etc/GMT-3
    [timestamp] => 1762939566
)
```

**Бизнес-логика:**

* Вызывает хранимую процедуру `delete_project` с передачей идентификатора проекта
* Использует стандартную обработку ответа через `parent::procedureResponce()`
* Выполняет каскадное удаление всех связанных данных проекта

***

#### 5. Метод `relation.add`

**Назначение:** Создает связь между пользователем и проектом, предоставляя пользователю доступ к проекту.

**Параметры запроса:**

* **Обязательные:**
  * `project` (int) - идентификатор проекта
  * `user` (int) - идентификатор пользователя
  * `auth` (string) - токен авторизации пользователя

**Требуемый уровень доступа:** `ACCESS_AUTH` (для авторизованных пользователей)

**Используемый HTTP-метод:** `POST`

Пример запроса:

```php
$method = 'POST';
$action = 'project.relation.add';
$data = array(
    'project' => 3,
    'user' => 4
);
$headers = array(
    'AUTH: ' . USER_TOKEN
);
```

Ответ:

```php
HTTP код: 200
Ответ сервера:
Array
(
    [result] => 4
    [message] => Пользователь добавлен в проект
    [time] => 12:28:35 12.11.2025
    [timezone] => Etc/GMT-3
    [timestamp] => 1762939715
)
```

**Бизнес-логика:**

* Вызывает хранимую процедуру `add_project_relation` с передачей идентификаторов пользователя и проекта
* **Расширенная обработка ответа:** Аналогична методу `add`
  * При успехе возвращает код 200 с результатом операции
  * При ошибке возвращает коды 424 или 520 с соответствующими сообщениями
  * Обрабатывает различные сценарии успеха и неудачи

***

#### 6. Метод `relation.delete`

**Назначение:** Удаляет связь между пользователем и проектом, отзывая доступ пользователя к проекту.

**Параметры запроса:**

* **Обязательные:**
  * `project` (int) - идентификатор проекта
  * `user` (int) - идентификатор пользователя
  * `auth` (string) - токен авторизации пользователя

**Требуемый уровень доступа:** `ACCESS_AUTH` (для авторизованных пользователей)

**Используемый HTTP-метод:** `DELETE`

Пример запроса:

```php
$method = 'DELETE';
$action = 'project.relation.delete';
$data = array(
    'project' => 3,
    'user' => 4
);
$headers = array(
    'AUTH: ' . USER_TOKEN
);
```

Ответ:

```php
HTTP код: 200
Ответ сервера:
Array
(
    [result] => 1
    [message] => Пользователь исключен из проекта
    [time] => 12:38:17 12.11.2025
    [timezone] => Etc/GMT-3
    [timestamp] => 1762940297
)
```

**Бизнес-логика:**

* Вызывает хранимую процедуру `delete_project_relation` с передачей идентификаторов пользователя и проекта
* **Расширенная обработка ответа:** Аналогична методам `add` и `relationAdd`
  * Детальная обработка различных кодов возврата и сообщений
  * Четкое разделение сценариев успеха и ошибок

***

### Особенности реализации

#### Управление доступом:

* **Двухуровневая система:** `ACCESS_AUTH` для основных операций, `ACCESS_ADMIN` для управления проектами
* **Контекст компании:** Автоматическое определение компании пользователя при создании проектов

#### Обработка данных:

* **Гибкая фильтрация:** Поддержка сложных условий отбора через `ArrayManager`
* **Пагинация:** Реализация ограничения выборки через `START` и `LIMIT` параметры
* **Нормализация:** Автоматическое приведение ключей фильтров и сортировки к верхнему регистру

#### Обработка ответов:

* **Два подхода:** Стандартная обработка через `procedureResponce()` и расширенная ручная обработка
* **Детальные ошибки:** Различные коды состояния для разных типов ошибок (424, 520)
* **Информативные сообщения:** Возврат человеко-читаемых сообщений об ошибках

#### Безопасность:

* Все методы требуют аутентификации
* Разграничение прав между обычными пользователями и администраторами
* Работа через хранимые процедуры обеспечивает контроль доступа на уровне БД  

## Класс Reference

### Общее описание

Класс `Reference` является контроллером для управления опорными геодезическими пунктами в системе. Наследуется от базового класса `Controller` и предоставляет базовый REST API для работы с опорными пунктами - фундаментальными точками в геодезических сетях, используемыми как основа для геодезических измерений.

***

### Методы класса

#### 1. Метод `add`

**Назначение:** Предназначен для добавления новых опорных пунктов в систему. В текущей реализации метод не содержит функциональности и требует разработки.

**Параметры запроса:**

* **Обязательные:**
  * `auth` (string) - токен авторизации пользователя

**Требуемый уровень доступа:** `ACCESS_ROOT` (только для root-пользователей)

**Используемый HTTP-метод:** `POST`

Пример запроса:

```php
```

Ответ:

```php
```

**Бизнес-логика:**

* **Требует реализации** - метод в настоящее время пустой
* Предполагается для создания новых опорных геодезических пунктов
* Вероятно, должен включать параметры координат, высоты, типа пункта и других атрибутов

**Не реализован**

***

#### 2. Метод `get`

**Назначение:** Получает список всех опорных пунктов, доступных в системе.

**Параметры запроса:**

* **Обязательные:**
  * `auth` (string) - токен авторизации пользователя

**Требуемый уровень доступа:** `ACCESS_AUTH` (для авторизованных пользователей)

**Используемый HTTP-метод:** `GET`

Пример запроса:

```php
```

Ответ:

```php
```

**Бизнес-логика:**

* Вызывает хранимую процедуру `get_reference` без параметров
* Возвращает полный список опорных пунктов в формате JSON
* Использует код ответа 200 (вместо константы OK)

**Особенности:**

* Предоставляет доступ ко всем опорным пунктам без фильтрации
* Не поддерживает пагинацию, фильтрацию или сортировку
* Возвращает raw-данные из процедуры без дополнительной обработки

***

#### 3. Метод `update`

**Назначение:** Предназначен для обновления данных существующих опорных пунктов. В текущей реализации метод не содержит функциональности и требует разработки.

**Параметры запроса:**

* **Обязательные:**
  * `auth` (string) - токен авторизации пользователя

**Требуемый уровень доступа:** `ACCESS_ROOT` (только для root-пользователей)

**Используемый HTTP-метод:** `PATCH`

Пример запроса:

```php
```

Ответ:

```php
```

**Бизнес-логика:**

* **Требует реализации** - метод в настоящее время пустой
* Предполагается для изменения координат, атрибутов или статуса опорных пунктов
* Вероятно, должен принимать идентификатор пункта и обновляемые поля

**Не реализован**

***

#### 4. Метод `delete`

**Назначение:** Удаляет опорный пункт из системы по идентификатору.

**Параметры запроса:**

* **Обязательные:**
  * `id` (int) - идентификатор опорной точки
  * `auth` (string) - токен авторизации пользователя

**Требуемый уровень доступа:** `ACCESS_ROOT` (только для root-пользователей)

**Используемый HTTP-метод:** `DELETE`

Пример запроса:

```php
```

Ответ:

```php
```

**Бизнес-логика:**

* **Получение контекста:** Определяет идентификатор текущего пользователя через `parent::userId()`
* **Извлечение параметра:** Получает идентификатор опорного пункта из запроса
* **Удаление:** Вызывает хранимую процедуру `delete_point_reference` с передачей идентификаторов пользователя и пункта
* **Обработка ответа:** Использует стандартную обработку через `parent::procedureResponce()`

**Особенности:**

* Передает идентификатор пользователя в процедуру удаления для контроля доступа
* Использует специализированную процедуру `delete_point_reference` (а не общую `delete_reference`)
* Обеспечивает проверку прав доступа перед выполнением удаления

***

### Особенности реализации

#### Управление доступом:

* **Строгая иерархия:**
  * `ACCESS_ROOT` - для создания, обновления и удаления (только root-пользователи)
  * `ACCESS_AUTH` - для просмотра (все авторизованные пользователи)
* **Контекст пользователя:** При удалении передается идентификатор пользователя для аудита и контроля прав

#### Состояние разработки:

* **Частичная реализация:** Только 2 из 4 методов реализованы
* **Базовый функционал:** Реализованы только получение списка и удаление
* **Критический функционал отсутствует:** Нет методов для создания и обновления опорных пунктов

#### Архитектура данных:

* **Работа через процедуры:** Все операции выполняются через хранимые процедуры БД
* **Специализированные процедуры:** Используются процедуры, специфичные для опорных пунктов
* **Минимальная обработка:** Отсутствует сложная бизнес-логика на уровне PHP

#### Безопасность:

* **Обязательная аутентификация:** Все методы требуют токен авторизации
* **Разделение прав:** Четкое разделение между операциями чтения и записи
* **Контроль доступа:** При удалении проверяются права пользователя

### Рекомендации по доработке

#### Необходимые улучшения:

1. **Реализовать метод `add`:**
   * Добавить параметры для координат (B, L, H, X, Y, Z)
   * Включить атрибуты типа пункта, класса точности, даты установки
   * Реализовать валидацию входных данных
2. **Реализовать метод `update`:**
   * Поддержка частичного обновления атрибутов
   * Валидация обновляемых полей
   * Контроль версий или аудит изменений
3. **Улучшить метод `get`:**
   * Добавить поддержку фильтрации, сортировки и пагинации
   * Включить параметры для выборки определенных атрибутов
   * Реализовать поиск по географическим критериям
4. **Стандартизировать коды ответов:**
   * Заменить числовой код 200 на константу OK
   * Добавить обработку различных сценариев ошибок

#### Вопросы проектирования:

* Определить полный набор атрибутов опорных пунктов
* Рассмотреть возможность пространственных запросов (ближайшие пункты, в bounding box)
* Реализовать историю изменений опорных пунктов
* Добавить поддержку различных систем координат

## Класс User

### Общее описание

Класс `User` является финальным (`final`) контроллером для управления пользователями в системе. Наследуется от базового класса `Controller` и предоставляет полный REST API для работы с пользователями, включая регистрацию, аутентификацию, управление профилями, правами доступа и безопасностью. Класс реализует сложную логику работы с персональными данными, включая их шифрование и валидацию.

***

### Методы класса

#### 1. Метод `add`

**Назначение:** Регистрирует нового пользователя в системе. Поддерживает два сценария: самостоятельная регистрация и приглашение в компанию.

**Параметры запроса:**

* **Обязательные при самостоятельной регистрации:**
  * `login` (string) - логин нового пользователя
  * `password` (string) - пароль нового пользователя
* **Обязательные для идентификации:**
  * `phone` (string) ИЛИ `email` (string) - хотя бы один должен быть указан
* **Необязательные:**
  * `company` (int) - компания, к которой относится новый пользователь
  * `phrase` (string) - фраза восстановления доступа
  * `auth` (string) - токен авторизации (обязателен при приглашении в компанию)

**Требуемый уровень доступа:** `ACCESS_ALL` (доступно всем, включая неавторизованных)

**Используемый HTTP-метод:** `POST`

Примеры запроса:

```php
$method = 'POST';
$action = 'user.add';
$data = array(
    'login' => 'TestingTest',
    'password' => 'Testing-1234',
    'email' => 'testingTest@mail.ru',
    'phrase' => 'Testing-1234'
);
$headers = array();
```

```php
HTTP код: 200
Ответ сервера:
Array
(
    [result] => 5
    [message] => Для продолжения регистрации необходимо зарегистрировать компанию
    [time] => 11:04:53 12.11.2025
    [timezone] => Etc/GMT-3
    [timestamp] => 1762934693
)
```

```php
$method = 'POST';
$action = 'user.add';
$data = array(
    'phone' => '+79999999999',
    'company' => 2
);
$headers = array(
    'AUTH: ' . USER_TOKEN
);
```

```php
HTTP код: 200
Ответ сервера:
Array
(
    [result] => 4
    [message] => Добавленный сотрудник должен пройти регистрацию втечение суток
    [time] => 14:37:20 11.11.2025
    [timezone] => Etc/GMT-3
    [timestamp] => 1762861040
)
```

```php
$method = 'POST';
$action = 'user.add';
$data = array(
    'phone' => '+79999999999',
    'login' => 'Testing',
    'password' => 'Esting-1234'
);
$headers = array();
```

```php
HTTP код: 200
Ответ сервера:
Array
(
    [error] => 
    [message] => Необходимо подтверждение профиля
    [time] => 14:48:30 11.11.2025
    [timezone] => Etc/GMT-3
    [timestamp] => 1762861710
)
```

**Бизнес-логика:**

* **Валидация:** Проверяет наличие хотя бы одного идентификатора (телефон или email)
* **Сценарии использования:**
  * **Приглашение в компанию:** Проверяет соответствие компании, генерирует пустые логин/пароль
  * **Самостоятельная регистрация:** Требует логин и пароль
* **Безопасность:**
  * Шифрует персональные данные через `Token::encryptUserData()`
  * Хеширует пароль через метод `createPassword()`
* **Сохранение:** Вызывает хранимую процедуру `add_user`

**Исключения:**

* `Exception` с кодом 400 при отсутствии телефона и email

***

#### 2. Метод `verify`

**Назначение:** Активирует профиль пользователя после регистрации или изменения персональных данных через код подтверждения.

**Параметры запроса:**

* **Обязательные:**
  * `id` (int) - идентификатор пользователя в компании
  * `code` (string) - код подтверждения активации профиля

**Требуемый уровень доступа:** `ACCESS_ALL` (доступно всем)

**Используемый HTTP-метод:** `POST`

Пример запроса:

```php
$method = 'POST';
$action = 'user.verify';
$data = array(
    'id' => 4,
    'code' => '391465'
);
$headers = array();
```

Ответ:

```php
HTTP код: 200
Ответ сервера:
Array
(
    [result] => 1
    [message] => OK
    [time] => 14:55:21 11.11.2025
    [timezone] => Etc/GMT-3
    [timestamp] => 1762862121
)
```

**Бизнес-логика:**

* Вызывает хранимую процедуру `user_verify` с передачей идентификатора пользователя и кода подтверждения
* Использует стандартную обработку ответа через `parent::procedureResponce()`

***

#### 3. Метод `code`

**Назначение:** Запрашивает новый код активации для пользователя.

**Параметры запроса:**

* **Обязательные:**
  * `id` (int) - идентификатор пользователя в компании
* **Условно обязательные:**
  * `auth` (string) - токен авторизации (если пользователь был ранее активен)

**Требуемый уровень доступа:** `ACCESS_ALL` (доступно всем)

**Используемый HTTP-метод:** Не указан

Пример запроса:

```php
$method = 'GET';
$action = 'user.code';
$data = array(
    'id' => 4
);
$headers = array();
```

Ответ:

```php
HTTP код: 200
Ответ сервера:
Array
(
    [result] => 1
    [message] => Operation is successful
    [time] => 14:53:53 11.11.2025
    [timezone] => Etc/GMT-3
    [timestamp] => 1762862033
)
```

**Бизнес-логика:**

* Вызывает хранимую процедуру `add_registration_code` с передачей идентификатора пользователя
* Использует стандартную обработку ответа через `parent::procedureResponce()`

***

#### 4. Метод `get`

**Назначение:** Получает список пользователей с поддержкой расширенной фильтрации, сортировки и пагинации.

**Параметры запроса:**

* **Обязательные:**
  * `auth` (string) - токен авторизации пользователя
* **Необязательные:**
  * `select` (array) - массив полей выборки данных
  * `filter` (array) - массив полей отбора данных
  * `order` (array) - массив пар ключ-значение для сортировки данных
  * `limit` (int) - число больше 0 для ограничения количества отбираемых данных

**Требуемый уровень доступа:** `ACCESS_AUTH` (для авторизованных пользователей)

**Используемый HTTP-метод:** `GET`

Пример запроса:

```php
$method = 'GET';
$action = 'user.get';
$data = array(
    'filter' => [
        'ACTIVE' => 0,
    ],
);
$headers = array(
    'AUTH: ' . USER_TOKEN
);
```

Ответ:

```php
HTTP код: 200
Ответ сервера:
Array
(
    [result] => Array
        (
            [1] => Array
                (
                    [ID] => 2
                    [ACTIVE] => 0
                    [ADMIN] => 1
                    [DELETED] => 1
                    [LOGIN] => Testov
                    [COMPANY_ID] => 2
                    [REGISTRATION] => 2025-10-31 08:26:29
                    [TIMESTAMP] => 2025-10-31 07:54:45
                )

        )

    [message] => OK
    [time] => 12:59:08 11.11.2025
    [timezone] => Etc/GMT-3
    [timestamp] => 1762855148
)
```

**Бизнес-логика:**

* Вызывает хранимую процедуру `get_user` для получения всех пользователей
* **Нормализация данных:** Приводит ключи и значения фильтров и сортировки к верхнему регистру
* **Пост-обработка:** Применяет фильтрацию, сортировку и пагинацию через `ArrayManager`
* Возвращает обработанные данные в формате JSON

***

#### 5. Метод `personal`

**Назначение:** Получает зашифрованные персональные данные пользователя (телефон и/или email) с дешифровкой.

**Параметры запроса:**

* **Обязательные:**
  * `id` (int) - идентификатор пользователя в компании
  * `auth` (string) - токен авторизации пользователя
* **Необязательные (хотя бы один должен быть указан):**
  * `phone` (bool) - флаг отображения номера телефона
  * `email` (bool) - флаг отображения адреса электронной почты

**Требуемый уровень доступа:** `ACCESS_ADMIN` (только для администраторов)

**Используемый HTTP-метод:** `GET`

Пример запроса:

```php
$method = 'GET';
$action = 'user.data';
$data = array(
    'id' => 1,
    'phone' => true,
    'email' => true
);
$headers = array(
    'AUTH: ' . USER_TOKEN
);
```

Ответ:

```php
HTTP код: 200
Ответ сервера:
Array
(
    [result] => Array
        (
            [ID] => 1
            [COMPANY_ID] => 2
            [PHONE] => 89696969696
            [EMAIL] => 
        )

    [message] => OK
    [time] => 13:02:57 11.11.2025
    [timezone] => Etc/GMT-3
    [timestamp] => 1762855377
)
```

**Бизнес-логика:**

* **Валидация:** Проверяет, что указан хотя бы один флаг для отображения данных
* **Получение данных:** Вызывает хранимую процедуру `get_user_personal_data`
* **Дешифровка:** Расшифровывает данные через `Token::decryptUserData()`
* **Формирование ответа:** Строит ответ только с запрошенными полями

**Исключения:**

* `Exception` с кодом 400 если не указаны флаги phone и email

***

#### 6. Метод `update`

**Назначение:** Обновляет данные существующего пользователя с поддержкой частичного обновления.

**Параметры запроса:**

* **Обязательные:**
  * `id` (int) - идентификатор пользователя в компании
  * `auth` (string) - токен авторизации пользователя
* **Необязательные (хотя бы один должен быть указан):**
  * `phone` (string) - номер телефона
  * `email` (string) - адрес электронной почты
  * `login` (string) - логин
  * `password` (string) - пароль
  * `phrase` (string) - фраза восстановления доступа

**Требуемый уровень доступа:** `ACCESS_AUTH` (для авторизованных пользователей)

**Используемый HTTP-метод:** `PATCH`

Пример запроса:

```php
$method = 'PATCH';
$action = 'user.update';
$data = array(
    'id' => 1,
    'phrase' => 'Test'
);
$headers = array(
    'AUTH: ' . USER_TOKEN
);
```

Ответ:

```php
HTTP код: 200
Ответ сервера:
Array
(
    [result] => 1
    [message] => OK
    [time] => 13:11:43 11.11.2025
    [timezone] => Etc/GMT-3
    [timestamp] => 1762855903
)
```

**Бизнес-логика:**

* **Валидация:** Проверяет наличие хотя бы одного поля для обновления
* **Безопасность:** Шифрует персональные данные и хеширует пароль
* **Обновление:** Вызывает хранимую процедуру `update_user`

***

#### 7. Метод `admin`

**Назначение:** Устанавливает или снимает права администратора для пользователя.

**Параметры запроса:**

* **Обязательные:**
  * `id` (int) - идентификатор пользователя в компании
  * `admin` (bool) - флаг администратора
  * `auth` (string) - токен авторизации пользователя

**Требуемый уровень доступа:** `ACCESS_ADMIN` (только для администраторов)

**Используемый HTTP-метод:** `PUT`

Пример запроса:

```php
$method = 'PUT';
$action = 'user.admin';
$data = array(
    'id' => 1,
    'admin' => true
);
$headers = array(
    'AUTH: ' . USER_TOKEN
);
```

Ответ:

```php
HTTP код: 200
Ответ сервера:
Array
(
    [result] => 1
    [message] => OK
    [time] => 13:27:07 11.11.2025
    [timezone] => Etc/GMT-3
    [timestamp] => 1762856827
)
```

**Бизнес-логика:**

* Вызывает хранимую процедуру `set_admin` с передачей идентификатора пользователя и флага администратора
* Использует стандартную обработку ответа

***

#### 8. Метод `delete`

**Назначение:** Удаляет пользователя из компании.

**Параметры запроса:**

* **Обязательные:**
  * `id` (int) - идентификатор пользователя в компании
  * `auth` (string) - токен авторизации пользователя

**Требуемый уровень доступа:** `ACCESS_AUTH` (для авторизованных пользователей)

**Используемый HTTP-метод:** `DELETE`

Пример запроса:

```php
$method = 'DELETE';
$action = 'user.delete';
$data = array(
    'id' => 4
);
$headers = array(
    'AUTH: ' . USER_TOKEN
);
```

Ответ:

```php
HTTP код: 200
Ответ сервера:
Array
(
    [result] => 1
    [message] => Operation is successful
    [time] => 17:15:45 11.11.2025
    [timezone] => Etc/GMT-3
    [timestamp] => 1762870545
)
```

**Бизнес-логика:**

* Вызывает хранимую процедуру `delete_user` с передачей идентификатора пользователя
* Использует стандартную обработку ответа

***

#### 9. Метод `login`

**Назначение:** Выполняет аутентификацию пользователя в системе и выдает токен доступа.

**Параметры запроса:**

* **Обязательные:**
  * `login` (string) - логин пользователя
  * `password` (string) - пароль пользователя

**Требуемый уровень доступа:** `ACCESS_ALL` (доступно всем)

**Используемый HTTP-метод:** `POST`

```php
$method = 'POST';
$action = 'user.login';
$data = array(
    'login' => 'TestovTest',
    'password' => 'TestovTest-1234'
);
```

Ответ:

```php
HTTP код: 200
Ответ сервера:
Array
(
    [result] => USER_TOKEN
    [message] => Авторизация подтверждена
    [time] => 11:34:56 11.11.2025
    [timezone] => Etc/GMT-3
    [timestamp] => 1762850096
)
```

**Бизнес-логика:**

* **Поиск пользователя:** Вызывает процедуру `get_user_by_login` для получения данных
* **Проверка пароля:** Использует метод `checkPassword()` для верификации
* **Обновление хеша:** При необходимости обновляет устаревший хеш пароля
* **Генерация токена:** Создает токен авторизации через `Token::createAuth()`
* **Запись сессии:** Сохраняет информацию о входе через процедуру `user_login`
* **Возврат токена:** При успешной аутентификации возвращает токен доступа

***

#### 10. Метод `logout`

**Назначение:** Выполняет выход пользователя из системы с возможностью сброса всех сессий.

**Параметры запроса:**

* **Обязательные:**
  * `auth` (string) - токен авторизации пользователя
* **Необязательные:**
  * `all` (bool) - флаг сброса всех авторизаций

**Требуемый уровень доступа:** `ACCESS_AUTH` (для авторизованных пользователей)

**Используемый HTTP-метод:** `POST`

Пример запроса:

```php
$method = 'POST';
$action = 'user.logout';
$data = array();
$headers = array(
    'AUTH: ' . USER_TOKEN
);
```

Ответ:

```php
HTTP код: 200
Ответ сервера:
Array
(
    [result] => 1
    [message] => Текущая авторизация сброшена
    [time] => 17:16:28 11.11.2025
    [timezone] => Etc/GMT-3
    [timestamp] => 1762870588
)
```

**Бизнес-логика:**

* Вызывает хранимую процедуру `user_logout` с передачей флага сброса всех сессий
* Использует стандартную обработку ответа

***

### Особенности реализации

#### Безопасность данных:

* **Шифрование:** Все персональные данные (телефон, email, фраза восстановления) шифруются
* **Хеширование паролей:** Используется современное хеширование с автоматическим обновлением
* **Валидация паролей:** Требования к сложности паролей

#### Управление доступом:

* **Контекст компании:** Проверка принадлежности пользователя к компании
* **Административные права:** Отдельный метод для управления правами администратора

#### Работа с сессиями:

* **Гибкий выход:** Возможность выхода из текущей или всех сессий
* **Время жизни токенов:** Настраивается через переменную окружения

#### Обработка данных:

* **Гибкие запросы:** Поддержка фильтрации, сортировки и пагинации
* **Частичное обновление:** Возможность обновления отдельных полей пользователя
