food-market/docs/catalog-import-progress.md
nns 864d492c93 feat(s32): MoySklad-импорт — upsert по external id, merge по barcode, skip archived, UOM-mapping
Для полной заливки каталога МойСклада в «Демо-магазин» на стейдже
переделал импорт по требованию «идемпотентный + без дублей».

Схема:
- 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>
2026-10-04 23:22:14 +05:00

37 lines
2.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 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
новых.
## Протокол выполнения
(заполняется построчно)