Для полной заливки каталога МойСклада в «Демо-магазин» на стейдже переделал импорт по требованию «идемпотентный + без дублей». Схема: - 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>
37 lines
2.4 KiB
Markdown
37 lines
2.4 KiB
Markdown
# 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
|
||
новых.
|
||
|
||
## Протокол выполнения
|
||
|
||
(заполняется построчно)
|