# Сопоставление каталога: инструкция к таблицам

Версия 1.0, 31 октября 2026 года. Это рабочий журнал подготовки данных. Он не изменяет карточки, остатки или заказы в учётной системе и не является файлом массового импорта Skirbo либо маркетплейса.

## Файлы

| Таблица | Пустой файл | Учебный пример |
|---|---|---|
| Соответствия внешних вариантов складским позициям | m10-mapping-template.csv | m10-mapping-example.csv |
| Очередь неоднозначностей и решений | m10-ambiguities-template.csv | m10-ambiguities-example.csv |
| История изменения соответствий | m10-history-template.csv | m10-history-example.csv |

Все числа, товары, владельцы, ссылки на выгрузки и имена ролей в примерах вымышлены. Учебные коды не предназначены для печати этикеток и рабочих API; их регистрация в GS1 не проверяется. Файлы источников с названиями вроде `wb-a-20261031.csv#row=2` показывают способ указать происхождение, а не предоставляют реальные выгрузки. Значение `DEMO-MAPPING-V1-FULL-NOT-PROVIDED` — ориентир для ссылки на полный предыдущий mapping; такого файла в примере нет.

CSV: UTF-8 с BOM, разделитель запятая, каждое поле заключено в двойные кавычки. Внутри `barcodes_raw` коды разделены точкой с запятой; такой способ подходит к выбранным учебным кодам без этого символа. Если источник допускает разделитель внутри кода, храните дополнительные коды отдельной связанной таблицей.

## Импорт без потери идентификаторов

В Excel импортируйте через «Данные → Из текста/CSV», выберите UTF-8 и запятую. До загрузки задайте **Текст** для всех ID, артикулов, штрихкодов, версий, временных меток и ссылок. `units_per_pack` при необходимости переведите в целое число. Сначала проверьте, что `0012` осталось `0012`, а `12` осталось `12`. Ведущие нули нельзя восстанавливать догадкой после преобразования в число. Обычный двойной щелчок по CSV может применить автоматические преобразования; даже кавычки не задают тип ячейки.

Основание: [Microsoft — импорт текстовых и CSV-файлов](https://support.microsoft.com/en-us/excel/get-started/import-or-export-text-txt-or-csv-files), проверено 31.10.2026. Имена команд зависят от редакции Excel. После импорта сохраните рабочую книгу, исходные выгрузки оставьте неизменными.

## Таблица соответствий

Одна строка — один внешний вариант товара в одном кабинете/источнике. Если источник не ведёт отдельные варианты и каждая позиция уже самостоятельна, строка описывает эту позицию. Составной ключ связи: **`source + account_id + key_kind + key_value`**, четыре отдельных значения. Один и тот же ключ не должен иметь два одновременно действующих назначения. Несколько внешних строк могут ссылаться на один `master_sku_id`, если подтверждены владелец, вариант и единица.

При наличии уровня вариантов `key_kind=variant_id`, `key_value=source_variant_id`. Если такого уровня у источника нет, `key_kind=product_id`, `key_value=source_product_id`. Это выбор по устройству источника, а не разрешение подставить родительскую карточку при неполной выгрузке. Если обязательный ID варианта не получен или оба ID отсутствуют, строка остаётся `review`; пустые ключи не сравнивают как равные. Тип ключа сохраняют даже при одинаковых значениях: `variant_id:42` и `product_id:42` различаются.

| Поле | Что записать |
|---|---|
| mapping_id | Собственный неизменный ID связи, например MAP-001 |
| source, account_id | Площадка или система и точный кабинет; не название магазина по памяти |
| owner_id | Кто владеет товаром; не подменять оператором склада |
| source_product_id, source_variant_id | Исходные ключи карточки и варианта, без переименования значений: в примере WB — nmID/chrtID, Ozon — product_id/sku; для системы без вариантов второй столбец пустой |
| key_kind, key_value | Тип и исходное значение выбранного ключа. `variant_id` с ID варианта либо `product_id` с ID позиции для источника без уровня вариантов. Оба поля — текст |
| seller_sku_raw, barcodes_raw, barcode_kind | Артикул и коды в исходном виде; происхождение кода отдельно от его внешнего сходства с GTIN |
| model, variant | Модель и значимые отличия: размер, цвет, объём, исполнение |
| unit, units_per_pack | В чём продаётся позиция и сколько штук в упаковке; это описание, не автоматическая формула остатков |
| master_sku_id | Принятый внутренний ID складской позиции; пусто, пока соответствие не принято |
| mapping_version | Версия согласованного набора соответствий |
| valid_from, valid_to | Интервал действия связи; ISO 8601 с часовым поясом. Для текущей связи valid_to пусто; спорная связь не становится действующей по одной дате |
| status | approved — принято; review — нужен разбор; rejected — отклонено; retired — историческая связь |
| decision_basis, approved_by | Чем подтверждено и кто принял решение; должности достаточно в учебном файле |
| source_snapshot | Имя неизменённого файла/среза, дата и номер строки; для рабочего файла храните также контрольную сумму среза |
| note | Ограничение, связанная неоднозначность, исключение |

Пустое поле не означает ноль, другой вариант или отсутствие владельца. Отсутствующий обязательный признак означает `review`.

## Очередь и история

В очереди `issue_id` связывает спор с `mapping_ids`. Запишите противоречие, недостающий документ, действие до решения, результат, принятый SKU, проверившего и время. **`assignee` — исполнитель следующего действия; он обязателен для открытого спора.** Это отдельное поле от `reviewer`, который подтверждает принятое решение. Для открытого спора оставьте `decision`, `resolved_master_sku_id`, `reviewer`, `decided_at` пустыми, `status=open`. После решения исполнителя можно сохранить как часть истории ответственности. Решение о разделении владельцев — полноценный результат, а не повод объединять остатки.

В истории каждая строка — изменение одного поля связи: `previous_version`, `new_version`, `previous_mapping_snapshot`, `field`, `old_value`, `new_value`, `effective_at`, `reason`, `approved_by`, `evidence_ref`, `affected_orders_check`. **Это выборка изменений, а не полный журнал восстановления.** Например, CHG-002 не описывает все прежние статусы и интервалы действия строки.

До каждого пакета изменений обязательно сохраняйте полный предыдущий mapping со всеми строками, статусами, ключами и интервалами действия. Архив должен быть неизменяемым; сохраните его контрольную сумму. В `previous_mapping_snapshot` укажите доступную проверяющему ссылку на полный файл и его идентифицирующую версию. Если ссылка находится в реестре архивов, рядом должен быть адрес именно этой записи. Проверяющий должен открыть файл и сверить версию и контрольную сумму, а не только увидеть непустое поле. Учебное значение с `NOT-PROVIDED` не проходит эту проверку; предыдущая полная версия в данном примере отсутствует, её восстановимость не заявляется.

Не переписывайте старую строку истории. Исправление ошибки в истории оформляйте следующей записью. Проверка затронутых заказов должна содержать итог и ссылку на журнал, а не только слово «проверено».

## Порядок работы

1. Сохраните исходные выгрузки и список их дат. Выберите одну ограниченную товарную группу.
2. Заполните таблицу соответствий, сохранив исходные строки. Не заменяйте `0012` на `12`, кириллицу на латиницу, пустой размер на «единый».
3. Проверьте владельца, вариант и упаковку. Отсутствие конфликтов названия недостаточно.
4. Неоднозначные строки отправьте в очередь. Исключите их из нового общего сопоставления; открытые обязательства по таким позициям разберите отдельно.
5. Сохраните полный предыдущий mapping в архив и сверьте его контрольную сумму. После решения заполните основание и проверившего, задайте новую версию и время действия; изменение старой связи внесите в историю со ссылкой на архив.
6. Сверьте число исходных вариантов: каждый должен иметь принятое соответствие либо явное исключение. Сравните количества по владельцам и единицам — одно сопоставление не меняет физический запас.
7. Проверьте обычный импорт, повтор, смену кода, похожий размер, второго владельца и существующий заказ. Только после результата расширяйте выбранную группу.

В примере семь внешних строк: пять `approved`, две `review`. Три принятые строки относятся к одному складскому SKU владельца A. У двух ERP-позиций нет отдельного ID варианта, но есть разные ключи `product_id:000012` и `product_id:000013`; артикулы `12` и `0012` сохранены отдельно. Размер L и артикул без установленного варианта остаются спорными; исполнители следующих действий назначены. `CHG-002` показывает остановленную ошибочную связь: проверка старых обязательств по ней ещё не выполнена, а полный предыдущий mapping в примере не предоставлен. Поэтому пример не является принятым каталогом для запуска и не доказывает возможность полного восстановления предыдущей версии.
