Files
rmser/API_DOCS.md
2025-12-11 05:20:53 +03:00

6.8 KiB
Raw Blame History

RMSER Backend API Documentation (v2.0)

Дата обновления: Текущая Base URL: http://localhost:8080/api

1. Типы данных (TypeScript Interfaces)

Используйте эти интерфейсы для строгой типизации на клиенте.

// Базовые типы
type UUID = string;

// --- Каталог и Фасовки ---

export interface MeasureUnit {
  id: UUID;
  name: string; // "кг", "л", "шт", "порц"
  code: string;
}

export interface ProductContainer {
  id: UUID;
  name: string; // "Коробка", "Пачка 200г"
  count: number; // Коэффициент пересчета в базовые единицы (напр. 0.2 или 12.0)
}

export interface CatalogItem {
  id: UUID;
  name: string;
  code: string;
  measure_unit: string; // Название базовой единицы (из MainUnit)
  containers: ProductContainer[]; // Доступные фасовки
}

// --- Матчинг (Обучение) ---

export interface MatchRequest {
  raw_name: string;       // Текст из чека
  product_id: UUID;       // ID товара iiko
  quantity: number;       // Количество (по умолчанию 1.0)
  container_id?: UUID;    // Опционально: ID фасовки, если выбрана
}

export interface SavedMatch {
  raw_name: string;
  product: CatalogItem;   // Вложенный объект товара
  quantity: number;       // Сохраненный коэффициент/количество
  container_id?: UUID;
  container?: ProductContainer; // Вложенный объект фасовки (для отображения имени)
  updated_at: string;
}

// --- Нераспознанное ---

export interface UnmatchedItem {
  raw_name: string;
  count: number;          // Сколько раз встречалось в чеках
  last_seen: string;      // ISO Date
}

2. Эндпоинты: OCR и Обучение

GET /ocr/catalog

Получить полный справочник товаров для поиска. Теперь включает единицы измерения и фасовки.

  • Response: 200 OK
[
  {
    "id": "uuid-butter...",
    "name": "Масло сливочное 82%",
    "code": "00123",
    "measure_unit": "кг", 
    "containers": [
      {
        "id": "uuid-pack...",
        "name": "Пачка 180г",
        "count": 0.180
      },
      {
        "id": "uuid-box...",
        "name": "Коробка (20 пачек)",
        "count": 3.6
      }
    ]
  },
  {
    "id": "uuid-milk...",
    "name": "Молоко 3.2%",
    "code": "00124",
    "measure_unit": "л",
    "containers": [] // Пустой массив, если фасовок нет
  }
]

GET /ocr/matches

Получить список уже обученных позиций. Используется для отображения таблицы "Ранее сохраненные связи".

  • Response: 200 OK
[
  {
    "raw_name": "Масло слив. 3 пачки",
    "product_id": "uuid-butter...",
    "product": {
       "id": "uuid-butter...",
       "name": "Масло сливочное 82%",
       "measure_unit": "кг"
       // ...остальные поля product
    },
    "quantity": 3, 
    "container_id": "uuid-pack...",
    "container": {
       "id": "uuid-pack...",
       "name": "Пачка 180г",
       "count": 0.180
    },
    "updated_at": "2023-10-27T10:00:00Z"
  }
]

Логика отображения на фронте: Если container пришел (не null) -> отображаем: Quantity x Container.Name (3 x Пачка 180г). Если container null -> отображаем: Quantity Product.MeasureUnit (0.54 кг).


POST /ocr/match

Создать или обновить привязку.

  • Body:

Вариант 1: Базовая единица (без фасовки) Пользователь выбрал "Петрушка", ввел "0.5" (кг).

{
  "raw_name": "петрушка вес",
  "product_id": "uuid-parsley...",
  "quantity": 0.5
  // container_id не передаем или null
}

Вариант 2: С фасовкой Пользователь выбрал "Масло", выбрал фасовку "Коробка", ввел "2" (штуки).

{
  "raw_name": "масло коробка",
  "product_id": "uuid-butter...",
  "quantity": 2,
  "container_id": "uuid-box..."
}
  • Response: 200 OK -> {"status": "saved"}

GET /ocr/unmatched

Получить список частых нераспознанных товаров. Используется для автодополнения (Suggest) в поле ввода "Текст из чека", чтобы пользователь не вводил название вручную.

  • Response: 200 OK
[
  {
    "raw_name": "Хлеб Бородинский нар.",
    "count": 12,
    "last_seen": "2023-10-27T12:00:00Z"
  },
  {
    "raw_name": "Пакет майка",
    "count": 5,
    "last_seen": "2023-10-26T09:00:00Z"
  }
]

3. Эндпоинты: Накладные (Invoices)

POST /invoices/send

Отправка накладной в iiko.

Важно: При формировании накладной на фронте, вы должны пересчитывать количество в базовые единицы, либо (в будущем) мы научим бэкенд принимать ID фасовки в items. На данный момент API ожидает amount и price уже приведенными к единому знаменателю, либо iiko сама разберется, если мы передадим ContainerID (этот функционал в разработке на стороне rms_client, пока шлите базовые единицы).

{
  "document_number": "INV-100",
  "date_incoming": "2023-10-27",
  "supplier_id": "uuid...",
  "store_id": "uuid...",
  "items": [
    {
      "product_id": "uuid...",
      "amount": 1.5, // 1.5 кг
      "price": 100   // Цена за кг
    }
  ]
}

4. Эндпоинты: Аналитика

GET /recommendations

Возвращает список проблем (товары без техкарт, без закупок и т.д.).

[
  {
    "ID": "uuid...",
    "Type": "UNUSED_IN_RECIPES",
    "ProductID": "uuid...",
    "ProductName": "Лист салата",
    "Reason": "Товар не используется ни в одной техкарте",
    "CreatedAt": "..."
  }
]

5. System

GET /health

Проверка статуса.

{"status": "ok", "time": "..."}