Перейти к содержанию

Chrome-расширение (клиент)

Расширение Chrome позволяет клиенту со страницы товара в магазине (1688, Taobao/Tmall, Poizon и др.) одной кнопкой отправить товар в свой черновик заказа в TaoMaster, с выбором конкретного черновика. Архитектура парсеров площадок — расширяемая.

Архитектура

flowchart LR
    P["Страница товара<br/>(1688 / Taobao / Poizon)"]
    P -->|"content/extract.js<br/>(world: MAIN)"| Pop["Popup расширения<br/>превью + выбор черновика"]
    Pop -->|"Bearer-токен, fetch"| API["/api/ext/* (JSON, CORS)"]
    API --> DB[("orders (draft)<br/>order_items")]
    Cab["Кабинет клиента →<br/>Настройки → Расширение Chrome"] -.генерирует токен.-> Pop
  • Расширение (MV3): popup парсит страницу через chrome.scripting.executeScript (по разрешению activeTab), показывает превью товара и список черновиков, отправляет выбор в API. Поддержанные площадки v1: 1688, Taobao/Tmall, Poizon, DNS (dns-shop.ru) + универсальный парсер.
  • Авторизация — персональный Bearer-токен, который клиент генерирует в кабинете и вставляет в расширение (Sanctum не используется).
  • Бэкенд переиспользует существующий AddOrderItem — товар добавляется в orders со статусом draft.

API расширения

JSON-эндпоинты, группа ext.auth + префикс /api/ext (routes/api.php). Без сессии и CSRF; авторизация — заголовок Authorization: Bearer <токен>.

Метод Маршрут Назначение
GET /api/ext/me Пользователь + его клиентские кабинеты
GET /api/ext/drafts Черновики по всем подтверждённым кабинетам (с именем посредника)
POST /api/ext/drafts Создать черновик в кабинете (client_id)
POST /api/ext/drafts/{order}/items Добавить товар в черновик

Контроллер App\Http\Controllers\Api\ExtensionController. Кабинеты/черновики собираются по всем подтверждённым членствам (CabinetService::cabinets()), заказы — Order::withoutGlobalScopes() с проверкой принадлежности client_id пользователю.

Accept: application/json

Расширение шлёт Accept: application/json — иначе при ошибке валидации Laravel вернёт 302-редирект вместо 422 JSON.

Токены

  • Таблица extension_tokens (user_id, name, token_hash sha256, last_used_at, last_ip). В БД хранится только хэш; сам токен (tao_…) показывается один раз при создании.
  • Модель ExtensionToken::generateFor(User, name)[модель, plaintext].
  • Middleware ext.auth (AuthenticateExtension): находит токен по хэшу, резолвит пользователя, обновляет last_used_at/last_ip.
  • Выдача и отзыв — в кабинете: Настройки → «Расширение Chrome» (Client/SettingsController::createToken/revokeToken).

CORS

config/cors.phppaths: ['api/*'], allowed_origins_patterns: ['#^chrome-extension://#'], supports_credentials: false (токен, не cookie).

Парсеры площадок (расширяемость)

Парсинг инжектируется в страницу (world MAIN):

  • content/extract.js — общие хелперы (window.__taoH), универсальный парсер (OpenGraph / JSON-LD / meta) и сборка результата.
  • content/adapters/*.js — адаптеры площадок, каждый регистрируется в реестр window.__TAO_ADAPTERS объектом { id, label, match(url), parse(base) }. В v1: 1688, Taobao/Tmall, Poizon, DNS (dns-shop.ru).
  • Итог: универсальный парсер → адаптер (если match) уточняет поля → нормализация. Пустые поля адаптера не затирают универсальные.

Добавить площадку: создать content/adapters/<site>.js и добавить путь в массив PARSER_FILES в popup.js. Манифест и бэкенд не меняются (парсинг — по activeTab); для многих сайтов работает и универсальный парсер без адаптера.

Поставка

Распакованное расширение (unpacked): chrome://extensions → «Режим разработчика» → «Загрузить распакованное». Артефакт — каталог taomaster-extension (MV3: manifest.json, popup.*, lib/*, content/*, icons/*, README.md).

Ограничения v1

  • Цена парсится в валюте площадки (¥ для 1688/Taobao); в позицию кладётся числом, итог — в валюте черновика.
  • Фото передаётся ссылкой (URL изображения площадки).
  • Селекторы маркетплейсов меняются — адаптеры могут требовать подстройки; универсальный парсер служит запасным вариантом.
  • Часть для посредника — отдельный этап.