add front spa-app

This commit is contained in:
2025-11-30 06:31:23 +03:00
parent 714844058f
commit 8aced994de
20 changed files with 3358 additions and 1 deletions

240
API_DOCS.md Normal file
View File

@@ -0,0 +1,240 @@
# 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`.