catalog-data
Данные каталога — SQLite, поиск по названию, мягкое удаление, миграции, заливка каталога из выгрузки товароучёта. Использовать при правке моделей, репозиториев и импорта товаров.
SKILL.md.claude/skills/catalog-data/SKILL.md
GitHubДанные каталога
- Поиск товаров по названию фильтруется в Python, а не в SQL:
LIKEв SQLite не понимает регистра кириллицы. - Товары удаляются мягко (
active = 0) — на них ссылается журнал операций. - Миграций пока нет, схема создаётся через
create_all. При первом изменении моделей на устройстве с данными — вводить Alembic. - В БД от снимка хранится только имя файла (поле
image); сами файлы, их привязка к товарам и подготовка к экрану — в скиллеproduct-photos. - Каталог заливается из выгрузки товароучёта
docs/prod.xlsxскриптомbackend/tools/import_products.py. Выгрузка лежит вdocs/, а не рядом со снимками: всё, что попадает вfrontend/public/products, уезжает в сборку и раздаётся прибором, а список артикулов с наименованиями там ни к чему. Скрипт: артикул становится кодом товара, единица измерения читается из названия («… кг» весовой, «… шт» и «… 200гр» штучные), снимок находится по тому же артикулу. Цены и группы в выгрузке нет — ключ--random-pricesставит заглушку там, где цены ещё нет, а--groups=раскладывает группы по первому слову названия. Без--applyскрипт только показывает план.
Приём каталога из 1С
- Приёмник —
backend/app/api/import_1c.py,POST /api/catalog/1c-import. Формат диктует обработка 1Сintegrations/1c/original-Libra.bsl, которая уже работает у заказчика и не правится без явной просьбы: заголовокX-API-Key, код товара в полеarticle, проверка связи поGET /health. Что она шлёт и что мы отвечаем —integrations/1c/README.md; менять контракт можно только с обеих сторон разом. - Артикул из 1С и есть
plu: покупатель набирает его на весах, он же пять цифр в штрихкоде. Позиция без числового артикула или длиннее пяти цифр не роняет пакет 422 — в схемеpluнеобязателен, а диапазон проверяет приёмник и кладёт позицию вerrors[]ответа, чтобы 1С показала её в своём логе. - Синхронизация полная: чего нет в пакете, то гасится. Поэтому пустой пакет и пакет
без единого пригодного артикула отклоняются (400) — сбой выгрузки не должен
гасить каталог. После приёма —
live.notify("catalog"), киоск перерисовывается. - 1С ходит на весы снаружи (сервер 1С только по RDP) через Cloudflare Tunnel с
прибора — поэтому приём без токена закрыт (503),
tools/dev.pyслушает0.0.0.0, а туннель и адреса описаны вdocs/deploy.md(скиллdeployment). - Групп как таблицы нет: они собираются из поля
categoryтоваров. Своего у группы две вещи, обе вcategory_covers: обложка (скиллproduct-photos) и место в порядке (sort_order, скиллkiosk-catalog). - Колонку к существующей таблице
create_allне добавляет, а базу прибора пересоздавать нельзя — в ней каталог и журнал. Для таких правок вdb.pyесть список_ADDED_COLUMNSиALTER TABLEна старте; когда их станет больше единиц — Alembic. - Та же чистка есть в админке («Товари» → «Очистити дані»,
POST /api/catalog/purge) тремя областями: журнал с растрами, скрытые товары, весь каталог. Журнал удаляется вместе с товарами, а не остаётся висеть: его записи ссылаются на товар поid. Снимки чистятся только приборные (data/photos) — демо-набор из сборки фронта не трогаем, он часть образа. Обложки групп чистка не трогает вовсе: их подбирают руками по одной, а группа с тем же именем придёт из 1С снова, и обложка встанет на место. После чистки —live.notify("catalog"). - Перед сдачей прибора —
tools/clean_db.py --apply: журнал операций, растры этикеток, товары сactive = 0(журнал пуст, держать их незачем) и снимки без товара вdata/photos; каталог и живые снимки остаются. Без--apply— план. - Под проверку выгрузки из 1С рабочие данные разработки убираются в мок:
tools/mock_data.py stashпереносит базу и снимки вbackend/data/mock/(гитигнор),restoreвозвращает; оба — при остановленном бэкенде (SQLite занят). Чтобы пустая база не засеялась демо, вbackend/.envставитсяS2L_SEED_DEMO=0. Осторожно сuvicorn --reloadна Windows: после убийства родителя дочерний процесс-воркер живёт дальше и держитs2l.db— искать по--multiprocessing-fork.