commit c13ebd14ef0d2143d0f1e5265cee07f13dff6dec Author: rocketru Date: Tue Jun 10 15:48:19 2025 +0300 initial commit diff --git a/eurostyle-server-api-requirements.md b/eurostyle-server-api-requirements.md new file mode 100644 index 0000000..7a0829b --- /dev/null +++ b/eurostyle-server-api-requirements.md @@ -0,0 +1,722 @@ +# 📡 API-документация для внешнего поставщика данных + +> Приложение будет обращаться к вашему API, чтобы синхронизировать базу данных. Ниже описано, какие endpoint'ы мы ожидаем, какие данные получать, и какие форматы поддерживать. + +--- + +## 📚 Таблица endpoint'ов + +| Метод | Endpoint | Описание | +|-------|-----------------------------|--------------------------------| +| GET | `/api/v1/brands` | Список брендов | +| GET | `/api/v1/customers` | Список контрагентов (юр лиц компании) | +| GET | `/api/v1/addresses` | Список адресов (обьектов) | +| GET | `/api/v1/masters` | Список мастеров | +| GET | `/api/v1/warehouses` | Список складов | +| GET | `/api/v1/parts` | Номенклатура (расходников) | +| GET | `/api/v1/remainders` | Список Остатков по складам | +| GET | `/api/v1/defects` | Список неисправностей | +| GET | `/api/v1/jobs` | Список услуг | +| GET | `/api/v1/product_instances` | Список оборудования | +| GET | `/api/v1/unit_of_measures` | Список единиц измерения | +| GET | `/api/v1/users` | Список пользователей | +| GET | `/api/v1/repair_orders` | Список заявок на ремонт | +| GET | `/api/v1/repair_orders/1` | Просмотр заявки на ремонт | +| POST | `/api/v1/repair_orders` | Создание заявки на ремонт | +| PUT | `/api/v1/repair_orders` | Изменение заявки на ремонт | + +--- + +## 🔎 Детали по каждому endpoint’у + +### ✅ `GET /api/v1/brands` + +```json +[ + { + "external_key": "brand-001", + "name": "CoolBrand" + } +] +``` + +| Поле | Тип | Обязательно | Описание | +|------|-----|-------------|----------| +| `external_key` | string | ✅ | Уникальный ID бренда | +| `name` | string | ✅ | Название бренда | + +--- + +### ✅ `GET /api/v1/customers` + +```json +[ + { + "external_key": "cust-001", + "name": "ООО Ромашка" + } +] +``` + +| Поле | Тип | Обязательно | Описание | +|------|-----|-------------|----------| +| `external_key` | string | ✅ | Уникальный ID клиента | +| `name` | string | ✅ | Название клиента | + +--- + +### ✅ `GET /api/v1/addresses` + +```json +[ + { + "external_key": "addr-001", + "name": "ул. Техническая, 10", + "brand_key": "brand-001", + "customer_key": "cust-001", + "master_key": "master-001", + "comment": "Пункт обслуживания" + } +] +``` + +| Поле | Тип | Обязательно | Описание | +|------|-----|-------------|----------| +| `external_key` | string | ✅ | ID адреса | +| `name` | string | ✅ | Название или адрес | +| `brand_key` | string | ✅ | Связь с брендом | +| `customer_key` | string | ✅ | Связь с клиентом | +| `master_key` | string | ✅| Прикреплённый мастер | +| `comment` | string | ❌ | Комментарий | + +--- + +### ✅ `GET /api/v1/masters` + +```json +[ + { + "external_key": "master-001", + "name": "Иванов Иван" + } +] +``` + +| Поле | Тип | Обязательно | Описание | +|------|-----|-------------|----------| +| `external_key` | string | ✅ | ID мастера | +| `name` | string | ✅ | Имя мастера | + +--- + +### ✅ `GET /api/v1/warehouses` + +```json +[ + { + "external_key": "wh-001", + "name": "Главный склад", + "master_key": "ms-001" + } +] +``` + +| Поле | Тип | Обязательно | Описание | +|----------------|-----|-------------|-----------------------------| +| `external_key` | string | ✅ | ID склада | +| `name` | string | ✅ | Название склада | +| `master_key` | string | ✅ | Мастер, к которому привязан | + +--- + +### ✅ `GET /api/v1/parts` + +```json +[ + { + "external_key": "part-001", + "name": "Прокладка", + "unit_of_measure_key": "uom-001" + } +] +``` + +| Поле | Тип | Обязательно | Описание | +|------|-----|-------------|----------------------| +| `external_key` | string | ✅ | ID детали | +| `name` | string | ✅ | Название детали | +| `unit_of_measure_key` | string | ✅ | ID Единицы измерения | + +--- + +### ✅ `GET /api/v1/remainders` + +```json +[ + { + "warehouse_key": "wh-001", + "part_key": "part-001", + "quantity": 12.5, + "unit_of_measure_key": "uom-001" + } +] +``` + +| Поле | Тип | Обязательно | Описание | +|------|--------|-------------|----------| +| `warehouse_key` | string | ✅ | ID склада | +| `part_key` | string | ✅ | ID детали | +| `quantity` | number | ✅ | Кол-во в наличии | +| `unit_of_measure_key` | string | ✅ | ID единицы измерения | + +--- + +### ✅ `GET /api/v1/defects` + +```json +[ + { + "external_key": "def-001", + "name": "Протечка" + } +] +``` + +| Поле | Тип | Обязательно | Описание | +|------|-----|-------------|----------| +| `external_key` | string | ✅ | ID дефекта | +| `name` | string | ✅ | Название дефекта | + +--- + +### ✅ `GET /api/v1/jobs` + +```json +[ + { + "external_key": "job-001", + "name": "Замена масла", + "code": "JOB-999" + } +] +``` + +| Поле | Тип | Обязательно | Описание | +|------|-----|-------------|----------| +| `external_key` | string | ✅ | ID работы | +| `name` | string | ✅ | Название | +| `code` | string | ✅ | Внутренний код | + +--- + +### ✅ `GET /api/v1/product_instances` + +```json +[ + { + "external_key": "pi-001", + "address_key": "addr-001", + "name": "Котёл Bosch", + "serial_number": "SN12345", + "inventory_number": "INV98765", + "warranty": true + } +] +``` + +| Поле | Тип | Обязательно | Описание | +|------|-----|-------------|----------| +| `external_key` | string | ✅ | ID устройства | +| `address_key` | string | ✅ | Привязка к адресу | +| `name` | string | ✅ | Название | +| `serial_number` | string | ❌ | Серийный номер | +| `inventory_number` | string | ❌ | Инвентарный номер | +| `warranty` | boolean | ❌ | Есть ли гарантия? | + +--- + +### ✅ `GET /api/v1/unit_of_measures` + +```json +[ + { + "external_key": "uom-001", + "name": "шт" + } +] +``` +--- + +### ✅ `GET /api/v1/users` + +```json +[ + { + "login": "user-001", + "password": "password1", + "role": 1, + "master_key": "master-001", + "customer_key": "cust-001" + } +] +``` + +| Поле | Тип | Обязательно | Описание | +|----------------|--------|-------------|---------------------| +| `login` | string | ✅ | Логин пользователя | +| `password` | string | ✅ | Хэшированный пароль | +| `role` | number | ✅ | Роль | +| `master_key` | string | ❌ | ID мастера | +| `customer_key` | string | ❌ | ID контрагента | + +role - Перечисление (Enum) + +| Значение | Описание | +|----------|----------| +| `0` | Оператор | +| `1` | Клиент | +| `2` | Мастер | + +--- + +### ✅ `GET /api/v1/repair_orders` + +Описание: Ответ содержит массив из хешей содержащих 1С ключ заявок на ремонт + +```json + [ + { + "external_key": "ro-001" + }, + { + "external_key": "ro-002" + }, + { + "external_key": "ro-003" + } + ] +``` +--- + +### ✅ `GET /api/v1/repair_orders/ro-001` + +Просмотр существующей заявки на ремонт. **ro-001** - это ключ 1С заявки на ремонт. + +**Пример успешного ответа, когда заявка на ремонт найдена:** + +```json +{ + "external_key": "ro-001", + "customer_key": "cust-001", + "address_key": "UPDATED-addr-001", + "brand_key": "brand-001", + "master_key": "master-001", + "parts": [ + { + "part_type": 1, + "count": 100, + "part_key": "material-1", + "part_name": "Деталь" + } + ], + "jobs": [ + { + "code": "code-1", + "job_key": "job-1", + "name": "услуга 1", + "count": 1 + } + ], + "product_instances": [ + { + "product_instance_key": "product_instance_key_1", + "name": "оборудование-1", + "serial_number": "123", + "inventory_number": "1", + "warranty": true + } + ], + "files": [ + { + "path": "\\Shared\\file.txt" + } + ], + "contact_person_name": "Петров Петр", + "number_in_client_database": "number_in_client_database_1", + "submission_date": "2025-04-07T08:30:00Z", + "accepted_at": "2025-04-07T09:00:00Z", + "master_arrival_at": "2025-04-07T10:15:00Z", + "fact_execution_date": "2025-04-07T12:45:00Z", + "expected_date": "2025-04-07T13:00:00Z", + "order_type": 0, + "status": 1, + "defect_key": "def-001", + "call_reason": "Капает из фильтра", + "conclusion": "Прокладка изношена" +} +``` + +| Поле | Тип | Обязательно | Описание | +|-----------------------------|----------|-------------|----------------------------------------| +| `external_key` | string | ✅ | Уникальный ID заявки | +| `customer_key` | string | ✅ | Ссылка на контрагента | +| `address_key` | string | ✅ | Ссылка на адрес | +| `brand_key` | string | ✅ | Ссылка на бренд | +| `master_key` | string | ✅ | Мастер | +| `contact_person_name` | string | ❌ | Имя контактного лица | +| `number_in_client_database` | string | ❌ | Номер в базе клиента | +| `submission_date` | datetime | ❌ | Дата поступления заявки | +| `accepted_at` | datetime | ❌ | Мастер принял | +| `master_arrival_at` | datetime | ❌ | Мастер прибыл | +| `fact_execution_date` | datetime | ❌ | Когда работа была фактически завершена | +| `expected_date` | datetime | ❌ | Плановая дата исполнения | +| `order_type` | numeric | ✅ | Тип заявки (enum) | +| `status` | numeric | ✅ | Статус заявки (enum) | +| `defect_key` | string | ❌ | Ссылка на неисправность | +| `call_reason` | text | ❌ | Причина вызова | +| `conclusion` | text | ❌ | Заключение | + +order_type - Перечисление (Enum) + +| Значение | Описание | +|----------|-------------------------| +| `0` | Плановые работы | +| `1` | Техническое обслуживание| +| `2` | Вызов | + + +status - Перечисление (Enum) + +| Значение | Описание | +|----------|-----------| +| `0` | Новая | +| `1` | Плановая | +| `2` | Завершено | +| `3` | Отложено | + + +part_type - Перечисление (Enum) + +| Значение | Описание | +|----------|-------------------------| +| `0` | Затраченый | +| `1` | Требуемый | + +--- + +### ✅ `GET /api/v1/repair_orders/999` + +Просмотр несуществующей заявки на ремонт. + +**Пример ошибки, заявка не найдена:** + +```json +{ + "errors": { + "id": ["не существует"] + } +} +``` + +--- + +### ✅ `POST /api/v1/repair_orders` + +Создание новой заявки на ремонт. + +**Тело запроса:** + +```json +{ + "customer_key": "cust-001", + "address_key": "addr-001", + "brand_key": "brand-001", + "master_key": "master-001", + "contact_person_name": "Петров Петр", + "number_in_client_database": "number_in_client_database_1", + "submission_date": "2025-04-07T08:30:00Z", + "accepted_at": "2025-04-07T09:00:00Z", + "master_arrival_at": "2025-04-07T10:15:00Z", + "fact_execution_date": "2025-04-07T12:45:00Z", + "expected_date": "2025-04-07T13:00:00Z", + "order_type": 0, + "status": 1, + "defect_key": "def-001", + "call_reason": "Капает из фильтра", + "conclusion": "Прокладка изношена", + "product_instances": [ + { + "external_key": "pi-001" + }, + { + "external_key": "pi-002" + } + ], + "parts": [ + { + "external_key": "part-001" + }, + { + "external_key": "part-002" + } + ], + "jobs": [ + { + "external_key": "job-001" + }, + { + "external_key": "job-002" + } + ] +} +``` + +**Пример успешного ответа когда заявка на ремонт успешно создана:** + +```json +{ + "external_key": "ro-001", + "customer_key": "cust-001", + "address_key": "UPDATED-addr-001", + "brand_key": "brand-001", + "master_key": "master-001", + "parts": [ + { + "part_type": 1, + "count": 100, + "part_key": "material-1", + "part_name": "Деталь" + } + ], + "jobs": [ + { + "code": "code-1", + "job_key": "job-1", + "name": "услуга 1", + "count": 1 + } + ], + "product_instances": [ + { + "product_instance_key": "product_instance_key_1", + "name": "оборудование-1", + "serial_number": "123", + "inventory_number": "1", + "warranty": true + "warranty": true + } + ], + "files": [ + { + "path": "\\Shared\\file.txt" + } + ], + "contact_person_name": "Петров Петр", + "number_in_client_database": "number_in_client_database_1", + "submission_date": "2025-04-07T08:30:00Z", + "accepted_at": "2025-04-07T09:00:00Z", + "master_arrival_at": "2025-04-07T10:15:00Z", + "fact_execution_date": "2025-04-07T12:45:00Z", + "expected_date": "2025-04-07T13:00:00Z", + "order_type": 0, + "status": 1, + "defect_key": "def-001", + "call_reason": "Капает из фильтра", + "conclusion": "Прокладка изношена" +} +``` + +Создание новой заявки на ремонт с ошибкой - пустое поле master_key. + +**Тело запроса:** + +```json +{ + "customer_key": "cust-001", + "address_key": "addr-001", + "brand_key": "brand-001", + "master_key": "", + "product_instances": [ + { + "name": "оборудование-1", + "serial_number": "123", + "inventory_number": "1", + "warranty": true + } + ], + "parts": [ + { + "part_type": 1, + "count": 100, + "part_name": "Деталь" + } + ], + "jobs": [ + { + "code": "code-1", + "name": "услуга 1", + "count": 1 + } + ], + "contact_person_name": "Петров Петр", + "number_in_client_database": "number_in_client_database_1", + "submission_date": "2025-04-07T08:30:00Z", + "accepted_at": "2025-04-07T09:00:00Z", + "master_arrival_at": "2025-04-07T10:15:00Z", + "fact_execution_date": "2025-04-07T12:45:00Z", + "expected_date": "2025-04-07T13:00:00Z", + "order_type": 0, + "status": 1, + "defect_key": "def-001", + "call_reason": "Капает из фильтра", + "conclusion": "Прокладка изношена" +} +``` + +**Ответ HTTP код 422:** + +```json +{ + "errors": { + "master_key": ["не может быть пустым"] + } +} +``` + +--- + +### ✅ `PUT /api/v1/repair_orders/rc-001` + +Изменение существующей заявки на ремонт. Где **rc-001** это ключ 1С заявки на ремонт + +**Тело запроса:** + +```json +{ + "customer_key": "cust-001", + "address_key": "UPDATED-addr-001", + "brand_key": "brand-001", + "master_key": "master-001", + "product_instances": [ + { + "name": "оборудование-1", + "serial_number": "123", + "inventory_number": "1", + "warranty": true + } + ], + "parts": [ + { + "part_type": 1, + "count": 100, + "part_name": "Деталь" + } + ], + "jobs": [ + { + "code": "code-1", + "name": "услуга 1", + "count": 1 + } + ], + "contact_person_name": "Петров Петр", + "number_in_client_database": "number_in_client_database_1", + "submission_date": "2025-04-07T08:30:00Z", + "accepted_at": "2025-04-07T09:00:00Z", + "master_arrival_at": "2025-04-07T10:15:00Z", + "fact_execution_date": "2025-04-07T12:45:00Z", + "expected_date": "2025-04-07T13:00:00Z", + "order_type": 0, + "status": 1, + "defect_key": "def-001", + "call_reason": "Капает из фильтра", + "conclusion": "Прокладка изношена" +} +``` + +**Пример успешного ответа когда заявка на ремонт успешно обновлена:** + +```json +{ + "external_key": "ro-001", + "customer_key": "cust-001", + "address_key": "UPDATED-addr-001", + "brand_key": "brand-001", + "master_key": "master-001", + "parts": [ + { + "part_type": 1, + "count": 100, + "part_key": "material-1", + "part_name": "Деталь" + } + ], + "jobs": [ + { + "code": "code-1", + "job_key": "job-1", + "name": "услуга 1", + "count": 1 + } + ], + "product_instances": [ + { + "product_instance_key": "product_instance_key_1", + "name": "оборудование-1", + "serial_number": "123", + "inventory_number": "1", + "warranty": true + } + ], + "files": [ + { + "path": "\\Shared\\file.txt" + } + ], + "contact_person_name": "Петров Петр", + "number_in_client_database": "number_in_client_database_1", + "submission_date": "2025-04-07T08:30:00Z", + "accepted_at": "2025-04-07T09:00:00Z", + "master_arrival_at": "2025-04-07T10:15:00Z", + "fact_execution_date": "2025-04-07T12:45:00Z", + "expected_date": "2025-04-07T13:00:00Z", + "order_type": 0, + "status": 1, + "defect_key": "def-001", + "call_reason": "Капает из фильтра", + "conclusion": "Прокладка изношена" +} +``` + +--- + +## 🔄 Поддержка изменений + +Во всех API справочников , а также в API получения списка заявок +на ремонт в строке адреса возможна передача параметра `?updated_since=`, в ответ на этот запрос будет соджержать данные +изменившиеся только после этой даты: + +```http +GET /api/v1/brands?updated_since=2025-04-01T00:00:00Z +``` + +--- + +## HTTP Коды ошибок + +| Код ошибки | Сообщение | +|------------|--------------------------| +| `400` | Некорректные данные в запросе (например, отсутствуют обязательные поля) | +| `404` | Невозможно найти один из связанных объектов (например, контрагент или адрес) | +| `500` | Внутренняя ошибка сервера | + + +## Общие сведения + +| Часть API | Описание | +|------------------------|-------------------------------------------------------------------------| +| **Формат данных** | JSON | +| **Кодировка** | UTF-8 | +| **Формат даты/времени** | ISO 8601 (`2025-04-09T15:20:00Z`) | +| **Аутентификация** | Bearer Token (передается в заголовке `Authorization`) | +| **Обработка ошибок** | При ошибках возвращается HTTP-статус и JSON-объект с деталями ошибки | \ No newline at end of file