Для полной заливки каталога МойСклада в «Демо-магазин» на стейдже переделал импорт по требованию «идемпотентный + без дублей». Схема: - Phase32a_MoySkladExternalId: VARCHAR(64) на products и product_groups + partial-unique index (OrgId, MoySkladExternalId) WHERE IS NOT NULL. NULL разрешён — товары, созданные вручную, без MS id. Клиент (MoySkladClient): - Auto-detect Basic vs Bearer: МойСклад принимает оба, но сторонние проекты (sklad на prod-vm) используют Base64(login:password). Строку распознаём как base64 с ':' в декоде → ставим Basic, иначе Bearer. - StreamProductsAsync принимает includeArchived (default true для back-compat; импортный путь передаёт false). - GetAllUomsAsync — грузит справочник единиц измерения один раз. Сервис (MoySkladImportService): - MoySkladImportOptions: OverwriteExisting / SkipArchived / MergeByBarcode. - Resolution order: MS id → barcode → article. Первый найденный апдейтится, не плодит дубль. - Группы — upsert по MS id; pre-существующие группы без MS id с тем же именем в том же родителе — подхватываются (MS id проставляется). - Товары из архива MoySklad (archived=true) полностью пропускаются (счётчик SkippedArchivedInSource в результате). - Barcode-дубли внутри MoySklad: первый встреченный выигрывает, остальные пропускаются с записью в Errors (счётчик SkippedDuplicateBarcodeInSource). - UOM: MS uom.id → MS uom.code → наш локальный Code. Весовые товары (weighed=true) всегда ставятся в «кг». - Расширенный MoySkladImportResult: Created / MergedByBarcode / SkippedArchivedInSource / SkippedDuplicateBarcodeInSource / GroupsUpdated. Контроллер (MoySkladImportController): - ImportRequest получает SkipArchived (default true), MergeByBarcode (default true). Токен по-прежнему принимается в body и НЕ сохраняется в Organizations.MoySkladToken, если передан в теле запроса. - Финальный Message прогресса собирает все счётчики. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2.4 KiB
2.4 KiB
Catalog import МойСклад → «Демо-магазин» (stage)
Решение владельца. Стенд закрыт basic-auth'ом на gateway от интернета (внутренняя сеть 192.168.1.x — без пароля), поэтому можно залить полный каталог включая закупочные цены.
Токен МойСклада. /var/www/sklad/appsettings.Production.json,
ключ MoySklad:Token, забирается через ssh + sudo на prod-vm. В
логи / коммиты / docs / отчёты токен никогда не попадает.
Передаётся только через env-переменную или stdin.
Границы. Не трогаем проект sklad, прод admin.food-market.kz,
global.json, deploy/*/nginx.
Чек-лист
- 1. Аудит текущего MoySklad-импорта + добор недостающих полей для «полной карточки» (товары, группы, ед. изм., штрихкоды, цены продажи/закупки, весовой признак, мин. остаток, артикул, фото) — сверка полей против API МойСклад 1.2.
- 2. Импорт в «Демо-магазин» на стейдже без дублей: upsert по внешнему id МойСклада; merge по штрихкоду; дубли штрихкодов в самом МойСкладе — первый пропускаем в отчёт; группы — тоже без дублей; архивные товары МойСклада не льём.
- 3. Токен у организации стенда после импорта удалить (или импорт без сохранения токена — тоже ок).
- 4. Отчёт: группы/товары created/updated/merged/skipped + выборочная сверка 10 карточек с МойСкладом.
- 5. Playwright-проверка каталога Демо-магазина изнутри сети: открывается, поиск по названию и штрихкоду работает, карточка показывает поля простого режима; повторный запуск импорта → 0 новых.
Протокол выполнения
(заполняется построчно)