0026. Стратегия доступа к личному кабинету WB (где нет официального API)
Копия ADR из репозитория:
backend/docs/adr/0026-seller-cabinet-access-strategy.md. Канонический текст — в репозитории; портал обновляется командойnpm run sync:adr.
- Статус: accepted (решение согласовано 2026-06-26 — вариант E как база MVP + D за фиче-флагом пост-MVP)
- Дата: 2026-06-26
- Связанные задачи: OP-35 (Spike · эпик OP-3 · Ядро интеграции с Wildberries)
Контекст и проблема
ТЗ (5.5, 5.6, 5.8) предполагает действия, для которых WB на момент исследования не публикует
официальный Seller API, и метод в ТЗ помечен «уточняется». Часть таких действий выполняется
только в веб-интерфейсе личного кабинета (ЛК) seller.wildberries.ru. Нужна безопасная
стратегия: как (и стоит ли) автоматизировать эти действия от имени продавца, давшего согласие и
доступ к своему кабинету, не подставляя его аккаунт под блокировку и не создавая неподъёмного
эксплуатационного и юридического долга.
Уточнение поверхности «только-ЛК» (проверено по локальному OpenAPI-снимку WB + офиц. докам)
Реальная UI-only поверхность узкая — большая часть «спорных» операций официальным API закрыта:
| ТЗ | Операция | Официальный API | Вывод |
|---|---|---|---|
| 5.5 | Чтение/ответ/архив/закрепы отзывов, вопросы | ✅ Feedbacks API (GET /api/v1/feedbacks, POST /api/v1/feedbacks/answer, /questions, /pins) | API |
| 5.5 | Жалоба/обжалование несправедливого отзыва | ❌ метода «пожаловаться» в снимке нет | UI-only (в release-notes WB заявлено добавление «Пожаловаться на отзыв» → перепроверять живой Feedbacks API) |
| 5.6 | РНП: воронка, поисковые запросы, остатки, доля бренда, nm-report | ✅ Analytics API (/api/analytics/v3/sales-funnel/*, /api/v2/nm-report/*, /api/v2/search-report/*, /api/v1/analytics/brand-share) + Advert API (OP-65) | API (gap отсутствует; правила объединения — отдельный спайк OP-86) |
| 5.8 | Чтение лимитов/коэффициентов приёмки, список складов | ✅ POST /api/v1/acceptance/options, GET /api/tariffs/v1/acceptance/coefficients, GET /api/v1/warehouses | API |
| 5.8 | Бронирование слота поставки FBO (привязка к складу/дате, «гонка за слотом») | ❌ POST /api/v3/supplies — это FBS-поставка собранных заказов, не FBO-слот | UI-only |
Итог: по-настоящему UI-only остаются две операции-действия — жалоба на отзыв (5.5, вероятно скоро станет официальной) и бронирование FBO-слота (5.8). Мониторинг для обеих — официальный (лимиты/коэффициенты, список отзывов читаются через API).
Рассмотренные варианты
| Вар. | Суть | Сложность | Юр./риск-профиль |
|---|---|---|---|
| A. Только официальный API | Запросы к *.wildberries.ru Seller API с токеном, выпущенным продавцом (по категориям, TTL 180 дней, флаг «только чтение»). Принять отсутствие двух UI-only действий. | Низкая | Санкционированный доступ, минимальный риск |
| B. Внутренние (неофициальные) эндпоинты ЛК | Переиспользование cookie-сессии/перехваченного bearer веб-кабинета для вызова незадокументированных эндпоинтов. | Высокая (ломкость без анонса, антибот) | Серая зона; прямо под запрет оферты; высокий риск бана |
| C. Headless-браузер / RPA | Playwright/Puppeteer эмулирует клики в UI ЛК (открыть отзыв → «Пожаловаться»; планирование поставки → выбрать слот). | Очень высокая (хрупко к вёрстке, ресурсоёмко, фингерпринт) | Аналогично B; «человекоподобнее», но всё равно автоматизация |
| D. Гибрид | A по умолчанию + точечно B/C только для остаточных UI-only действий, по явному согласию, с fail-safe в ручной шаг. | Средняя в ядре, высокая в «остаточном» модуле | Управляемый: риск изолирован в малом явно-согласованном модуле за фиче-флагом |
| E. Без автоматизации спорного — «ассистируемый ручной шаг» | Сервис делает официальную часть (мониторинг лимитов/коэффициентов, чтение/ответы на отзывы) и подсказывает действие: нотификация «появился слот x1 на складе Y» / «отзыв — кандидат на жалобу» + диплинк в нужный экран ЛК. Само нажатие — продавец. | Низкая (ломается только диплинк, не бизнес-логика) | Минимальный: действие совершает сам пользователь в своём ЛК |
Почему B/C дороги и чувствительны
- Вход в ЛК беспарольный: телефон + одноразовый SMS-код (учётка на WB ID), опционально 2FA на email. Автоматизация не может «залогиниться сама» без человека в момент SMS/2FA. Модель неизбежно «человек вошёл один раз → мы держим и продлеваем его сессию» — это долгоживущий доступ ко всему кабинету (финансы, выводы, цены), а не скоуп-ограниченный API-токен.
- Хранение сессий продавцов требует шифрования at-rest (KMS/Vault), per-tenant изоляции, информированного согласия, аудита, мгновенного отзыва, соответствия 152-ФЗ. Компрометация хранилища сессий = компрометация кабинетов клиентов.
- Оферта WB (дополнение мая 2025, «Правила использования портала») трактует «серые» API/биддеры/парсеры и эмуляцию как основание для блокировки ЛК; есть публичные кейсы бана аккаунта и IP. Согласие продавца закрывает риск «иска от клиента», но не отменяет санкцию WB: WB — третья сторона, и нарушение его правил остаётся основанием для блокировки. Автобронирование — ровно та зона, против которой WB ведёт активную антибот-войну.
Решение
Согласовано (2026-06-26): принять E как базовую стратегию MVP, с заделом под D за фиче-флагом:
- Вариант A для всего, что закрывает официальный Seller API — мониторинг лимитов/коэффициентов приёмки и списка складов (5.8), чтение и ответы на отзывы/вопросы (5.5), вся аналитика РНП (5.6), поставки FBS. Токены — по категориям, с флагом «только чтение» где возможно; секреты шифруются at-rest (ADR-0005), доступ к WB — через rate-limit/retry (ADR-0006).
- Две UI-only операции (жалоба на отзыв 5.5, бронирование FBO-слота 5.8) — как «ассистируемый ручной шаг» (E): сервис детектирует событие (через официальный мониторинг) и нотифицирует продавца с диплинком в нужный экран ЛК; само действие совершает человек. Сессии ЛК не храним.
- Полная автоматизация этих двух действий (D через B/C) — отдельный опциональный пост-MVP модуль за фиче-флагом, не на критическом пути; включается только с явным информированным согласием продавца, с аудит-логированием каждого действия, человеко-подобными паттернами, fail-safe в ручной шаг и per-tenant изоляцией сессий/прокси.
- Триггер пересмотра: перед любой реализацией B/C перепроверять живой Feedbacks/Supplies API — как только WB откроет жалобу/бронирование официально (release-notes намекают на жалобу), операция переезжает в вариант A и модуль за фиче-флагом становится не нужен.
Обоснование
- Реальная UI-only поверхность мала (2 действия) и нестабильна: жалоба, судя по release-notes, скоро станет официальной; автобронирование — фокус антибот-войны WB и обновлённой оферты (бан аккаунта).
- Вариант E даёт ~90% продуктовой ценности (продавец мгновенно узнаёт о слоте/отзыве и кликает сам) при near-zero юридическом и операционном риске и без хранения чувствительных сессий ЛК.
- Сохраняется агентская чистота и не ставится под удар актив клиента (деньги/кабинет) ради автоматизации одного клика; инфраструктуру сессий/прокси/антибот-обхода откладываем до момента, когда продукт докажет спрос именно на полностью автоматический режим.
Последствия
- Положительные: MVP не хранит сессии ЛК и не нарушает оферту WB → аккаунты клиентов не под угрозой блокировки; низкая эксплуатационная нагрузка; реализация двух UI-only действий сводится к нотификации + диплинку (дёшево, ломается только ссылка). Официальная часть переиспользует уже принятые ADR-0005 (шифрование), ADR-0006 (rate-limit/retry).
- Отступления/границы: полностью автоматические жалоба и бронирование в MVP не поставляются — это осознанный отказ ради безопасности; задел остаётся за фиче-флагом. Если заказчик настаивает на полной автоматизации с первого релиза — это меняет риск-профиль (см. вариант D) и требует отдельного решения с принятием ToS-риска и бюджета на хранение сессий/прокси/поддержку.
- Зависимость от внешней нестабильности: диплинки и наличие официальных методов нужно перепроверять при изменениях WB; жалоба на отзыв может стать официальной в ближайших релизах.
- Реализация — отдельными тикетами после согласования (вне scope спайка): эндпоинты мониторинга лимитов/коэффициентов и детектор «кандидатов на жалобу», доставка нотификаций с диплинками, и — опционально, пост-MVP — модуль автодействий за фиче-флагом.