Платформа управления продажами

Фича-лист

Дата: 2026-04-13

Оглавление

  1. Навигационное меню
  2. Роли и доступ (RBAC)
  3. Панель администратора
  4. Мониторинг данных
  5. Журнал аудита
  6. Авторизация и управление пользователями
  7. Личный кабинет (шапка)
  8. РНП — Блок фильтров
  9. РНП — Короткий отчёт
  10. РНП — Паспорт товара
  11. Паспорт товара — Объединение и разъединение карточек
  12. РНП — Аналитика товара
  13. РНП — История товара (rnp-detail-history)
  14. РНП — Основная таблица
  15. BI — Apache Superset (bi-superset)
  16. RBAC — Матрица доступа
  17. Требования к данным из 1С
  18. Требования к данным из API WB
  19. Требования к данным из парсинга и скрапинга
  20. РНП — Карта происхождения MVP-показателей
  21. Целевая модель данных
  22. Короткий словарь терминов
  23. Макеты интерфейса

Навигационное меню

Структура

Максимальная глубина: два уровня (родитель → дочерний пункт).

Дочерний пункт не может иметь детей.

РНП                              [все роли]
BI                               [ГД, Админ, Супер-Админ]
Администрирование                [Админ, Супер-Админ]
  └── Сотрудники
  └── Отделы
  └── Настройки
  └── Мониторинг данных
  └── Аудит

Доступность пунктов по ролям

Пункт менюМенеджерРОПГДАдминСупер-Админ
РНП
BI
Администрирование
→ Сотрудники
→ Отделы
→ Настройки
→ Мониторинг данных
→ Аудит

Пункты, недоступные роли, не отображаются (не скрыты визуально, а отсутствуют в DOM).

Правила

Визуальные макеты интерфейсов — макеты интерфейса (PDF).

Роли и доступ (RBAC)

Обзор

Система ролей определяет, какие разделы и данные видит пользователь.

Детальная матрица доступа — отдельный документ.

Роли

РольОписаниеНазначение
Супер-админЕдинственная стартовая учётка. Видит всё.Создаётся при деплое, роль неизменна
АдминНазначенный администратор. Видит всё.Назначается супер-админом вручную
ГДГенеральный директор. Видит сводку и BI (Superset).Назначается вручную
РОПРуководитель отдела продаж. Видит товары своих менеджеров.Назначается вручную или как руководитель отдела
МенеджерБазовая роль. Видит только свои товары.Роль по умолчанию при создании из 1С

Правила

Матрица доступа — «RBAC — Матрица доступа».

Панель администратора

Обзор

Раздел доступен только супер-админу и назначенным админам.

Содержит: глобальные настройки системы, управление пользователями, управление отделами.

Глобальные настройки

Список параметров, которые администратор может изменить через UI:

ПараметрОписаниеПо умолчанию
Время жизни ссылки восстановления пароляЧерез сколько часов ссылка сброса истекает1 час
Предлагать смену пароля при первом входеФлаг для новых пользователейуточнить
Кол-во дней для Dead StockN дней без заказов → товар в DSуточнить
Отдел по умолчанию для новых сотрудниковКуда попадает сотрудник из 1С, если не указан отделобязательная настройка системы
Срок хранения журнала аудитаКол-во дней хранения записей (от 1 до 365)уточнить

API-токены внешних сервисов:

ПараметрОписание
WB API токенТокен Wildberries для выгрузки данных и write-back операций
MPStats токенТокен для получения внешней аналитики
Список токенов и настроек будет пополняться.

Управление пользователями

Таблица всех пользователей системы.

Доступные действия на пользователе:

Логика блокировки:

Управление отделами

Функциональность:

Руководитель отдела:

Пользователь с ролью РОП (RBAC), назначенный руководителем отдела через атрибут head_user_id на сущности отдела.

Роль РОП определяет уровень доступа, head_user_id определяет конкретный отдел.

head_user_id может ссылаться только на пользователя из этого же отдела.

Руководитель видит товары всех сотрудников своего отдела.

При удалении отдела:

Все сотрудники отдела переводятся в отдел по умолчанию.

Отдел по умолчанию удалить нельзя.

Глобальная настройка: отдел по умолчанию — куда попадает новый сотрудник из 1С, если явно не указан отдел.

Технически критичные глобальные настройки храним как typed-поля, а не как произвольный JSON. В этот слой входят как минимум:

Мониторинг данных

Обзор

Раздел доступен только супер-админу и назначенным админам.

Показывает состояние ETL-пайплайнов (cron) и потока синхронизации из 1С. Только чтение — управление пайплайнами (перезапуск и т.д.) не предусмотрено в текущей версии.

ETL / Cron-пайплайны

Таблица всех cron-задач. Данные получаются из PG_ETL_PIPELINE_STATUS.

Колонки:

ПолеОписание
Название пайплайнаИдентификатор / описание пайплайна
Статус последнего запускаsuccess / failed / running / no runs
Время стартаДата и время последнего запуска
Время завершенияКогда завершился последний запуск
ДлительностьВремя выполнения последнего запуска
Следующий запускСледующее время по расписанию
Watermark данныхДо какой бизнес-даты / времени данные фактически догружены
Freshness lagНасколько текущие данные отстают от ожидаемой свежести
Обработано строкКол-во строк / событий, успешно обработанных последним прогоном
Rejected / skipped / duplicatesТехнические счётчики качества загрузки
Сообщение об ошибкеТолько при статусе failed — краткое сообщение из лога пайплайна

Поведение:

Синхронизация 1С → Kafka

Мониторинг синхронизации состоит из трёх operational-слоёв:

На UI это может быть сведено в компактный блок, но логически это не одна универсальная “лента всего подряд”.

Базовый экран MVP: лента последних событий из Kafka-топика синхронизации сотрудников + ошибки обработки.

Колонки:

ПолеОписание
Время событияTimestamp из Kafka
Типновый сотрудник / обновление / увольнение
Email сотрудникаИдентификатор из события
Статус обработкипринято / ошибка
Детали ошибкиЗаполняется при статусе ошибка

Параметры:

Сводный статус по источникам

Отдельный компактный блок, который показывает здоровье не только пайплайна, но и самих данных по каждому источнику.

Колонки:

ПолеОписание
ИсточникНапример: 1С Номенклатура, 1С Сотрудники, WB Sales Funnel, WB Stocks, Скрапер СПП
Статусhealthy / lagging / failed / no data
Последняя успешная синхронизацияКогда источник последний раз успешно обновился
Watermark данныхДо какого момента источник фактически догружен
Freshness lagНасколько источник отстаёт от ожидаемой свежести
Обработано / rejected / skipped / duplicatesКраткие счётчики качества загрузки
Последняя ошибкаЕсли источник сейчас в проблемном состоянии

Технические решения

Журнал аудита

Обзор

Раздел доступен только супер-админу и назначенным админам.

Фиксирует все административные действия в системе. Только чтение.

Таблица событий

Колонки:

ПолеОписание
Дата и времяTimestamp действия
АдминистраторКто выполнил действие (email / имя)
Тип действияКатегория события (см. ниже)
ОбъектНа кого / что направлено действие
ДеталиПодробности: старое и новое значение, где применимо

Типы отслеживаемых действий

Пользователи:

Отделы:

Глобальные настройки:

Сессии:

Фильтры

Авторизация и управление пользователями

Обзор

Классическая авторизация по логину и паролю. Без SSO, LDAP, OAuth.

Источник пользователей — 1С, синхронизация через Kafka.

Роли и субординация — отдельный документ.

Экран логина

Поля:

Дополнительно:

Восстановление пароля

Правило доступа к логину / reset:

Синхронизация пользователей из 1С

Источник: 1С Справочник Сотрудники / Физические лица → Kafka

Требования к данным из 1С:

Сценарий: новый пользователь появился в 1С

Сценарий: пользователь уволен (признак активности = неактивен)

Технические требования auth-слоя:

Личный кабинет (шапка)

Обзор

Постоянный элемент интерфейса, доступный из любого экрана. Расположение: правый верхний угол.

Элемент в шапке

Инициалы пользователя или аватар → клик → дропдаун:

Смена пароля

Поля:

РНП — Блок фильтров

Обзор

Фильтры применяются глобально ко всему экрану РНП и определяют

какой срез данных видит пользователь. Все фильтры работают в комбинации (AND).

Менеджер по умолчанию видит только свои артикулы — фильтр по менеджеру

проставляется автоматически из его роли.

Фильтры

1. Период

2. Категория 1С

3. Сезон продаж

4. Коллекция

хранения как SCD Type 2 по артикулам и периодам

5. Менеджер

Менеджер видит только свои артикулы — фильтр проставляется из RBAC автоматически.

РОП и ГД видят всё.

6. ABC

В новой системе считаем сами.

7. Количество дней на сайте

8. ВП, %

9. Артикул WB

10. Артикул поставщика

Группы выгрузок, которые питают фильтры

Группа A — WB API: История остатков

Питает: Артикул WB, Артикул поставщика, Период (даты), Категория WB (предмет), Бренд

Группа B — 1С справочник Номенклатура

Питает: Категория 1С, Сезон продаж, Материал верха, Фабрика

Группа C — 1С Воронка продаж

Питает: Коллекция, Менеджер (назначение артикула)

Группа D — Расчётные величины (считаем сами в DWH)

Питает: ABC, Количество дней на сайте, ВП%

РНП — Короткий отчёт

Обзор

Блок сводных KPI-карточек в верхней части экрана РНП. Отображает агрегированные показатели

по текущему фильтру. Все значения пересчитываются при изменении фильтров.

Структура отображения для первых трёх метрик: план / факт / % выполнения плана / дельта (факт − план).

Метрики

1. Выручка, млн. руб

2. % проданного

3. ЧП, руб

4. % участия в акциях

5. Мотивация менеджера

Группы выгрузок, которые питают короткий отчёт

Группа A — API WB v3: Sales Funnel

Питает: Выручка факт (Показатель 20)

Группа B — 1С Планирование продаж

Питает: план по Выручке, % проданного, ЧП (Показатели 67, 69, 77)

Группа C — Расчётные величины (считаем сами в DWH)

Питает: % проданного факт, все показатели % плана и дельты, % участия в акциях, мотивация менеджера (Показатели 79, 115–122)

РНП — Паспорт товара

Обзор

Паспорт — первый из трёх блоков в раскрываемой строке товара на экране РНП.

Содержит идентификационные и справочные данные по артикулу: кто производит, откуда, в какой коллекции, сколько заказано.

Данные преимущественно статичные (справочник), обновляются редко.

Поля

Идентификация

ПолеПоказательИсточникЧастота
Фото товараAPI WB Карточка товара — проксируем URL, бинарники не хранимраз в день
Артикул WB2API WB История остатковраз в день
Артикул поставщика3API WB История остатковраз в день
Юр лицо5API WB seller-info, поле tinраз в день
Бренд6API WB История остатковраз в день
Повтор591С справочник Номенклатурасправочник

Классификация

ПолеПоказательИсточникЧастота
Категория 1С501С справочник Номенклатурасправочник
Вид категории511С справочник Номенклатурасправочник
Товарная категория521С справочник Номенклатурасправочник
Особенности модели531С справочник Номенклатурасправочник
Пол541С справочник Номенклатурасправочник
Категория WB (Предмет)4API WB История остатковраз в день
Сезон продаж551С справочник Номенклатурасправочник
Страна происхождения561С справочник Номенклатурасправочник
Направление571С справочник Номенклатурасправочник
Группа списка581С справочник Номенклатурасправочник
Коллекция441С Воронка продажпо событию изменения
Материал верха481С справочник Номенклатурасправочник
Материал подкладки491С справочник Номенклатурасправочник
Цвет материала верха601С справочник Номенклатурасправочник
Цвет611С справочник Номенклатурасправочник
Фабрика471С справочник Номенклатурасправочник

Закупка и себестоимость

ПолеПоказательИсточникЧастота
Заказано, шт451С Заказ поставщикусобытийно
Дозаказ, шт1С Заказ поставщикусобытийно
Себестоимость, руб621С Приобретение товаров и услуг → Kafkaпри поступлении товара
Себестоимость, юани911С Заказ поставщику → Kafkaсобытийно

Дозаказ, шт считаем на нашей стороне как сумму количества по строкам заказов поставщику, где документ помечен признаком дозаказ, только в рамках актуального сезона / коллекции для артикула.

Прочее

ПолеПоказательИсточникЧастота
Кол-во дней на сайте113расчётная величинараз в день
Рейтинг по отзывам40API WBраз в день

Специальные блоки

Эластичность спроса

График зависимости заказов от цены и СПП/WB Club.

Визуализирует как менялись заказы при изменении цены.

Статус: MVP.

Источники: заказы (П7), цена факт (П42), СПП (П65) — все ежедневные.

Формулы: П42 = П20 / П19, П64 = П42 * (1 - П65).

Технический момент: СПП и цену нужно хранить историчски (запись раз в день), не только текущее значение.

История изменений карточки

Таймлайн с вехами: изменения фото, SEO, описания, категории, цены.

Статус: MVP.

Реализация: аудит-лог товара — при каждой ежедневной выгрузке из API сравниваем ключевые поля с предыдущим снимком, фиксируем дельту как событие. WB API историю не отдаёт, фиксируем сами.

Объединение / разъединение карточек

Функционал write-back через API WB — merge/split карточек товара.

Статус: MVP — выделяется в отдельный feature-документ, обсуждается отдельно.

Группы выгрузок

Группа A — API WB: История остатков

Питает: Артикул WB, Артикул поставщика, Категория WB, Бренд

Группа A2 — API WB: Seller Info

Питает: Юр лицо

Группа B — 1С справочник Номенклатура

Питает: Категория 1С, Сезон продаж, Материал верха, Фабрика, Повтор

Группа C — 1С Воронка продаж

Питает: Коллекция

Группа D — 1С Закупки

Питает: Заказано шт, Себестоимость руб/юани

Группа E — Расчётные величины

Питает: Кол-во дней на сайте

Паспорт товара — Объединение и разъединение карточек

Обзор

Функционал write-back через API WB. Позволяет объединить несколько карточек товара

в одну группу (единый imtID) или разъединить сгруппированные карточки.

Доступ: из блока "Паспорт" на экране РНП. Кнопка видна Менеджеру, РОП, Админу, Супер-Админу (по матрице «RBAC — Матрица доступа»). ГД — только чтение, кнопка скрыта.

Механика API WB

Один эндпоинт для обоих операций:

POST https://content-api.wildberries.ru/content/v2/cards/moveNm

Объединение — указываем targetIMT (imtID группы, куда добавляем) и массив nmIDs:

{
  "targetIMT": 123456,
  "nmIDs": [837459235, 828572090]
}

Разъединение — тот же эндпоинт, targetIMT не передаём, только nmIDs.

WB генерирует новые imtID для разъединённых карточек.

Если передать несколько nmID без targetIMT — они объединятся в новую группу с новым imtID.

Чтобы дать каждой карточке отдельный imtID — отправлять по одной за запрос.

Ограничения WB:

Группа в API:

При запросе списка карточек (POST /content/v2/get/cards) каждая карточка возвращает nmID и imtID.

Карточки с одинаковым imtID — в одной группе. Это основа для отображения связей.

UI-флоу: объединение

UI-флоу: разъединение

Технические решения

РНП — Аналитика товара

Обзор

Второй из трёх блоков в раскрываемой строке товара на экране РНП.

По умолчанию свёрнут — отображается по клику на заголовок блока.

Содержит метрики план/факт/% плана/дельта за выбранный в фильтре период, воронку продаж и операционные показатели по конкретному артикулу.

Метрики план / факт

Структура отображения: план / факт / % выполнения плана / дельта (факт − план).

Финансовые

МетрикаПок. планИсточник планПок. фактИсточник факт% планаДельта
Выручка, млн. рубП671С Планирование продажП20API WB v3 Sales Funnel, buyoutSumП115П116
Выручка, штП711С Планирование продажП19API WB v3 Sales Funnel, buyoutCountП123П124
Цена, рубП681С Планирование продажП42расчётная (П20 / П19)П125П126
% проданногоП691С Планирование продажП79расчётная (П20 / П45)П117П118
ЧП, %П140расчётнаяП96расчётная (П95 / П20)П127П128
ЧП, рубП771С Планирование продажП95расчётная (П80 - П84 - П86 - П87 - П88 - П21)П119П120
Расходы на рекламу, рубП1021С Планирование продаж, поле Реклама внутренняя, рубП21API WB ПродвижениеП129П130
ДРР, %П131расчётнаяП82расчётнаяП132П133
П97 в исходном xlsx — опечатка. Клиент подтвердил: факт ЧП = П95.

АВС-рейтинг

МетрикаПоказательИсточник
АВСП99расчётная, еженедельно

Воронка продаж (факт)

Источник переходов и конверсий: POST /api/analytics/v3/sales-funnel/products (API WB v3) — openCount, addToCartCount, ordersCount ежедневно по nmID.

Источник показов: внешний скрапер другой команды (данные из LK WB, раздел «Воронка продаж», поле «Показы»).

Примечание: поле views (показы) в WB API не реализовано. Реальное поле — openCount (переходы в карточку). Показы доступны только через внешний скрапер другой команды.
ПоказательПок.Формула
CTR клик (по товару)П18openCount / показы (внешний скрапер другой команды)
CR корзинаП135addToCartCount / openCount
CR заказП136ordersCount / openCount
% выкупа (по товару)П26выкупы / заказы

Операционные показатели

МетрикаПок.ИсточникПримечание
% отгруженного от заказаП137расчётнаяП155 / П45
Индекс локализацииП138расчётнаяlocalOrderPercent из парсинга WB Analytics (см. scraping §4.1). Средневзвешенный КТР по заказам за 13 недель
КТР (коэф. территориального распределения + размерная горка)П139расчётнаяindex из таблицы соответствия left <= П138 <= right (см. scraping §4.2). Детали: WB инструкция
АутоффстокП89расчётная% отсутствующих размеров от полной размерной горки артикула. Пример: горка 6 размеров, в наличии 4 → аутовсток 33%

СПП (Скидка постоянного покупателя)

СПП в WB API недоступен. Источник — внешний скрапер другой команды.

Частота: раз в час (текущая практика клиента).

Хранить историчски ежедневно — необходимо для графика эластичности спроса в паспорте.

Группы выгрузок

Группа A — API WB v3: Sales Funnel

Питает: Выручка факт (П20), Выручка шт факт (П19), воронка (П18, П135, П136, П26)

Группа B — API WB: Продвижение

Питает: Расходы на рекламу факт (П21)

Группа C — 1С Планирование продаж

Питает: все плановые показатели и исходные плановые величины для downstream-расчётов (П67, П68, П69, П70, П71, П72–П78, П100, П102, П141, П156)

Группа D — Скрапинг

Питает: СПП (П65), Показы для CTR (П18)

Группа E — Расчётные величины (DWH)

Питает: % проданного, ЧП%, ЧП руб, ДРР, АВС, воронка расчётные, операционные (П79, П80, П82, П89, П96, П99, П115–П133, П135–П140)

РНП — История товара (rnp-detail-history)

Обзор

Третий блок в раскрываемой строке товара на экране РНП. Показывает исторические данные по артикулу в разрезе дней.

По умолчанию свёрнут — отображается по клику.

Структура отображения

Строки = метрики / поля.

Колонки = дни: первая колонка после названий — сегодня, следующая — вчера, и т.д. вправо в глубину истории.

Производительность: горизонтальный виртуальный скролл с ленивой подгрузкой колонок — браузер рендерит только видимые дни, остальные подгружаются по мере прокрутки.

Пустое состояние: до выбора фильтра таблица РНП не отображается вообще — соответственно и этот блок тоже.

Строки таблицы

Блок событий

ПолеПок.ИсточникПримечание
Акция (название)П104API WB Promotioncalendar/promotions + calendar/promotions/nomenclatures; название акции + статус участия для конкретного nmID
АВСП99расчётная, еженедельноКласс артикула на эту неделю
План отгрузки1С Приходный ордерРасчётная дата: дата проведения приходного ордера + 4 дня. Поле не хранится напрямую — вычисляется при каждой загрузке.

План действий

Текстовое поле на каждый день.

Заказы

МетрикаПок. планПок. фактИсточник факт
Заказы, штП72 (1С Планирование продаж)П7API WB v3 Sales Funnel, orderCount

Плановая оборачиваемость (П29, П30) и связанный с ней блок в текущий MVP не входят. Возвращаемся к ним в следующих итерациях после появления устойчивого источника в 1С.

Остатки

МетрикаПок.Источник
Остатки на текущий день, штП33API WB История остатков
Остаток в путиП37расчётная
АутоффстокП89расчётная% отсутствующих размеров от полной размерной горки

Цена

МетрикаПок.Источник
Цена план (текущий месяц)П681С Планирование продаж
Цена план (следующий месяц)П1411С Планирование продаж
Цена фактП42расчётная (П20 / П19)
% скидки (факт)П66WB Reports API, supplier/orders.discountPercent
СППП65внешний скрапер другой команды, раз в час
Цена для покупателя (минус СПП)П64расчётная (П42 * (1 - П65))
Цена для покупателя (минус Клуб WB)П142API WB

Финансы ВП

МетрикаПок. планПок. факт
ВП, %П145 (П144 / П67)П81
ВП, рубП144 (П67 - П156)П80 (П20 - П63)

Себестоимость и затраты (скрыто для роли Менеджер)

МетрикаПок.Источник
Себестоимость, юаниП911С Заказ поставщику → Kafka
Себестоимость, рубП621С Приобретение товаров и услуг → Kafka
Курс юань/рубП901С Справочник Сезон продаж
Переменные на ед.П871С Нормативы для расчета планов
Постоянные на ед.П881С Нормативы для расчета планов
Все комиссииП84расчётная (П20 * П83)
Налоговая нагрузка, %П851С Нормативы для расчета планов

Воронка и реклама

МетрикаПок.Источник
CTR клик (по товару)П18openCount / показы; показы — внешний скрапер другой команды, openCount — API WB v3 Sales Funnel
CR корзинаП135addToCartCount / openCountAPI WB v3 Sales Funnel
CR заказП136ordersCount / openCountAPI WB v3 Sales Funnel
% выкупа (по товару)П26расчётная
CTR клик рекламныйП150расчётная из API WB Продвижение
CPO рекламныйП153расчётная
Расходы на рекламу планП1021С Планирование продаж, поле Реклама внутренняя, руб
Расходы на рекламу фактП21API WB Продвижение

Отзывы

МетрикаИсточник
Рейтинг по отзывам (П40)API WB v3 Sales Funnel, feedbackRating
Кол-во негативных отзывовAPI WB
Расчётное кол-во для перекрытия негативарасчётная

Write-back: цена и скидка

Кнопки "Выгрузка новой цены" и "Выгрузка новой скидки" — inline-форма в строке истории.

Механика:

Ограничения WB:

Write-back: участие в акции

По текущим ответам клиента механика блока акций в MVP выглядит так:

В строке каждого дня (или в отдельном блоке на сегодня) отображается:

ЭлементОписание
Название акцииИз П104 — текущая акция WB
Предложение WBРекомендованные скидка и цена для участия (из API WB акций)
Статус участияДа / Нет — участвует ли товар в этой акции
Индикатор участия"1/1" или аналог — количество доступных акций для артикула
Кнопка "Участвовать"Менеджер вводит параметры участия; write-back идёт в WB promotion-контур

DS-товары и акции:

РНП — Основная таблица

Обзор

Главная часть экрана РНП. Отображает список артикулов, соответствующих выбранным фильтрам.

Каждая строка — один артикул (nmID). Строка раскрывается аккордеоном в три блока:

«РНП — Паспорт товара» → «РНП — Аналитика товара» → «РНП — История товара».

Пустое состояние: пока фильтр не применён — таблица не отображается вовсе.

Колонки таблицы

Колонки видимые по умолчанию (без раскрытия строки):

КолонкаПок.ИсточникПримечание
ФотоAPI WB Карточка товараПервое (главное) фото, проксируется через backend
Артикул WBП2API WB История остатковnmID
Артикул поставщикаП3API WB История остатковVendor code
БрендП6API WB История остатков
Категория 1СП501С справочник Номенклатура
КоллекцияП441С Воронка продажТекущая (по SCD Type 2)
МенеджерП461С Воронка продажТекущий (по SCD Type 2)
ABCП99расчётная, еженедельноБейдж: A / B / C / DS
Остатки, штП33API WB История остатковНа текущий день
Заказы, шт (факт)П7API WB v3 Sales Funnel, orderCountЗа выбранный период
Выручка, руб (факт)П20API WB v3 Sales Funnel, buyoutSumЗа выбранный период
ЧП, % (факт)П96расчётнаяЗа выбранный период
Цена для покупателяП64расчётная (П42 * (1 - П65))Актуальная
АутоффстокП89расчётнаяЗа выбранный период

Сортировка

Механика раскрытия строки

Клик на строку — строка раскрывается аккордеоном, под ней появляются три вложенных блока:

▼ Строка артикула (раскрыта)
  ├── [Паспорт товара]         ← первый, раскрыт по умолчанию
  ├── [Аналитика товара]       ← второй, свёрнут
  └── [История товара]         ← третий, свёрнут

Производительность

RBAC

РольВидит
МенеджерТолько свои артикулы (фильтр по менеджеру проставляется автоматически из RBAC)
РОПВсе артикулы своего отдела
ГД, Админ, Супер-АдминВсе артикулы

Решения

BI — Apache Superset (bi-superset)

Обзор

Отдельная страница с встроенными BI-дашбордами Apache Superset.

Предназначена для аналитики в свободном формате — настройка и просмотр дашбордов без ограничений по метрикам.

Доступ: ГД, Админ, Супер-Админ.

Структура страницы

Конфигурация дашбордов

UUID дашбордов хранятся в конфиге деплоя (не в БД и не в настройках системы).

Изменение набора дашбордов → изменение конфига + редеплой.

Пример структуры конфига:

superset:
  dashboards:
    - id: "abc123-uuid"
      title: "Продажи"
    - id: "def456-uuid"
      title: "Остатки"
    - id: "ghi789-uuid"
      title: "Реклама"

Механика аутентификации (Guest Token)

WB-система не передаёт пользователей в Superset напрямую.

Доступ к дашбордам обеспечивается через Guest Token:

RLS не требуется — ГД, Админ и Супер-Админ видят все данные без ограничений.

Требования к конфигурации Superset

Фиксируется в superset_config.py при деплое:

FEATURE_FLAGS = {
    "EMBEDDED_SUPERSET": True
}

ENABLE_CORS = True
CORS_OPTIONS = {
    "origins": ["https://our-app-domain.com"]
}

TALISMAN_CONFIG = {
    "content_security_policy": {
        "frame-ancestors": ["https://our-app-domain.com"]
    }
}

Сервисный аккаунт Superset (логин/пароль для минтинга guest token) хранится в секретах backend-сервиса.

RBAC — Матрица доступа

Навигация

РазделМенеджерРОПГДАдминСупер-Админ
РНП
BI (Superset)
Администрирование → Сотрудники
Администрирование → Отделы
Администрирование → Настройки
Администрирование → Мониторинг данных
Администрирование → Аудит

РНП — скоуп данных

РольВидит артикулы
МенеджерТолько свои по историческому assignment на выбранный период
РОПВсе артикулы своего отдела по историческому составу отдела и assignment на выбранный период
ГДВсе артикулы
АдминВсе артикулы
Супер-АдминВсе артикулы

РНП — скрытые поля (история товара)

Поля скрыты от роли Менеджер, остальные видят:

ПолеМенеджерРОПГДАдминСупер-Админ
Себестоимость (юани / руб)
Курс юань/руб
Переменные на ед.
Постоянные на ед.
Все комиссии
Налоговая нагрузка, %

РНП — write-back операции

ОперацияМенеджерРОПГДАдминСупер-Админ
Изменить цену / скидкусвоиотделвсевсе
Участие в акциисвоиотделвсевсе
Объединение / разъединение карточексвоиотделвсевсе
План действий (текстовое поле)своиотделвсевсе
"Свои" — артикулы, назначенные менеджеру по историческому assignment на выбранный период.
"Отдел" — все артикулы менеджеров отдела по историческому составу отдела и assignment на выбранный период.
ГД — только чтение по всем артикулам.

Администрирование

ДействиеМенеджерРОПГДАдминСупер-Админ
Управление пользователями
Назначить роль Супер-Админ
Управление отделами
Глобальные настройки
Мониторинг данных (cron / Kafka)
Аудит операций
Роль Супер-Админ не назначается через UI никем — создаётся при деплое, изменить нельзя.

Требования к данным из 1С

Всё что нам нужно получить из 1С через Kafka.

Документ — основа для постановки задачи подрядчику 1С.

Канал передачи для всех блоков: 1С → Kafka → наш ETL → DWH.

1. Сотрудники

Объект 1С: Справочник Сотрудники / Физические лица

ПолеОписаниеПримечание
GUID сотрудникаУникальный идентификатор в 1СКлюч для идемпотентной синхронизации и связки с ответственными по товару
Фамилия, Имя, ОтчествоОтображается в интерфейсе
EmailИспользуется как уникальный логин в системеЦелевое обязательное поле auth-контура
Признак активностиРаботает / УволенЦелевое обязательное поле auth-контура

Механика синхронизации:

Важно: если в текущей конфигурации 1С поля email и / или признака активности ещё нет, это не снимает требование с интеграционного контракта. Для запуска целевого auth-контура эти поля должны быть добавлены в модель 1С отдельной доработкой.

Отдел сотрудника: поле отдела из 1С не передаётся. Назначение в отдел — только через UI системы (раздел «Управление отделами»). Новый сотрудник из 1С автоматически попадает в «отдел по умолчанию» (настраивается в глобальных настройках).

2. Справочник Номенклатура

Объект 1С: Справочник Номенклатура

Тип загрузки: SCD Type 2 (история изменений важна)

ПолеПоказательПримечание
Артикул поставщикаП3Vendor code, ключ связки с WB nmID
Категория 1СП50Не совпадает с категорией WB
Вид категорииП51
Товарная категорияП52
Сезон продажП55
Особенности моделиП53
ПолП54
Страна происхожденияП56
НаправлениеП57
Группа спискаП58
Материал верхаП48Источник — только 1С
Материал подкладкиП49
Цвет материала верхаП60
ЦветП61
Фабрика / производительП47Источник — только 1С
Признак «Повтор»П59Да / Нет

3. Воронка продаж (назначение менеджера и коллекции)

Объект 1С: 1С Воронка продаж

Тип загрузки: SCD Type 2 (менеджер и коллекция меняются помесячно)

ПолеПоказательПримечание
Артикул поставщикаКлюч привязки к номенклатуре
КоллекцияП44Например: «Осень-Зима 2025-2026»
Менеджер (ID сотрудника)П46Один менеджер на артикул в периоде
Дата начала назначенияНужна для SCD Type 2

Критично: без этого источника невозможно разграничить данные по менеджерам за прошлые периоды.

4. Планирование продаж

Объект 1С: 1С Планирование продаж

Тип загрузки: плановые значения на месяц, обновляются при изменении плана

ПолеПоказательГранулярность
Выручка план, рубП67Артикул × месяц
Выручка план, штП71Артикул × месяц
Цена план (текущий месяц)П68 / П31Артикул × месяц
Цена план (следующий месяц)П141 / П32Артикул × месяц
% проданного планП69Артикул × месяц
% проданного план накопленный по коллекцииП70Коллекция × месяц
ЧП план, рубП77Артикул × месяц
Себестоимость план, едП78Артикул × месяц
Себестоимость план (агрегат)П156Артикул × месяц
Расходы на рекламу план, руб (Реклама внутренняя, руб)П102Артикул × месяц
Заказы план, штП72Артикул × месяц
Корзины планП73Артикул × месяц
Переходы планП74Артикул × месяц
Показы планП75Артикул × месяц
Отгрузки планП76Артикул × месяц
Средняя цена заказа планП100Артикул × месяц

Примечание по рекламе: для П102 фиксируем поле Реклама внутренняя, руб в 1С Планирование продаж.

5. Приобретение товаров и услуг (себестоимость)

Объект 1С: Документ «Приобретение товаров и услуг»

Тип загрузки: событийный — появляется при фактическом поступлении товара

Источник: только 1С → Kafka. Excel как источник себестоимости исключён.

ПолеПоказательПримечание
Артикул поставщикаКлюч привязки
Себестоимость, рубП62Пустое до момента прихода товара — отображать прочерк, не ноль
Дата поступленияНужна для исторического хранения

⚠️ Важно для подрядчика 1С — два жизненных цикла себестоимости:

Передавать нужно только проведённые документы «Приобретение товаров и услуг», не помеченные на удаление. Неподтверждённые и черновики исключаем.

6. Заказ поставщику

Объект 1С: Документ «Заказ поставщику»

Тип загрузки: событийный

ПолеПоказательПримечание
Артикул поставщикаКлюч привязки
Заказано, штП45Количество в заказе
Себестоимость в юаняхП91Пустое до оформления заказа — отображать прочерк, не ноль
Признак типа заказаНовый допреквизит документа: основной заказ / дозаказ
Сезон заказаИспользуем для фильтрации дозаказов только в рамках актуального сезона / коллекции
Дата заказа

Правило для Дозаказ, шт:

7. Приходный ордер (план отгрузки)

Объект 1С: Документ «Приходный ордер»

Как найти: через связанные документы Заказа поставщику

Тип загрузки: событийный

ПолеПоказательПримечание
Артикул поставщикаКлюч привязки
Дата проведенияИспользуется для расчёта плановой даты отгрузки: дата проведения + 4 дня
Количество к отгрузке, шт

⚠️ Транзиентное поле: мы не храним «плановую дату отгрузки» напрямую. При каждой загрузке берём дату проведения приходного ордера, добавляем 4 дня — и вот это и есть плановая дата. Никакого отдельного поля «план отгрузки» в 1С нет.

8. Нормативы для расчета планов

Объект 1С: Справочник / регистр «Нормативы для расчета планов»

Тип загрузки: справочник, меняется редко

ПолеПоказательПримечание
Комиссия ВБ, %П83Плановый норматив
Налоговая нагрузка, %П85
Переменные расходы на ед. (без налогов, комиссии и курсовых разниц)П87
Постоянные расходы на ед.П88

Бизнес-правило выбора норматива (подтверждено клиентом, Ольга показала из 1С):

9. Справочник Сезон продаж (курс юань/руб)

Объект 1С: Справочник Сезон продаж

Тип загрузки: справочник

ПолеПоказательПримечание
Курс юань / рубП90Плановый курс, хранящийся в 1С; нужен для пересчёта себестоимости

10. Реализация товаров и услуг (фактические отгрузки)

Объект 1С: Документ «Реализация товаров и услуг»

Тип загрузки: событийный

ПолеПоказательПримечание
Артикул поставщикаКлюч привязки; downstream-агрегация по коллекции делается уже у нас
Отгрузки, рубП155В reference-upd.xlsx показатель описан как сумма отгрузок по коллекции
Дата документаНужна для исторического хранения

11. Показатели вне текущего обязательного контракта 1С

Эти показатели не входят в текущий обязательный контракт 1С.

ПоказательПок.Вопрос
Юр лицоП5Источник фиксируем не в 1С, а в WB API через seller-info по токену кабинета
Плановая оборачиваемость 1 и 2П29, П30В текущем MVP показатели не реализуем. Post-MVP follow-up для Веры / 1С: предусмотреть место в 1С для ввода плановой оборачиваемости с нужной детализацией, датами и версионностью; отдельно проработать допкритерии, которых сейчас нет в модели 1С

Сводная таблица объектов

Объект 1СТипТранспортХранение в DWH
Справочник СотрудникиСправочникKafkaАктуальное состояние + признак активности
Справочник НоменклатураСправочникKafkaSCD Type 2
Воронка продаж (менеджер / коллекция)СправочникKafkaSCD Type 2
Планирование продажПлановый документKafkaАктуальный план на месяц
Приобретение товаров и услугТранзакционныйKafkaИсторически по дате поступления
Заказ поставщикуТранзакционныйKafkaИсторически по дате
Приходный ордерТранзакционныйKafkaДата проведения + кол-во; плановая дата = дата + 4 дня (вычисляется, не хранится)
Нормативы для расчета плановСправочникKafkaАктуальное состояние
Справочник Сезон продажСправочникKafkaАктуальное состояние (курс юань/руб)
Реализация товаров и услугТранзакционныйKafkaИсторически по дате

Требования к данным из API WB

Всё что нам нужно забирать из API Wildberries для РНП.

Документ — основа для постановки задач по ETL и интеграции с WB API.

Канал передачи для всех блоков: WB API → наш ETL → DWH.

Принципы

Статусы валидации

1. Sales Funnel v3

Статус валидации:

Источник: WB Seller Analytics

Метод: POST /api/analytics/v3/sales-funnel/products

Домен: seller-analytics-api.wildberries.ru

Частота: раз в день

Гранулярность: nmID × день

ПолеПоказательПоле APIПримечание
Артикул WBП2nmIdНСИ
Артикул поставщикаП3vendorCodeНСИ
ПредметП4subjectNameНСИ
БрендП6brandName
Заказы, штП7orderCount
Заказы, рубП8orderSum
Перешли в карточкуП9openCount
Положили в корзинуП10cartCount
Доля карточки в выручкеП12shareOrderPercent
Добавили в отложенныеП13addToWishlist
Заказали WB Club, штП14wbClub_orderCount
Выкупили WB Club, штП15wbClub_buyoutCount
Среднее время доставкиП16timeToReady
Отменили, штП17cancelCount
Выкупы, штП19buyoutCount
Выкупы, рубП20buyoutSum
Рейтинг карточкиП39productRating
Рейтинг по отзывамП40feedbackRatingСредний рейтинг товара по отзывам, шкала 1–5
Цена минус Club WBП142wbclub_avgPrice

Технические замечания:

1A. Seller Info

Статус валидации:

Источник: WB API Information

Метод: GET /api/v1/seller-info

Частота: при каждой полной загрузке WB + при подключении нового токена

Гранулярность: token / seller cabinet

ПолеПоказательПоле APIПримечание
Юр лицоП5tinРабочий идентификатор юрлица в проекте
Идентификатор кабинета WBsellerIdТехнический идентификатор кабинета / продавца
Название кабинета / продавцаnameDisplay-name для кабинета

Правило использования:

2. История остатков — товары

Статус валидации:

Источник: WB Seller Analytics

Метод: POST /api/v2/stocks-report/products/products

Домен: seller-analytics-api.wildberries.ru

Частота: раз в день

Гранулярность: nmID × день

ПолеПоказательПоле API
Остатки на текущий день, штП33stockCount
Стоимость остатков на текущий деньП34stockSum

3. История остатков — склады WB

Статус валидации:

Источник: WB Seller Analytics

Метод: POST /api/analytics/v1/stocks-report/wb-warehouses

Домен: seller-analytics-api.wildberries.ru

Частота: раз в день

Гранулярность: nmID × день

ПолеПоказательПоле API
В пути к клиентуП35inWayToClient
В пути от клиентаП36inWayFromClient

4. История остатков — офисы / склады

Статус валидации:

Источник: WB Seller Analytics

Метод: POST /api/v2/stocks-report/offices

Домен: seller-analytics-api.wildberries.ru

Частота: раз в день

Гранулярность: nmID × офис × день

ПолеПоказательПоле API
Остатки по складамП107stockCount

5. Карточки товаров

Статус валидации: ⚠️

Источник: WB Content API

Метод: POST /content/v2/get/cards/list

Домен: content-api.wildberries.ru

Частота: раз в день

Гранулярность: nmID

ПолеПоказательПоле APIПримечание
КартинкаП22cards_photosХраним URL / прокси-ссылку, не бинарник
ЯрлыкП24tagsНСИ
Дата создания карточки WBcreated_atТехнический атрибут карточки, храним отдельно как wb_card_created_at

Правило для П38:

6. Продвижение — расходы

Статус валидации:

Источник: WB Продвижение

Метод: GET /adv/v1/upd

Домен: advert-api.wildberries.ru

Частота: раз в день

Гранулярность: зависит от рекламной сущности WB, в витрине агрегируется до товара / периода

ПолеПоказательПоле API
Расходы на рекламу, ₽П21updSum

7. Продвижение — статистика

Статус валидации:

Источник: WB Продвижение

Метод: GET /adv/v3/fullstats

Домен: advert-api.wildberries.ru

Частота: раз в день

Гранулярность: зависит от рекламной сущности WB, в витрине агрегируется до товара / периода

ПолеПоказательПоле API
Рекламные показыП146views
Рекламные переходыП147clicks
Рекламные корзиныП148atbs
Рекламные заказыП149orders

8. Supplier Orders Report

Статус валидации:

Источник: WB Statistics API

Метод: GET /api/v1/supplier/orders

Домен: statistics-api.wildberries.ru

Частота: не зафиксирована в workbook

ПолеПоказательПоле APIПримечание
% скидкиП66discountPercentОфициально задокументированное поле WB Reports API

9. Календарь акций

Статус валидации:

Источник: WB Promotion

Метод: GET /api/v1/calendar/promotions

Домен: dp-calendar-api.wildberries.ru

Частота: раз в день

Гранулярность: акция × период

ПолеПоказательПоле APIПримечание
Акция (название)П104nameСписок акций в заданном периоде

Назначение в РНП:

10. Номенклатуры в акции

Статус валидации:

Источник: WB Promotion

Метод: GET /api/v1/calendar/promotions/nomenclatures

Домен: dp-calendar-api.wildberries.ru

Частота: раз в день

Гранулярность: promotionID × nmID

ПолеПоказательПоле APIПримечание
Статус участия в акцииП104inActionУчаствует ли конкретный nmID в акции
Текущая цена в акцииП104priceДля UI и проверки write-back
Плановая цена акцииП104planPriceПредложение WB по цене
Текущая скидкаП104discountТекущая скидка в акции
Плановая скидка акцииП104planDiscountПредложение WB по скидке

Правило использования:

Ограничение WB:

11. Продажи по регионам

Статус валидации:

Источник: WB Seller Analytics

Метод: GET /api/v1/analytics/region-sale

Домен: seller-analytics-api.wildberries.ru

Частота: не зафиксирована в workbook

ПолеПоказательПоле API
Продажи по регионам / ЦФОП108saleItemInvoiceQty

12. Штрафы

Статус валидации:

Источник: WB Reports

Точка входа в workbook: getMeasurementPenalties

ПолеПоказательПримечание
ШтрафыП103В workbook указано, что одного метода недостаточно: нужно суммировать ещё 4 метода из этого же раздела

Зафиксированный состав ETL:

Правило агрегации по умолчанию:

Проверено живым API:

13. Элементы вне текущего API-контракта

Это строки из вкладки АПИ, которые пока не образуют готовый ETL-контур.

ПоказательПричина
ДатаЭто системная дата, не API
СсылкаВ workbook прямо указано: нет в API, расчёт через артикул
Заказали штВ рамках текущего проекта источник зафиксирован как внешний парсер другой команды
Заказали на сумму рубВ рамках текущего проекта источник зафиксирован как внешний парсер другой команды
Выкупили штВ рамках текущего проекта источник зафиксирован как внешний парсер другой команды
Выкупили на сумму рубВ рамках текущего проекта источник зафиксирован как внешний парсер другой команды
Цена минус СППРасчётный показатель
Комиссия ВБ, %Источник — 1С Нормативы для расчета планов, не WB API

Сводка по контурам ETL

КонтурИсточникМетодЧастота
Sales Funnel v3Seller Analytics/api/analytics/v3/sales-funnel/productsраз в день
Seller InfoAPI Information/api/v1/seller-infoпри полной загрузке / новый токен ✅ ➕
Stocks productsSeller Analytics/api/v2/stocks-report/products/productsраз в день
Stocks wb-warehousesSeller Analytics/api/analytics/v1/stocks-report/wb-warehousesраз в день
Stocks officesSeller Analytics/api/v2/stocks-report/officesраз в день
Content cardsContent API/content/v2/get/cards/listраз в день ⚠️
Adv financeПродвижение/adv/v1/updраз в день
Adv fullstatsПродвижение/adv/v3/fullstatsраз в день
Promotions calendarPromotion/api/v1/calendar/promotionsраз в день
Promotions nomenclaturesPromotion/api/v1/calendar/promotions/nomenclaturesраз в день
Supplier ordersStatistics API/api/v1/supplier/ordersуточнить
Region saleSeller Analytics/api/v1/analytics/region-saleуточнить
Penalties blockReportsнесколько методовуточнить

Требования к данным из парсинга и скрапинга

Всё что нам нужно получать не через официальные API, а через парсинг / скрапинг.

Документ — основа для постановки задач по non-API интеграциям для РНП.

Часть этих данных будет поступать не из нашей реализации, а из готового скрапера / парсеров другой команды.

Канал передачи для всех блоков: Внешний скрапер / парсер другой команды → наш ETL → DWH.

Принципы

1. Показы и воронка продаж (история)

Источник: парсинг WB Seller (неофициальный endpoint)

Причина: поле "Показы" отсутствует в официальном WB OpenAPI; данные берутся из внутреннего аналитического endpoint'а WB Seller

1.1 Показы (П11) и полная воронка

Метод: POST https://seller-content.wildberries.ru/ns/analytics-api/content-analytics/api/v1/sales-funnel/report/product/history

Частота: раз в день (забираем сегодня + вчера; вчера — финальные данные, сегодня — меняются в течение дня)

Гранулярность: nmID × день

Тело запроса:

{
  "nmID": 820630478,
  "currentPeriod": {
    "start": "2026-04-05",
    "end": "2026-04-11"
  }
}

Ключевые поля ответа (data[].*):

ПолеПоказательПримечание
dateП1Дата отчёта
viewCount.currentП11Показы — база для CTR и воронки
openCardCount.currentП9Перешли в карточку
addToCartCount.currentП10Положили в корзину
addToWishlistCount.currentП13Добавили в отложенные
viewToOpenConversion.currentCTR переход в карточку, %
openToCartConversion.currentКонверсия корзина, %
cartToOrderConversion.currentКонверсия заказ, %
orderCount.currentП7Заказы, шт
orderSum.currentП8Заказы, руб
buyoutSum.currentП20Выкупы, руб
buyoutCount.currentП19Выкупы, шт
cancelSum.currentОтмены, руб
cancelCount.currentП17Отмены, шт
buyoutPercent.current% выкупа
wbClub.orderCount.currentП14Заказили WB Club, шт
wbClub.orderSum.currentЗаказили WB Club, руб
wbClub.buyoutSum.currentВыкупили WB Club, руб
wbClub.buyoutCount.currentП15Выкупили WB Club, шт
wbClub.cancelSum.currentОтмены WB Club, руб
wbClub.cancelCount.currentОтмены WB Club, шт
wbClub.buyoutPercent.current% выкупа WB Club

Стратегия сбора:

Авторизация:

Использование downstream:

2. СПП (Скидка постоянного покупателя)

Источник: парсинг WB Seller (неофициальный endpoint)

Причина: СПП отсутствует в официальном WB OpenAPI; данные берутся из внутреннего endpoint'а WB Discounts & Prices

2.1 СПП (П65)

Метод: POST https://discounts-prices.wildberries.ru/ns/dp-api/discounts-prices/suppliers/api/v1/list/goods/filter

Частота: раз в час

Гранулярность: nmID × timestamp

Тело запроса:

{
  "limit": 50,
  "offset": 0,
  "facets": [],
  "filterWithoutPrice": false,
  "filterWithLeftovers": false,
  "filterWithoutCompetitivePrice": false,
  "sort": "price",
  "sortOrder": 0
}

Ключевые поля ответа (data.listGoods[].*):

ПолеПоказательПримечание
nmIDП2Ключ связки с товаром
discountOnSiteП65СПП, % — значение в процентах
pricesМассив базовых цен (по размерам)
discountedPricesМассив цен со скидкой
clubDiscountedPricesМассив цен со скидкой WB Club
discountОбщая скидка, %
competitivePriceКонкурентная цена
promotions[]Список акций, в которых участвует товар

Стратегия сбора:

Авторизация:

Использование downstream:

3. Метрики заказов / выкупов (нишевые)

Источник: тот же endpoint, что и раздел 1 — парсинг WB Seller

Причина: эти показатели берутся из того же ответа /sales-funnel/report/product/history, что и Показы

ПолеПоказательКлюч в ответе
Заказали штП109orderCount.current
Заказали на сумму рубП110orderSum.current
Выкупили штП111buyoutCount.current
Выкупили на сумму рубП112buyoutSum.current

Примечание: отдельный запрос не нужен — данные приходят в том же ответе, что и Показы (раздел 1).

Отличие П109–П112 от П7, П8, П19, П20:

4. Индекс локализации (ИЛ) и КТР

Источник: парсинг WB Seller (неофициальные endpoint'ы)

Причина: ИЛ и КТР недоступны через официальный WB OpenAPI; данные берутся из внутренних аналитических endpoint'ов WB Seller

4.1 Индекс локализации (П138)

Метод: POST https://seller-content.wildberries.ru/ns/analytics-api/content-analytics/api/v1/localization/report-by-nm

Частота: раз в день

Гранулярность: nmID × день

Тело запроса:

{
  "nmIDs": [],
  "subjectID": 0,
  "brand": "",
  "tagID": 0,
  "start": "2026-04-05",
  "end": "2026-04-11",
  "limit": 50,
  "offset": 0,
  "orderBy": {"field": "nonLocalOrderCount", "mode": "desc"},
  "stockType": ""
}

Ключевые поля ответа (data[].*):

ПолеПоказательПримечание
nmIDП2Ключ связки с товаром
localOrderPercentП138Индекс локализации, %

4.2 КТР — Коэффициент территориального распределения (П139)

Метод: POST https://seller.wildberries.ru/ns/categories-info/suppliers-portal-analytics/api/v1/localization-list

Частота: раз в день

Гранулярность: справочник (обновляется раз в день)

Формат ответа (data.indexts[]):

{
  "index": 0.5,
  "left": 95,
  "right": 100,
  "pricePercent": 0
}

Правило расчёта П139:

Авторизация:

Сводка по контурам

КонтурИсточникЧастотаСтатус
Показы + воронка + нишевые метрикипарсинг WB Seller (/sales-funnel/report/product/history)раз в день (сегодня + вчера)обязательный
СППпарсинг WB Discounts & Prices (/list/goods/filter)раз в часобязательный
Индекс локализации (ИЛ)парсинг WB Seller (/localization/report-by-nm)раз в деньобязательный
КТРпарсинг WB Seller (/localization-list) + расчёт по диапазонураз в деньобязательный

РНП — Карта происхождения MVP-показателей

Единый source of truth по показателям РНП, которые реально входят в MVP по листу MVP пояснения из reference-upd.xlsx.

Документ отвечает на три вопроса:

Правила

Принятые оговорки

Статусы

1. WB API

ППоказательГде используетсяКак берёмСтатус
П1ДатаФильтрыДата ежедневного WB-снимка остатков; ось периода в витрине РНПfixed
П2Артикул WBФильтры, ПаспортWB daily product snapshot; в текущем API-контуре технически забираем через Sales Funnel v3, поле nmIdfixed
П3Артикул поставщикаФильтры, ПаспортWB daily product snapshot; в текущем API-контуре технически забираем через Sales Funnel v3, поле vendorCodefixed
П4Предмет / категория WBПаспортWB daily product snapshot; в текущем API-контуре технически забираем через Sales Funnel v3, поле subjectNamefixed
П5Юр лицоПаспортGET /api/v1/seller-info, поле tin; один токен WB = одно юр лицо, во все WB-данные прокидываем атрибут кабинета токенаfixed
П6БрендПаспортWB daily product snapshot; в текущем API-контуре технически забираем через Sales Funnel v3, поле brandNamefixed
П7Заказы, штИсторияPOST /api/analytics/v3/sales-funnel/products, поле orderCountfixed
П19Выкупы, штКороткий отчёт, АналитикаPOST /api/analytics/v3/sales-funnel/products, поле buyoutCountfixed
П20Выкупы, рубКороткий отчёт, АналитикаPOST /api/analytics/v3/sales-funnel/products, поле buyoutSumfixed
П21Расходы на рекламу, ₽ фактАналитика, ИсторияGET /adv/v1/upd, поле updSumfixed
П157Затраты на рекламную кампанию, ₽ фактАналитика, ИсторияАПИ ВБ. Продвижение, поле sum; по смыслу совпадает с П21 — фактические затраты на рекламуfixed
П33Остатки на текущий день, штИсторияPOST /api/v2/stocks-report/products/products, поле stockCountfixed
П40Рейтинг по отзывамПаспорт, ИсторияPOST /api/analytics/v3/sales-funnel/products, поле feedbackRatingfixed
П66% скидки фактИсторияGET /api/v1/supplier/orders, поле discountPercentfixed
П103ШтрафыАналитикаАгрегат по блоку retention reports WB; в «Требования к данным из API WB» зафиксировано суммирование денежных полей по 5 отчётамfixed
П104АкцияИсторияДвухшаговый WB promotion-контур: GET /api/v1/calendar/promotions для списка акций и GET /api/v1/calendar/promotions/nomenclatures для проверки участия конкретного nmID и параметров акцииfixed
П142Цена минус Club WBИсторияPOST /api/analytics/v3/sales-funnel/products, поле wbclub_avgPricefixed

2. 1С

ППоказательГде используетсяКак берёмСтатус
П44КоллекцияФильтры, Паспорт1С Воронка продаж; храним как SCD Type 2 по артикулу поставщика и периодуfixed
П45Заказано, штПаспорт1С Заказ поставщикуfixed
П46МенеджерФильтры1С Воронка продаж; храним как SCD Type 2 по артикулу поставщика и периодуfixed
П47ФабрикаПаспорт1С Справочник Номенклатураfixed
П48Материал верхаПаспорт1С Справочник Номенклатураfixed
П50Категория 1СФильтры, Паспорт1С Справочник Номенклатураfixed
П55Сезон продажФильтры, Паспорт1С Справочник Номенклатураfixed
П59ПовторПаспорт1С Справочник Номенклатураfixed
П62Себестоимость, рубПаспорт, История1С Приобретение товаров и услуг; появляется после фактического поступления товараfixed
П67Выручка планКороткий отчёт, Аналитика1С Планирование продажfixed
П68Цена план текущего месяцаАналитика, История1С Планирование продажfixed
П69% проданного планКороткий отчёт, Аналитика1С Планирование продажfixed
П71План штАналитика1С Планирование продажfixed
П72План заказы штИстория1С Планирование продажfixed
П77План ЧПКороткий отчёт, Аналитика1С Планирование продажfixed
П85Налоговая нагрузка, %История1С Нормативы для расчета плановfixed
П87Переменные расходы на ед.История1С Нормативы для расчета плановfixed
П88Постоянные расходы на ед.История1С Нормативы для расчета плановfixed
П90КурсИстория1С Справочник Сезон продажfixed
П91Себестоимость, юаниПаспорт, История1С Заказ поставщикуfixed
П102Расходы на рекламу, ₽ планАналитика, История1С Планирование продаж, поле Реклама внутренняя, рубfixed
П141Цена план следующего месяцаИстория1С Планирование продажfixed

3. Внешний скрапер / парсер другой команды

ППоказательГде используетсяКак берёмСтатус
П65СППИстория, зависимости для П64 и графика эластичностиЖдём готовую реализацию от другой команды; на нашей стороне только приём, ETL и хранение историиfixed

Связанные зависимости вне MVP-таблицы:

4. Расчётные показатели в DWH

4.1 Воронка, фильтры и операционные показатели

ППоказательГде используетсяКак считаемСтатус
П18CTR клик (по товару)АналитикаopenCount / Показы, где openCount приходит из Sales Funnel v3, а Показы — из внешнего скрапераfixed
П26% выкупа (по товару)АналитикаП19 / П7fixed
П37Остаток в путиИсторияП35 + П36 = В пути к клиенту + В пути от клиентаfixed
П79Факт % проданногоКороткий отчёт, АналитикаП19 / П45 (выкупы шт / заказано шт)fixed
П81Валовая рентабельность фактФильтры, ИсторияВаловая финансовая модель РНП; в фильтрах уже зафиксирована формула (Выручка - Себестоимость - Переменные расходы) / Выручкаfixed
П82ДРР фактАналитикаРасчётная метрика DWH на основе рекламных расходов факт и выручкиfixed
П84Все комиссииИсторияП20 * П83fixed
П89АутоффстокАналитика, ИсторияАлгоритм уже согласован; считаем в DWH по размерной горке артикулаfixed
П99ABCФильтры, АналитикаАлгоритм ABC уже согласован; считаем в DWH еженедельноfixed
П113Количество дней на сайтеФильтры, ПаспортСчитаем количество дат, в которые товар был в остатках, а не сегодня - дата первого появленияfixed
П134CTR клик (по коллекции)ИсторияПереходы по этой коллекции / Показы по этой коллекцииfixed
П135CTR корзинаАналитика, ИсторияКорзины по этой коллекции / Переходы по этой коллекцииfixed
П136CTR заказАналитика, ИсторияЗаказы по этой коллекции / Корзины по этой коллекцииfixed
П137% отгруженногоАналитикаП155 / П45fixed
П138Индекс локализацииАналитикаПарсинг POST /ns/analytics-api/content-analytics/api/v1/localization/report-by-nm, поле localOrderPercentfixed
П139КТРАналитикаПарсинг POST /ns/categories-info/suppliers-portal-analytics/api/v1/localization-list; index из записи где left <= П138 <= rightfixed
П150CTR клик рекламныйИсторияП147 / П146fixed
П153CPOИсторияП157 / П149fixed
П154% выкупа (по коллекции)ИсторияВыкупы по этой коллекции / Заказы по этой коллекцииfixed

4.2 План / факт, дельты и финансовые витринные метрики

ППоказательГде используетсяКак считаемСтатус
П42Цена фактАналитика, ИсторияП20 / П19fixed
П64Цена минус СППИсторияП42 * (1 - П65); если П65 = 33%, то цена 99 превращается в 66fixed
П80Валовая прибыль фактИсторияП20 - П63, где П63 = П62 * П19fixed
П95Чистая прибыль фактКороткий отчёт, АналитикаП80 - П84 - П86 - П87 - П88 - П21 по формуле workbookfixed
П96Рентабельность по ЧП фактАналитикаП95 / П20fixed
П115Выполнение плана выручкаКороткий отчёт, АналитикаП20 / П67, где П20 агрегируется по текущему фильтру / коллекцииfixed
П116Дельта выручкаКороткий отчёт, АналитикаП20 - П67fixed
П117Выполнение плана % проданногоКороткий отчёт, АналитикаП79 / П69fixed
П118Дельта % проданногоКороткий отчёт, АналитикаП79 - П69fixed
П119Выполнение плана чистая прибыльКороткий отчёт, АналитикаП95 / П77fixed
П120Дельта чистая прибыльКороткий отчёт, АналитикаП95 - П77fixed
П121% участия в акцияхКороткий отчёт(сумма заказов по товарам, участвовавшим хотя бы в одной акции) / (сумма всех заказов) * 100; для одной даты используем rolling окно 7 дней, для диапазона — выбранный период; менеджер считает по своим товарам, РОП — по товарам сотрудниковfixed
П122Мотивация менеджераКороткий отчётКвартальная метрика по всем коллекциям: K = 0.7 (П20 / П67) + 0.3 (П80 / П144); шкала бонуса 95% -> 50k, 100% -> 100k, 105% -> 150k; при перевыполнении > 5% добавляется ещё 50k. Отдельный бонус: 5% * (П157 - П102) при положительной разнице (экономия на рекламе)fixed
П123Выполнение плана количествоАналитикаП19 / П71fixed
П124Дельта количествоАналитикаП19 - П71fixed
П125Выполнение плана средний чекАналитикаП42 / П68fixed
П126Дельта средний чекАналитикаП42 - П68fixed
П127Выполнение плана рентабельность ЧП%АналитикаП96 / П140fixed
П128Дельта ЧП%АналитикаП96 - П140fixed
П129Выполнение плана по рекламеАналитикаП21 / П102fixed
П130Дельта рекламаАналитикаП21 - П102fixed
П131ДРР планАналитикаП102 / П67fixed
П132Выполнение плана ДРР%АналитикаП82 / П131fixed
П133Дельта ДРР%АналитикаП82 - П131fixed
П140ЧП% планАналитикаП77 / П67fixed
П144Валовая прибыль планИсторияП67 - П156fixed
П145Валовая рентабельность планИсторияП144 / П67fixed

5. Показатели вне текущего зафиксированного контура

ППоказательГде используетсяЧто зафиксировано сейчасСтатус
П29Плановая оборачиваемость 1ИсторияВынесено из текущего MVP; post-MVP направление — перенос в 1С с отдельной проработкой структуры храненияfuture
П30Плановая оборачиваемость 2ИсторияВынесено из текущего MVP; post-MVP направление — перенос в 1С с отдельной проработкой структуры храненияfuture
П114Достижение параметров оборачиваемостиФильтрыВынесено из текущего MVP; в РНП сейчас не показываем, вернёмся после появления устойчивого источника П29/П30future

6. Ненумерованные элементы MVP

Это важные элементы интерфейса РНП, которые присутствуют на листе MVP пояснения, но не имеют собственного номера показателя:

ЭлементГде используетсяИсточник / решение
Фото товараПаспорт, таблица РНПWB Content API, главное фото карточки
Дозаказ, штПаспорт1С Заказ поставщику; считаем как сумму количества по строкам документов с признаком дозаказ только по актуальному сезону / коллекции
Эластичность спросаПаспортГрафик строится на истории П7, П42, П65, П142
История изменений карточкиПаспортСобственный audit-log по дельтам ежедневных снимков карточки WB
Объединение / разъединение карточекПаспортWrite-back через WB API, отдельный функциональный контур
План действийИсторияРедактируемое текстовое поле внутри нашей системы
План отгрузкиИстория1С Приходный ордер + 4 дня
Выгрузка новой цены / скидкиИсторияWrite-back в WB API
Предложение WB по акцииИсторияWB promotion-контур: GET /api/v1/calendar/promotions + GET /api/v1/calendar/promotions/nomenclatures
Статус участия в акции / кнопка "Участвовать"ИсторияWrite-back в WB promotion-контур
Кол-во негативных отзывов / расчёт перекрытияИсторияОтдельная логика поверх отзывов; в текущем MVP не формализована в номерной метрике

Что смотреть дальше

Целевая модель данных

Целевое состояние данных для системы в целом:

Из этого документа сознательно исключены подвешенные блоки, вынесенные из текущего контура:

Рекомендация по хранению

Базовый вариант: PostgreSQL + ClickHouse.

Правила

1. PostgreSQL

Это сущности, которые лучше держать в PG, потому что они часто мутируют, требуют точечных update/delete, участвуют в auth/RBAC или являются operational state.

erDiagram
    PG_ROLES {
        string code PK
        string name
        boolean is_system
        datetime created_at
        datetime updated_at
    }

    PG_DEPARTMENTS {
        bigint id PK
        boolean active
        string name
        bigint head_user_id FK
        boolean is_default
        datetime created_at
        datetime updated_at
        datetime deleted_at
    }

    PG_USERS {
        bigint id PK
        string employee_guid_1c UK
        boolean active
        string lastname
        string firstname
        string middlename
        string full_name
        string email UK
        string password_hash
        datetime password_changed_at
        string role_code FK
        bigint department_id FK
        string employment_status
        boolean is_blocked
        datetime invited_at
        datetime last_login_at
        datetime created_at
        datetime updated_at
        datetime deleted_at
    }

    PG_USER_SESSIONS {
        string session_id PK
        bigint user_id FK
        string refresh_token_hash
        string ip
        string user_agent
        datetime expires_at
        datetime revoked_at
        datetime created_at
    }

    PG_PASSWORD_RESET_TOKENS {
        string token_id PK
        bigint user_id FK
        string token_hash
        datetime expires_at
        datetime used_at
        datetime created_at
    }

    PG_AUTH_LOGIN_ATTEMPTS {
        bigint id PK
        bigint user_id FK
        string email
        string ip
        string user_agent
        string outcome
        string failure_reason
        datetime created_at
    }

    PG_PASSWORD_RESET_REQUESTS {
        bigint id PK
        bigint user_id FK
        string email
        string ip
        string request_status
        datetime created_at
    }

    PG_CORE_SETTINGS {
        bigint id PK
        bigint default_department_id FK
        int password_reset_ttl_minutes
        int admin_audit_retention_days
        int monitoring_feed_depth_days
        bigint updated_by_user_id FK
        datetime updated_at
    }

    PG_DYNAMIC_SETTINGS {
        string key PK
        string value_type
        json value_json
        bigint updated_by_user_id FK
        datetime updated_at
    }

    PG_EXTERNAL_SERVICE_TOKENS {
        bigint id PK
        string service_code
        string label
        string secret_ref
        boolean is_active
        datetime rotated_at
        datetime created_at
        datetime updated_at
    }

    PG_WB_CABINETS {
        bigint id PK
        bigint external_service_token_id FK
        string seller_id
        string tin
        string name
        boolean is_active
        datetime synced_at
        datetime created_at
        datetime updated_at
    }

    PG_ADMIN_AUDIT_LOG {
        bigint id PK
        bigint actor_user_id FK
        string action_type
        string entity_type
        string entity_id
        json before_payload
        json after_payload
        datetime created_at
    }

    PG_WRITEBACK_JOBS {
        bigint id PK
        string job_type
        string target_system
        string status
        string idempotency_key
        string external_task_id
        bigint requested_by_user_id FK
        int retry_count
        datetime next_retry_at
        string error_code
        datetime locked_at
        string worker_id
        string resync_status
        json request_payload
        json response_payload
        datetime created_at
        datetime finished_at
    }

    PG_WRITEBACK_JOB_ITEMS {
        bigint id PK
        bigint job_id FK
        bigint nm_id
        bigint imt_id_before
        bigint imt_id_after
        string result_status
        string error_code
        string error_text
        string external_item_id
        string resync_status
        datetime created_at
    }

    PG_PRODUCT_ACTION_PLANS {
        bigint id PK
        bigint nm_id
        date plan_date
        bigint author_user_id FK
        text plan_text
        datetime created_at
        datetime updated_at
    }

    PG_ETL_PIPELINE_STATUS {
        bigint id PK
        string pipeline_code
        string last_status
        datetime last_started_at
        datetime last_finished_at
        int duration_sec
        datetime next_run_at
        datetime data_watermark_at
        int freshness_lag_minutes
        bigint processed_rows
        bigint rejected_rows
        bigint skipped_rows
        bigint duplicate_rows
        string error_message
        datetime updated_at
    }

    PG_SOURCE_SYNC_STATUS {
        bigint id PK
        string source_system
        string source_entity
        string sync_status
        datetime last_success_at
        datetime data_watermark_at
        int freshness_lag_minutes
        bigint processed_rows
        bigint rejected_rows
        bigint skipped_rows
        bigint duplicate_rows
        string error_message
        datetime updated_at
    }

    PG_INTEGRATION_INBOX {
        bigint id PK
        string source_system
        string event_type
        string entity_type
        string entity_key
        string processing_status
        json payload
        datetime event_time
        datetime processed_at
    }

    PG_INTEGRATION_FAILED_EVENTS {
        bigint id PK
        bigint inbox_event_id FK
        string source_system
        string event_type
        string entity_type
        string entity_key
        string failure_stage
        string error_code
        string error_text
        json payload
        datetime failed_at
    }

    PG_INTEGRATION_PIPELINE_RUNS {
        bigint id PK
        string pipeline_code
        string run_status
        int processed_events
        int failed_events
        string error_code
        string error_text
        datetime started_at
        datetime finished_at
    }

    PG_ROLES ||--o{ PG_USERS : grants
    PG_DEPARTMENTS ||--o{ PG_USERS : has_users
    PG_DEPARTMENTS ||--o{ PG_CORE_SETTINGS : default_for_new_users
    PG_USERS ||--o{ PG_USER_SESSIONS : owns
    PG_USERS ||--o{ PG_PASSWORD_RESET_TOKENS : receives
    PG_USERS ||--o{ PG_AUTH_LOGIN_ATTEMPTS : attempts
    PG_USERS ||--o{ PG_PASSWORD_RESET_REQUESTS : requests_reset
    PG_USERS ||--o{ PG_ADMIN_AUDIT_LOG : acts
    PG_USERS ||--o{ PG_WRITEBACK_JOBS : requests
    PG_WRITEBACK_JOBS ||--o{ PG_WRITEBACK_JOB_ITEMS : contains
    PG_USERS ||--o{ PG_PRODUCT_ACTION_PLANS : authors
    PG_USERS ||--o{ PG_CORE_SETTINGS : updates
    PG_USERS ||--o{ PG_DYNAMIC_SETTINGS : updates
    PG_EXTERNAL_SERVICE_TOKENS ||--o{ PG_WB_CABINETS : identifies

2. ClickHouse: master data и исторические измерения

Это слой исторических измерений и текущего аналитического контекста товара.

erDiagram
    CH_DIM_PRODUCT_SCD {
        bigint product_sk PK
        string product_bk
        string vendor_code
        bigint nm_id
        bigint imt_id
        string wb_seller_tin
        string wb_seller_name
        string brand_name
        string subject_name
        datetime wb_card_created_at
        datetime valid_from
        datetime valid_to
        boolean is_current
    }

    CH_DIM_PRODUCT_ATTR_SCD {
        bigint product_attr_sk PK
        string product_bk
        string vendor_code
        string category_1c
        string kind_1c
        string product_category
        string season_code
        string features
        string gender
        string country
        string direction
        string group_name
        string material_upper
        string material_lining
        string upper_color
        string color
        string factory
        boolean is_repeat
        datetime valid_from
        datetime valid_to
        boolean is_current
    }

    CH_DIM_PRODUCT_ASSIGNMENT_SCD {
        bigint assignment_sk PK
        string product_bk
        string vendor_code
        string collection_code
        string manager_guid_1c
        datetime valid_from
        datetime valid_to
        boolean is_current
    }

    CH_DIM_SEASON_RATE {
        bigint season_rate_sk PK
        string season_code
        decimal cny_rub_rate
        datetime valid_from
        datetime valid_to
        boolean is_current
    }

    CH_DIM_PLAN_NORMS_SCD {
        bigint plan_norm_sk PK
        string norm_scope_key
        decimal wb_commission_percent
        decimal tax_percent
        decimal variable_cost_per_unit
        decimal fixed_cost_per_unit
        datetime valid_from
        datetime valid_to
        boolean is_current
    }

    CH_DIM_WB_PROMOTIONS {
        bigint promotion_id PK
        string name
        datetime start_date
        datetime end_date
        datetime loaded_at
    }

    CH_DIM_PRODUCT_SCD ||--o{ CH_DIM_PRODUCT_ATTR_SCD : has_attrs_history
    CH_DIM_PRODUCT_SCD ||--o{ CH_DIM_PRODUCT_ASSIGNMENT_SCD : has_assignment_history

3. ClickHouse: raw facts from WB

erDiagram
    CH_FACT_WB_SALES_FUNNEL_DAILY {
        date snapshot_date
        string product_bk
        bigint nm_id
        string wb_seller_tin
        string vendor_code
        int open_count
        int cart_count
        int order_count
        decimal order_sum
        int cancel_count
        int buyout_count
        decimal buyout_sum
        decimal share_order_percent
        int add_to_wishlist
        int wbclub_order_count
        int wbclub_buyout_count
        int time_to_ready
        decimal product_rating
        decimal feedback_rating
        decimal wbclub_avg_price
        string ingest_batch_id
        string pipeline_run_id
        json source_meta_json
        datetime loaded_at
    }

    CH_FACT_WB_STOCK_PRODUCT_DAILY {
        date snapshot_date
        string product_bk
        bigint nm_id
        string wb_seller_tin
        int stock_count
        decimal stock_sum
        string ingest_batch_id
        string pipeline_run_id
        json source_meta_json
        datetime loaded_at
    }

    CH_FACT_WB_STOCK_OFFICE_DAILY {
        date snapshot_date
        string product_bk
        bigint nm_id
        string office_id
        string office_name
        string region_name
        int stock_count
        string ingest_batch_id
        string pipeline_run_id
        json source_meta_json
        datetime loaded_at
    }

    CH_FACT_WB_STOCK_SIZE_DAILY {
        date snapshot_date
        string product_bk
        bigint nm_id
        bigint chrt_id
        string sku
        string warehouse_id
        int quantity
        string ingest_batch_id
        string pipeline_run_id
        json source_meta_json
        datetime loaded_at
    }

    CH_FACT_WB_STOCK_TRANSIT_DAILY {
        date snapshot_date
        string product_bk
        bigint nm_id
        string wb_seller_tin
        int in_way_to_client
        int in_way_from_client
        string ingest_batch_id
        string pipeline_run_id
        json source_meta_json
        datetime loaded_at
    }

    CH_FACT_WB_CONTENT_SNAPSHOT_DAILY {
        date snapshot_date
        string product_bk
        bigint nm_id
        bigint imt_id
        string main_photo_url
        json photos_json
        json tags_json
        datetime wb_card_created_at
        string ingest_batch_id
        string pipeline_run_id
        json source_meta_json
        datetime loaded_at
    }

    CH_FACT_WB_ADV_UPDATES {
        datetime upd_time
        bigint advert_id
        string camp_name
        string payment_type
        int advert_type
        int advert_status
        int upd_num
        decimal upd_sum
        string currency
        string ingest_batch_id
        string pipeline_run_id
        json source_meta_json
        datetime loaded_at
    }

    CH_FACT_WB_ADV_FULLSTATS_NM_DAILY {
        date stat_date
        bigint advert_id
        int app_type
        string product_bk
        bigint nm_id
        int views
        int clicks
        int atbs
        int orders
        int canceled
        int shks
        decimal spend_sum
        decimal sum_price
        decimal cpc
        decimal ctr
        decimal cr
        string ingest_batch_id
        string pipeline_run_id
        json source_meta_json
        datetime loaded_at
    }

    CH_FACT_WB_PROMOTION_NM_DAILY {
        date snapshot_date
        bigint promotion_id
        string product_bk
        bigint nm_id
        boolean in_action
        decimal price
        decimal plan_price
        decimal discount
        decimal plan_discount
        string ingest_batch_id
        string pipeline_run_id
        json source_meta_json
        datetime loaded_at
    }

    CH_FACT_WB_SUPPLIER_ORDERS_RAW {
        date order_date
        string product_bk
        bigint nm_id
        string vendor_code
        decimal discount_percent
        string ingest_batch_id
        string pipeline_run_id
        json raw_payload
        json source_meta_json
        datetime loaded_at
    }

    CH_FACT_WB_REGION_SALE_DAILY {
        date snapshot_date
        string product_bk
        bigint nm_id
        string region_code
        decimal sale_item_invoice_qty
        string ingest_batch_id
        string pipeline_run_id
        json raw_payload
        json source_meta_json
        datetime loaded_at
    }

    CH_FACT_WB_PENALTY_RAW {
        string report_type
        date event_date
        string product_bk
        bigint nm_id
        decimal amount
        string ingest_batch_id
        string pipeline_run_id
        json raw_payload
        json source_meta_json
        datetime loaded_at
    }

    CH_EVENT_PRODUCT_CARD_CHANGE {
        bigint event_id PK
        string product_bk
        bigint nm_id
        string change_type
        json before_payload
        json after_payload
        string ingest_batch_id
        string pipeline_run_id
        json source_meta_json
        datetime detected_at
        string source
    }

    CH_FACT_WB_REVIEWS_DAILY {
        date snapshot_date
        string product_bk
        bigint nm_id
        decimal feedback_rating
        int negative_review_count
        int total_review_count
        int reviews_to_override
        string ingest_batch_id
        string pipeline_run_id
        json source_meta_json
        datetime loaded_at
    }

    CH_DIM_PRODUCT_SCD ||--o{ CH_FACT_WB_SALES_FUNNEL_DAILY : has_sales_funnel
    CH_DIM_PRODUCT_SCD ||--o{ CH_FACT_WB_STOCK_PRODUCT_DAILY : has_stock
    CH_DIM_PRODUCT_SCD ||--o{ CH_FACT_WB_STOCK_OFFICE_DAILY : has_office_stock
    CH_DIM_PRODUCT_SCD ||--o{ CH_FACT_WB_STOCK_SIZE_DAILY : has_size_stock
    CH_DIM_PRODUCT_SCD ||--o{ CH_FACT_WB_STOCK_TRANSIT_DAILY : has_transit
    CH_DIM_PRODUCT_SCD ||--o{ CH_FACT_WB_CONTENT_SNAPSHOT_DAILY : has_snapshots
    CH_DIM_PRODUCT_SCD ||--o{ CH_FACT_WB_ADV_FULLSTATS_NM_DAILY : has_ad_stats
    CH_DIM_WB_PROMOTIONS ||--o{ CH_FACT_WB_PROMOTION_NM_DAILY : contains
    CH_DIM_PRODUCT_SCD ||--o{ CH_FACT_WB_PROMOTION_NM_DAILY : participates
    CH_DIM_PRODUCT_SCD ||--o{ CH_FACT_WB_SUPPLIER_ORDERS_RAW : has_supplier_orders
    CH_DIM_PRODUCT_SCD ||--o{ CH_FACT_WB_REGION_SALE_DAILY : has_region_sales
    CH_DIM_PRODUCT_SCD ||--o{ CH_FACT_WB_PENALTY_RAW : has_penalties
    CH_DIM_PRODUCT_SCD ||--o{ CH_EVENT_PRODUCT_CARD_CHANGE : has_changes
    CH_DIM_PRODUCT_SCD ||--o{ CH_FACT_WB_REVIEWS_DAILY : has_reviews

4. ClickHouse: raw facts from 1С и внешних парсеров

erDiagram
    CH_FACT_1C_PURCHASE_ORDERS {
        string order_id_1c
        date order_date
        string product_bk
        string vendor_code
        string season_code
        boolean is_reorder
        int ordered_qty
        decimal cost_cny
        string ingest_batch_id
        string pipeline_run_id
        json source_meta_json
        datetime loaded_at
    }

    CH_FACT_1C_RECEIPTS {
        string receipt_id_1c
        date receipt_date
        string product_bk
        string vendor_code
        decimal unit_cost_rub
        string ingest_batch_id
        string pipeline_run_id
        json source_meta_json
        datetime loaded_at
    }

    CH_FACT_1C_SALES_PLAN_MONTHLY {
        date plan_month
        string product_bk
        string vendor_code
        decimal revenue_plan_rub
        int qty_plan
        decimal price_plan_current
        decimal price_plan_next
        decimal pct_sold_plan
        decimal pct_sold_plan_collection
        decimal profit_plan_rub
        decimal unit_cost_plan
        decimal cost_plan_total
        decimal ad_cost_plan_rub
        int orders_plan_qty
        int carts_plan_qty
        int opens_plan_qty
        int views_plan_qty
        decimal shipments_plan_rub
        decimal avg_order_price_plan
        string ingest_batch_id
        string pipeline_run_id
        json source_meta_json
        datetime loaded_at
    }

    CH_FACT_1C_SHIPMENTS {
        string shipment_id_1c
        date shipment_date
        string product_bk
        string vendor_code
        decimal shipped_amount_rub
        string ingest_batch_id
        string pipeline_run_id
        json source_meta_json
        datetime loaded_at
    }

    CH_FACT_1C_RECEIVING_ORDERS {
        string receiving_order_id_1c
        date posting_date
        string product_bk
        string vendor_code
        int qty_to_ship
        string ingest_batch_id
        string pipeline_run_id
        json source_meta_json
        datetime loaded_at
    }

    CH_FACT_SPP_HOURLY {
        datetime snapshot_ts
        string product_bk
        bigint nm_id
        decimal spp_percent
        string ingest_batch_id
        string pipeline_run_id
        json source_meta_json
        datetime loaded_at
    }

    CH_FACT_VIEWS_DAILY {
        date snapshot_date
        string product_bk
        bigint nm_id
        int views
        string ingest_batch_id
        string pipeline_run_id
        json source_meta_json
        datetime loaded_at
    }

    CH_DIM_PRODUCT_SCD ||--o{ CH_FACT_1C_PURCHASE_ORDERS : has_orders
    CH_DIM_PRODUCT_SCD ||--o{ CH_FACT_1C_RECEIPTS : has_receipts
    CH_DIM_PRODUCT_SCD ||--o{ CH_FACT_1C_SALES_PLAN_MONTHLY : has_plans
    CH_DIM_PRODUCT_SCD ||--o{ CH_FACT_1C_SHIPMENTS : has_shipments
    CH_DIM_PRODUCT_SCD ||--o{ CH_FACT_1C_RECEIVING_ORDERS : has_receiving_orders
    CH_DIM_PRODUCT_SCD ||--o{ CH_FACT_SPP_HOURLY : has_spp
    CH_DIM_PRODUCT_SCD ||--o{ CH_FACT_VIEWS_DAILY : has_views
    CH_DIM_SEASON_RATE ||--o{ CH_FACT_1C_SALES_PLAN_MONTHLY : uses_rate

5. ClickHouse: derived marts

erDiagram
    CH_MART_RNP_DAILY {
        date snapshot_date
        bigint nm_id
        string product_bk
        string vendor_code
        string collection_code
        string manager_guid_1c
        string wb_seller_tin
        decimal revenue_plan
        decimal revenue_fact
        int qty_plan
        int orders_plan
        decimal buyout_sum
        int buyout_count
        int order_count
        int stock_count
        int stock_in_transit
        decimal price_plan_current
        decimal price_plan_next
        decimal price_fact
        decimal price_minus_spp
        decimal discount_percent_fact
        decimal stock_sum
        decimal wbclub_price
        decimal rating_feedback
        decimal spp_percent
        int views
        decimal click_ctr
        decimal cart_cr
        decimal order_cr
        decimal buyout_pct
        decimal pct_sold_plan
        decimal pct_sold_fact
        decimal gross_profit_plan
        decimal gross_profit_fact
        decimal gross_margin_plan
        decimal gross_margin_fact
        decimal drr_fact
        decimal all_commissions_fact
        decimal fx_diff_fact
        decimal autoffstock_pct
        string abc_class
        decimal penalties_fact
        int days_on_site_count
        decimal localization_index
        decimal ktr_value
        boolean in_action
        string promotion_name
        decimal ad_spend_fact
        decimal ad_click_ctr
        decimal cpo
        decimal shipped_pct
        decimal net_profit_plan
        decimal net_profit_fact
        decimal net_margin_plan
        decimal net_margin_fact
        decimal promotion_participation_pct
        int negative_review_count
        int reviews_to_override
        json calc_payload
        datetime loaded_at
    }

    CH_MART_RNP_ROLLUP {
        string period_grain
        date period_start_date
        bigint nm_id
        string product_bk
        string vendor_code
        string collection_code
        string manager_guid_1c
        string wb_seller_tin
        decimal revenue_plan
        decimal revenue_fact
        decimal revenue_plan_pct
        decimal revenue_delta
        decimal pct_sold_plan
        decimal pct_sold_fact
        decimal pct_sold_plan_pct
        decimal pct_sold_delta
        decimal net_profit_plan
        decimal net_profit_fact
        decimal net_profit_plan_pct
        decimal net_profit_delta
        decimal qty_plan_pct
        decimal qty_delta
        decimal price_plan_pct
        decimal price_delta
        decimal net_margin_plan
        decimal net_margin_fact
        decimal net_margin_plan_pct
        decimal net_margin_delta
        decimal ad_spend_plan
        decimal ad_spend_fact
        decimal ad_spend_plan_pct
        decimal ad_spend_delta
        decimal drr_plan
        decimal drr_fact
        decimal drr_plan_pct
        decimal drr_delta
        decimal gross_profit_plan
        decimal gross_profit_fact
        decimal gross_margin_plan
        decimal gross_margin_fact
        decimal promotion_participation_pct
        decimal manager_bonus_amount
        decimal localization_index
        decimal ktr_value
        json aggregated_payload
        datetime loaded_at
    }

    CH_DIM_PRODUCT_SCD ||--o{ CH_MART_RNP_DAILY : denormalizes
    CH_DIM_PRODUCT_SCD ||--o{ CH_MART_RNP_ROLLUP : denormalizes
    CH_DIM_PRODUCT_ASSIGNMENT_SCD ||--o{ CH_MART_RNP_DAILY : scopes
    CH_DIM_PRODUCT_ASSIGNMENT_SCD ||--o{ CH_MART_RNP_ROLLUP : scopes

6. Cross-store связи

Это не физические FK между БД, а логические связи, которые надо держать в голове при проектировании ETL и приложения.

erDiagram
    PG_WB_CABINETS {
        bigint id PK
        string seller_id
        string tin
        string name
    }

    PG_USERS {
        bigint id PK
        string employee_guid_1c
        string full_name
        string role_code
        bigint department_id
    }

    CH_DIM_PRODUCT_SCD {
        bigint product_sk PK
        string product_bk
        string vendor_code
        bigint nm_id
        bigint imt_id
        string wb_seller_tin
    }

    CH_DIM_PRODUCT_ASSIGNMENT_SCD {
        bigint assignment_sk PK
        string product_bk
        string vendor_code
        string collection_code
        string manager_guid_1c
    }

    PG_WB_CABINETS ||--o{ CH_DIM_PRODUCT_SCD : scopes_by_tin
    PG_USERS ||--o{ CH_DIM_PRODUCT_ASSIGNMENT_SCD : manages_by_guid

Что точно лучше держать в PG

Что логично держать в CH

Словарь таблиц

Ниже короткое человеческое объяснение, что означает каждая таблица.

PostgreSQL

Справочник ролей RBAC. Нужен, чтобы явно хранить доступные роли системы: Менеджер, РОП, Админ, Супер-админ, ГД.

Справочник отделов. Хранит сами отделы, признак отдела по умолчанию и руководителя отдела. Если head_user_id заполнен, он должен указывать на пользователя из этого же отдела с ролью РОП.

Основная таблица пользователей приложения. Это не “исторический сотрудник”, а текущее состояние учётной записи: кто пользователь, активен ли он, заблокирован ли, в каком он отделе и какая у него роль.

Активные и завершённые пользовательские сессии. Нужна для logout, инвалидирования доступа и контроля активных логинов.

Одноразовые токены для восстановления пароля. Нужны только auth-слою.

Журнал попыток входа. Нужен для истории неуспешных логинов, расследования проблем авторизации и базовых anti-bruteforce правил.

Журнал запросов на восстановление пароля. Нужен для rate limit и контроля частоты reset-запросов по email / IP.

Typed-глобальные настройки системы, которые критичны для логики приложения. Здесь держим параметры вроде отдела по умолчанию, TTL reset-link и срока хранения аудита, чтобы не терять валидацию и ссылочную целостность.

Динамические key-value настройки, которые не требуют отдельных FK и строгой схемы. Это запасной контейнер для действительно гибких настроек, а не место для критичных параметров бизнес-логики.

Хранилище подключённых внешних токенов и ссылок на секреты. Здесь не аналитика, а operational-конфигурация интеграций.

Текущий реестр кабинетов WB, полученных через токены. Нужен, чтобы знать, какому юрлицу соответствует токен и какие данные пришли из какого кабинета.

Аудит административных действий. Хранит факт “кто что поменял” в users/departments/settings.

Верхнеуровневая сущность write-back операции. Одна запись = один запрос/операция в сторону WB, например merge/split или изменение параметров участия в акции. Помимо факта операции хранит operational-поля для реальной эксплуатации: идемпотентность, внешний task/request id WB, ретраи, блокировку воркером и статус post-writeback re-sync.

Детализация write-back job по карточкам. Нужна, когда одна операция затрагивает несколько nm_id. На этом уровне фиксируем per-item результат, внешний идентификатор WB при необходимости, код ошибки и статус re-sync.

Write-back state machine:

Правило: write-back и post-writeback re-sync считаем двумя разными state-машинами. У job может быть status = success, но resync_status = pending|running|failed, пока данные ещё не подтверждены обратной синхронизацией.

Редактируемый пользователем “план действий” по товару. Это не импорт из 1С и не аналитика, а внутреннее прикладное поле системы.

Кэш статусов пайплайнов для админского экрана мониторинга. Помимо статуса последнего запуска держим operational-показатели вроде watermark, freshness lag и количества обработанных / rejected / skipped / duplicate строк.

Сводное состояние по каждому источнику и сущности загрузки. Нужен, чтобы мониторинг показывал не только “последний DAG зелёный”, но и реальную свежесть данных по каждому source-слою отдельно.

Operational inbox для входящих интеграционных событий. Здесь живёт очередь на обработку и текущий processing state, но не долгоживущий аудит и не DLQ.

Отдельный слой failed / dead-letter событий. Нужен для расследований, повторной обработки и хранения ошибок без превращения inbox в помойку.

Журнал запусков интеграционных пайплайнов. Это не событие предметной области, а operational log конкретного прогона: когда стартовал, сколько обработал, сколько упало и с какой ошибкой завершился.

ClickHouse: dimensions и SCD

Главная историческая продуктовая размерность. Это точка, где стыкуются 1С и WB:

product_bk, vendor_code, nm_id, imt_id, юрлицо, базовые WB-атрибуты.

Канонический бизнес-ключ в аналитическом слое — product_bk = wb_seller_tin + vendor_code.

История справочных атрибутов товара из 1С: категория 1С, сезон, фабрика, материалы, повтор и т.д. Нужна, потому что атрибуты могут меняться во времени.

История назначения товара на коллекцию и менеджера. Критична для корректной аналитики по менеджерам за прошлые периоды.

История курса юань/руб по сезонам. Используется в расчётах и плановых моделях.

История нормативов для расчёта планов из 1С. Здесь лежат П83, П85, П87, П88. Держим отдельно от месячного плана продаж, потому что это другой источник и другой жизненный цикл. Business-grain нормативов подтверждён клиентом — norm_scope_key определяет scope норматива (категория/сезон/юрлицо/бренд/коллекция/тип товара или их комбинация).

Справочник акций WB. Хранит сами акции как отдельные сущности, а не участие товара в них.

ClickHouse: raw facts from WB

Основной ежедневный WB-факт по карточке товара: открытия, корзины, заказы, выкупы, рейтинги, WB Club и т.д. Это одна из самых важных fact-таблиц для РНП.

Ежедневные агрегированные остатки по товару. Нужна для П33, П34, П38, П113 и других derived-метрик.

Ежедневные остатки по офисам/складам WB. Это складской разрез, который нужен не для общего остатка, а для более детальной аналитики.

Ежедневные остатки по размеру и складу. Это слой, который нужен для расчёта П89 Аутоффсток и всех size-aware производных метрик.

Ежедневный факт по остаткам “в пути к клиенту / от клиента”.

Ежедневный снапшот состояния карточки WB: фото, теги, imt_id, дата создания карточки. Нужен и для UI, и для аудита изменений карточки.

История расходов на рекламу из GET /adv/v1/upd. Реальный grain по документации и live API: advert_id × upd_time. Здесь лежит cost-history кампании, а не товарный слой, и nm_id в этом факте нет.

Детальная статистика рекламы из GET /adv/v3/fullstats. Реальный raw-grain по документации и live API: advert_id × stat_date × app_type × nm_id. Именно здесь живут товарные views / clicks / atbs / orders и spend на уровне nm_id.

Ежедневное участие конкретного товара в конкретной акции WB. Нужна для П104, истории участия в акциях и фильтрации “акционный товар / неакционный”.

Raw-слой WB supplier/orders. Нужен в первую очередь для % скидки факт (П66) и как факт-источник для downstream-расчётов, где используется скидка WB.

Ежедневные продажи по регионам / ЦФО. Пока это узкоспециализированный слой для региональной аналитики.

Raw-удержания и штрафы WB. Здесь не итоговая метрика, а сырые строки из retention reports, из которых потом собирается П103.

События изменений карточки WB. Это уже не снапшот, а дельта: что изменилось между двумя снапшотами.

Ежедневные данные по отзывам: рейтинг, количество негативных отзывов, расчётное количество для перекрытия негатива. Источник — WB API (отзывы/рейтинги), агрегируется daily по nmID.

ClickHouse: raw facts from 1С

Raw-факт из заказов поставщику. Нужен для П45, П91, а также для расчёта Дозаказ, шт.

Raw-факт из документов прихода / приобретения. Это фактическая себестоимость в рублях и дата поступления.

Месячный плановый факт из 1С. Здесь лежат выручка план, цена план, реклама план, ЧП план и другие плановые величины.

Факт отгрузок из 1С. Нужен для П155 и связанных производных показателей.

Raw-факт из приходного ордера. Нужен для ненумерованного “плана отгрузки”: downstream считаем posting_date + 4 дня, само транзиентное поле отдельно не храним.

ClickHouse: external parser / scraper facts

История СПП из внешнего скрапера. Нужна для исторического анализа и расчёта цены для покупателя.

История показов из внешнего скрапера. Нужна для CTR и воронки, потому что в WB API “показы” в нужном смысле нет.

ClickHouse: marts

Главная ежедневная широкая витрина РНП. Именно из неё удобнее всего строить экран РНП, графики, daily drill-down и derived-метрики. В этой витрине держим текущие daily/history показатели и промежуточные расчётные поля вроде fx_diff_fact, если они нужны для формул верхнего уровня.

Ограниченный acceleration-layer поверх daily-витрины. Здесь держим только фиксированные предагрегации по понятным grain, например week и month, без универсального scope_key. Произвольные диапазоны и произвольные комбинации фильтров считаем из CH_MART_RNP_DAILY.

7. Покрытие текущих показателей РНП

Текущее правило простое:

Что это закрывает по текущему scope РНП:

Короткий словарь терминов

Короткие определения для терминов, которые регулярно встречаются в спеках РНП и обсуждениях с клиентом.

Ous

Что это: рабочее обозначение показателя Аутоффсток (П89).

Смысл: доля отсутствующих размеров относительно полной размерной горки артикула.

Пример: если у артикула должно быть 6 размеров, а в наличии есть 4, то Ous = 2 / 6 = 33%.

Где используется: «РНП — Аналитика товара», «РНП — История товара», «Карта происхождения MVP-показателей».

Что уже понятно: для расчёта нужен размерный разрез остатков. Источник размерных остатков — GET /api/v3/stocks (WB API), где есть chrtId, warehouseId, quantity.

ИЛ

Что это: Индекс локализации (П138).

Смысл: показатель WB, связанный с тем, насколько заказы локализуются относительно нужных складов / кластеров.

Где используется: «РНП — Аналитика товара», «Карта происхождения MVP-показателей».

Источник: парсинг POST /ns/analytics-api/content-analytics/api/v1/localization/report-by-nm (seller-content.wildberries.ru), поле localOrderPercent по nmID.

Частота: раз в день.

КТР

Что это: Коэффициент территориального распределения (П139).

Смысл: показатель из методики WB по локализации, который используется в расчёте ИЛ.

Где используется: «РНП — Аналитика товара», «Карта происхождения MVP-показателей».

Источник: парсинг POST /ns/categories-info/suppliers-portal-analytics/api/v1/localization-list (seller.wildberries.ru).

Правило расчёта: берём localOrderPercent (П138) для nmID, находим запись в indexts[], где left <= localOrderPercent <= right (включительно), значение index = КТР.

Частота: раз в день.

СПП

Что это: Скидка постоянного покупателя (П65).

Смысл: скидка покупателя, которая влияет на фактическую цену для покупателя.

Где используется: «РНП — История товара», «РНП — Паспорт товара», «Требования к данным из парсинга и скрапинга», «Карта происхождения MVP-показателей».

Источник: парсинг POST /ns/dp-api/discounts-prices/suppliers/api/v1/list/goods/filter (discounts-prices.wildberries.ru), поле discountOnSite.

Частота: раз в час.

Связанная формула: П64 = П42 * (1 - П65).

Макеты интерфейса

Набор визуальных макетов интерфейса (схематичный «каркас» приложения с низкой детализацией) собран в едином документе: макеты интерфейса (PDF).

Содержит макеты разделов: