mirror of
https://github.com/serty2005/rmser.git
synced 2026-02-04 19:02:33 -06:00
240 lines
7.3 KiB
Markdown
240 lines
7.3 KiB
Markdown
# API Documentation: RMSER Backend
|
||
|
||
## 1. Общая информация
|
||
|
||
* **Base URL:** `http://localhost:8080/api`
|
||
* **Формат данных:** JSON.
|
||
* **CORS:** Разрешены запросы с `localhost:5173` (и любых других источников в режиме dev).
|
||
* **Auth:** На данный момент эндпоинты открыты. В будущем предполагается передача токена в заголовке `Authorization: Bearer <token>`.
|
||
|
||
### Обработка ошибок
|
||
В случае ошибки сервер возвращает HTTP код 4xx/5xx и JSON:
|
||
```json
|
||
{
|
||
"error": "Описание ошибки"
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## 2. TypeScript Интерфейсы (Models)
|
||
|
||
Используйте эти интерфейсы для типизации данных на клиенте.
|
||
|
||
```typescript
|
||
// --- Общие типы ---
|
||
|
||
// UUID (строка)
|
||
type UUID = string;
|
||
|
||
// Decimal (деньги/вес приходят строкой, чтобы избежать потери точность в JS)
|
||
type Decimal = string;
|
||
|
||
// --- Каталог и OCR ---
|
||
|
||
// Товар для выпадающего списка (Autosuggest)
|
||
export interface CatalogItem {
|
||
id: UUID;
|
||
name: string;
|
||
code: string; // Артикул или код быстрого набора
|
||
}
|
||
|
||
// Связь "Текст из чека" -> "Товар iiko"
|
||
export interface ProductMatch {
|
||
raw_name: string; // Текст из OCR (ключ)
|
||
product_id: UUID;
|
||
product?: CatalogItem; // Вложенный объект (при чтении)
|
||
updated_at: string; // ISO Date
|
||
}
|
||
|
||
// --- Рекомендации (Аналитика) ---
|
||
|
||
export interface Recommendation {
|
||
ID: UUID;
|
||
Type: string; // Код проблемы (UNUSED_IN_RECIPES, NO_INCOMING, etc.)
|
||
ProductID: UUID;
|
||
ProductName: string;
|
||
Reason: string; // Человекочитаемое описание проблемы
|
||
CreatedAt: string;
|
||
}
|
||
|
||
// --- Накладные ---
|
||
|
||
export interface InvoiceItemRequest {
|
||
product_id: UUID;
|
||
amount: number; // или string, если нужна высокая точность
|
||
price: number;
|
||
}
|
||
|
||
export interface CreateInvoiceRequest {
|
||
document_number: string;
|
||
date_incoming: string; // Format: "YYYY-MM-DD"
|
||
supplier_id: UUID;
|
||
store_id: UUID;
|
||
items: InvoiceItemRequest[];
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## 3. Эндпоинты
|
||
|
||
### 📊 Аналитика (Рекомендации)
|
||
|
||
#### Получить список рекомендаций
|
||
Возвращает список выявленных проблем в учете (товары без техкарт, ингредиенты без закупок и т.д.). Данные обновляются фоновым процессом на бэкенде.
|
||
|
||
* **URL:** `/recommendations`
|
||
* **Method:** `GET`
|
||
* **Response:** `200 OK`
|
||
|
||
```json
|
||
[
|
||
{
|
||
"ID": "uuid...",
|
||
"Type": "UNUSED_IN_RECIPES",
|
||
"ProductID": "uuid...",
|
||
"ProductName": "Петрушка с/м",
|
||
"Reason": "Товар не используется ни в одной техкарте",
|
||
"CreatedAt": "2023-10-27T10:00:00Z"
|
||
}
|
||
]
|
||
```
|
||
|
||
---
|
||
|
||
### 👁 OCR и Обучение (Matching)
|
||
|
||
#### 1. Получить справочник товаров (для селекта)
|
||
Используется для построения локального индекса поиска (autocomplete) на фронтенде, чтобы привязывать позиции. Возвращает только активные товары (`GOODS`).
|
||
|
||
* **URL:** `/ocr/catalog`
|
||
* **Method:** `GET`
|
||
* **Response:** `200 OK`
|
||
|
||
```json
|
||
[
|
||
{
|
||
"id": "607a1e96-f539-45d2-8709-3919f94bdc3e",
|
||
"name": "Молоко Домик в Деревне 3.2%",
|
||
"code": "00123"
|
||
},
|
||
...
|
||
]
|
||
```
|
||
|
||
#### 2. Получить таблицу обучения (Matches)
|
||
Возвращает список уже созданных связей "Грязное название из чека" -> "Чистый товар iiko".
|
||
|
||
* **URL:** `/ocr/matches`
|
||
* **Method:** `GET`
|
||
* **Response:** `200 OK`
|
||
|
||
```json
|
||
[
|
||
{
|
||
"raw_name": "молоко двд 3,2",
|
||
"product_id": "607a1e96-f539-45d2-8709-3919f94bdc3e",
|
||
"product": {
|
||
"ID": "607a1e96-f539-45d2-8709-3919f94bdc3e",
|
||
"Name": "Молоко Домик в Деревне 3.2%",
|
||
...
|
||
},
|
||
"updated_at": "..."
|
||
}
|
||
]
|
||
```
|
||
|
||
#### 3. Создать/Обновить привязку
|
||
Сохраняет правило: "Если в чеке встретишь этот текст, считай это вот этим товаром".
|
||
|
||
* **URL:** `/ocr/match`
|
||
* **Method:** `POST`
|
||
* **Body:**
|
||
|
||
```json
|
||
{
|
||
"raw_name": "молоко двд 3,2",
|
||
"product_id": "607a1e96-f539-45d2-8709-3919f94bdc3e"
|
||
}
|
||
```
|
||
|
||
* **Response:** `200 OK` -> `{"status": "saved"}`
|
||
|
||
---
|
||
|
||
### 📄 Накладные (Invoices)
|
||
|
||
#### Отправить накладную в iikoRMS
|
||
Создает черновик приходной накладной в системе iiko.
|
||
|
||
* **URL:** `/invoices/send`
|
||
* **Method:** `POST`
|
||
* **Body:**
|
||
|
||
```json
|
||
{
|
||
"document_number": "INV-12345",
|
||
"date_incoming": "2023-10-27",
|
||
"supplier_id": "uuid-supplier...",
|
||
"store_id": "uuid-store...",
|
||
"items": [
|
||
{
|
||
"product_id": "uuid-product...",
|
||
"amount": 10.5,
|
||
"price": 150.00
|
||
}
|
||
]
|
||
}
|
||
```
|
||
|
||
* **Response:** `200 OK`
|
||
|
||
```json
|
||
{
|
||
"status": "ok",
|
||
"created_number": "000123" // Номер документа, присвоенный iiko
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
### ⚙️ System
|
||
|
||
#### Healthcheck
|
||
Проверка доступности API.
|
||
|
||
* **URL:** `http://localhost:8080/health`
|
||
* **Method:** `GET`
|
||
* **Response:**
|
||
|
||
```json
|
||
{
|
||
"status": "ok",
|
||
"time": "2023-10-27T12:34:56+03:00"
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## 4. Сценарии использования (Frontend Workflow)
|
||
|
||
### Сценарий А: "Обучение" (раздел Settings / OCR Learning)
|
||
1. При загрузке страницы вызвать `GET /api/ocr/matches` и отобразить таблицу.
|
||
2. Вызвать `GET /api/ocr/catalog` и сохранить в памяти для быстрого поиска (Combobox/Select).
|
||
3. Пользователь может добавить новую связь вручную:
|
||
* Вводит текст (например, "Хлеб Бородинский").
|
||
* Выбирает товар из выпадающего списка.
|
||
* Нажимает "Save" -> вызывается `POST /api/ocr/match`.
|
||
* Таблица обновляется.
|
||
|
||
### Сценарий Б: "Дашборд аналитика"
|
||
1. При загрузке главной страницы вызвать `GET /api/recommendations`.
|
||
2. Сгруппировать массив по полю `Type` или `Reason`.
|
||
3. Отобразить карточки: "Товары без техкарт (5 шт)", "Ингредиенты без закупок (12 шт)".
|
||
|
||
### Сценарий В: "Создание накладной" (Пока ручное)
|
||
*Пока нет загрузки фото через Web, предполагается ручной ввод или редактирование данных, полученных иным путем.*
|
||
1. Форма ввода номера, даты.
|
||
2. Таблица товаров (добавление строк через поиск по каталогу).
|
||
3. Кнопка "Отправить в iiko" -> `POST /api/invoices/send`. |