Architecture

🏗 Architecture & Integrations

docs/architecture/integrations.md

🔌 Потоки данных (Data Streams / Integrations)

Обзор

Раздел "Потоки данных" (Data Streams / Integrations) — это UI-интерфейс для управления всеми "Щупальцами" SprosOS. Каждый коннектор — это независимый канал сбора сигналов из внешнего источника.

Концепция "Гибридного коннектора"

Реальность: не все API маркетплейсов предоставляют полный доступ к данным без Premium-подписки (пример: отзывы Ozon).

Гибридная модель (Hybrid Connector) — коннектор, использующий комбинацию методов сбора данных:

┌─────────────────────────────────────────────┐
│             Гибридный коннектор              │
│                 (Ozon)                       │
│                                             │
│  ┌─────────────────┐  ┌──────────────────┐  │
│  │ API-канал       │  │ Web-канал         │  │
│  │ (Premium)       │  │ (Без подписки)    │  │
│  │                 │  │                   │  │
│  │ ✅ Каталог      │  │ ⬜ Сбор отзывов   │  │
│  │ ✅ Цены/остатки  │  │     (браузер)    │  │
│  │ ✅ Заказы       │  │ ⬜ Вопросы        │  │
│  │ ⬜ Отзывы *     │  │     (браузер)    │  │
│  └─────────────────┘  └──────────────────┘  │
│                                             │
│         * Требует Premium-подписки           │
│           Fallback: CSV-импорт или парсинг   │
└─────────────────────────────────────────────┘

Уровни доступа

УровеньОписаниеПример
Full APIПолный доступ ко всем данным через APIOzon Premium, WB API
Partial APIAPI доступен, но часть данных заблокированаOzon Base (есть каталог, нет отзывов)
Web ScrapingДанные только через парсинг публичных страницAvito, Telegram
File ImportТолько ручная загрузка CSV/ExcelЛюбой источник как fallback

Стратегия fallback

1. Попытка API (если ключ есть)
2. Если API не даёт отзывы → Web Scraping (браузер)  
3. Если Web Scraping заблокирован → Ручной импорт CSV

Статусы для UI

СтатусЦветОписание
active🟢 ЗелёныйКоннектор работает, данные поступают
error🔴 КрасныйКоннектор сломан (ключ истёк, API недоступен)
partial🟡 ЖёлтыйРаботает частично (напр., каталог есть, отзывов нет)
not_configured⚪ СерыйНе настроен, ключи не введены

Canonical Entity: DataStream

from pydantic import BaseModel
from datetime import datetime
from typing import Optional
from enum import Enum


class ConnectorType(str, Enum):
    api = "api"               # Полноценное API
    web_scraping = "web_scraping"  # Парсинг
    file = "file"             # CSV/Excel импорт
    hybrid = "hybrid"         # Комбинированный


class ConnectorStatus(str, Enum):
    active = "active"
    error = "error"
    partial = "partial"
    not_configured = "not_configured"


class DataStream(BaseModel):
    """Каноническое представление потока данных в системе."""
    id: str
    name: str                          # Человеческое название
    type: ConnectorType                # Тип подключения
    status: ConnectorStatus            # Текущий статус
    value_provided: str                # Что даёт (от пользователя)
    requirements: str                  # Что требует
    last_sync: Optional[datetime]      # Последняя успешная синхронизация
    icon: Optional[str] = None         # Иконка/логотип (URL или emoji)

Приоритизированный список коннекторов

#КоннекторТипСтатусЧто даётТребует
1OzonhybridpartialКаталог (API) + отзывы (Premium/CSV)Client ID, API Key, ЛК доступ
2CSV/Excel Importfilenot_configuredУниверсальный импорт любых таблицФайл в формате CSV/XLSX
3Wildberriesapinot_configuredКаталог, отзывы, ценыAPI-ключ продавца
4Яндекс.Маркетapinot_configuredОтзывы, рейтинги, вопросыAPI-ключ продавца
5Avitoweb_scrapingnot_configuredОбъявления, отзывы, статистикаЛК доступ
6Telegram Botshybridnot_configuredСбор обратной связи, отзывыTelegram Bot Token

Макет UI-страницы (концепт)

┌──────────────────────────────────────────────┐
│  ⚙️ Потоки данных                  [Добавить] │
├──────────────────────────────────────────────┤
│                                              │
│  ┌──────┐  ┌──────┐  ┌──────┐  ┌──────┐    │
│  │Ozon  │  │CSV   │  │WB    │  │Я.Мар.│    │
│  │🟡    │  │⚪    │  │⚪    │  │⚪    │    │
│  │partial│  │not...│  │not...│  │not...│    │
│  │[Настр]│  │[Настр]│  │[Настр]│  │[Настр]│    │
│  └──────┘  └──────┘  └──────┘  └──────┘    │
│                                              │
│  ┌──────┐  ┌──────┐                          │
│  │Avito │  │Tele  │                          │
│  │⚪    │  │gram │                          │
│  │     │  │⚪    │                          │
│  │[Настр]│  │[Настр]│                          │
│  └──────┘  └──────┘                          │
│                                              │
└──────────────────────────────────────────────┘