1. Маска телефона: префикс «+7 », оператор не подставляется заранее.
Нормализация снимает ведущую «8» и код страны «7» (на 11 цифрах),
value хранится каноническим «+7»+national и восстанавливается снятием
литерального «+7» (без 8/11-эвристик) — ввод больше не «скачет».
Обе копии (public + admin). Проверено на всех вариантах + вставка.
2. Тариф и бесплатный период: Organization.Plan/FreeTrialEndsAt +
конфигурация «Бизнес» (Phase50, существующие → «start», дата NULL).
Signup сохраняет план и 90 дней; показ в кабинете владельца и в
карточке/списке суперадмина. Биллинга/блокировки нет.
3. Ошибки формы: переход к первому полю с ошибкой + фокус; единые
сообщения «Укажите email/телефон/название магазина», «Придумайте пароль».
4. «Первые шаги»: кнопка «Скрыть» (возврат из настроек организации);
шаг каталога показывает статус копии реестра («загружается…» /
«Каталог готов: N товаров — проверьте продажные цены»); ссылка на
Forgejo заменена на «Базу знаний».
5. «Новые функции»: не считаем изменения до даты регистрации орг
(новой орг баннер скрыт) + русская плюрализация улучшений/исправлений.
6. Карточка товара: «Закупочная цена» видна и в простом режиме (настройка
ShowReferencePriceOnProduct), подпись настройки приведена к новой схеме.
7. Копия реестра: первый штрихкод помечается «Основным»; бэкфилл уже
скопированных товаров без основного (Phase51).
Тесты: PlanSignupTests (3), RegistryCopyPrimaryBarcodeTests (1),
MarkupToggleTests (3, регрессия) — зелёные. Phone-нормализация покрыта
симуляцией ввода/вставки.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Список штрихкодов, стоящих в МойСклад более чем на одном товаре (barcode,
число товаров, наименования, артикулы). 46 штрихкодов на ≥2 товарах (один — на
трёх), что соответствует SkippedDuplicateBarcode=47 при наполнении реестра.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Настройка организации RecalcRetailOnSupplyByGroupMarkup (по умолчанию ВЫКЛ,
миграция Phase49 для всех существующих орг тоже ВЫКЛ). При ВЫКЛ проведение
приёмки меняет продажную цену ТОЛЬКО если она задана вручную в строке; наценка
группы не применяется. При ВКЛ — прежнее поведение (продажная = себестоимость +
наценка группы, округление вверх). Ручная кнопка «Пересчитать» и наценка группы
остаются. Настройка — в разделе товаров/цен настроек магазина.
Побочно исправлен мультитенантный баг: SuppliesController.Post читал флаги
(AllowFractionalPrices и новый) через `_db.Organizations...FirstOrDefaultAsync`
без скоупа — таблица organizations не tenant-фильтруется, возвращалась
произвольная орг. Теперь берём флаги у организации самой приёмки.
Тесты MarkupToggleTests: ВЫКЛ (наценка есть, приёмка проведена → продажная не
изменилась), ВКЛ (пересчиталась), ручная цена в строке работает в обоих режимах
— 3/3; SupplyPricingSchemeTests 3/3.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
РЕЕСТР ТОВАРОВ (глобальный системный шаблон карточек):
- Домен ProductRegistry{Group,Card,Barcode} (Entity, без OrganizationId),
миграция Phase47; штрихкод уникален в реестре (ключ новизны).
- Наполнение «из МойСклад заново» (команда суперадмина, повторяемая): читает
entity/product (архивные/модификации/комплекты/услуги — считает и пропускает),
группы из productFolder (путь), штрихкоды всех типов; buyPrice→закупочная+
себестоимость, salePrices→продажная; пересоздаёт только MoySklad-карточки,
Shop-карточки не трогает. МойСклад только чтение (пагинация 1000, 429-бэкофф).
- Фоновое пополнение из каталогов магазинов-участников (recurring, флаг в
PlatformSettings, по умолчанию ВЫКЛ): новые штрихкоды → карточки; фильтр
мусора (неверная контр. цифра EAN-13/8, пустое имя); существующие не трогает.
- Копия реестра в каталог нового магазина при регистрации — фоновым заданием
(Hangfire) сразу после signup; баннер «Каталог загружается…», повторно не
копирует. Остатков нет (0).
- Флаг организации ContributesToRegistry (демо/автотест — ВЫКЛ миграцией).
- SuperAdmin раздел «Реестр товаров»: поиск/правка/удаление карточек, тоггл
фонового пополнения (причина+аудит), кнопка наполнения из МойСклад, флаги
участия орг. Только SuperAdmin.
СХЕМА ЦЕН (решение владельца 12.10): три цены в карточке.
- Закупочная: ReferencePrice→PurchasePrice (миграция Phase48 RENAME COLUMN,
данные сохранены). Каждая проведённая приёмка пишет закупочную = цена строки;
unpost возвращает из предыдущей проведённой приёмки. API отдаёт purchasePrice
и временно referencePrice (алиас для iOS).
- Себестоимость (Cost): только чтение, скользящее среднее (как было).
- Продажная (бывш. «розничная»): меняется приёмкой только при ручной правке в
строке. Системный тип цены «Розничная цена»→«Продажная цена» (миграция+сидер),
подписи в UI переименованы.
- Убраны: автозаполнение эталонной при первой приёмке, ReferencePriceRefreshJob
(30-дневная перезапись), понятие «эталонная» в UI.
Тесты: SupplyPricingSchemeTests (приёмка без правок → продажная не меняется,
закупочная = цена строки, себестоимость средняя; правка продажной в строке;
unpost → закупочная вернулась) — 3/3.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Суперадмин управляет дельта-подгрузкой МойСклад на стенд флагом в «Настройках
платформы» (по умолчанию ВЫКЛ), не трогая systemd-таймер руками.
- PlatformSettings: MoySkladDeltaSyncEnabled (bool, default false) + состояние
последнего прогона (startedAt/finishedAt/ok/migrated/error); миграция Phase46
(ADD COLUMN IF NOT EXISTS, идемпотентно).
- Super-admin API: GET/PUT /platform-settings/moysklad-delta — тоггл с reason,
пишется в SuperAdminAuditLog; GET отдаёт состояние прогона. Только SuperAdmin.
- Admin API (для скрипта, роль Admin): GET /admin/moysklad/delta-sync (флаг),
POST /admin/moysklad/delta-sync/report (итог прогона → PlatformSettings).
- Серверная защита: import-supplies при delta=true и выключенном флаге → 409
с понятной причиной. Ручной импорт из мастера (без delta=true) не затронут.
- delta_sync.py: сначала спрашивает флаг — при «Выкл» одна строка в лог и выход
без изменения lastSync (повторное включение догонит пропущенное); помечает
запросы delta=true; в конце репортит итог прогона суперадмину.
- SuperAdminPlatformSettingsPage: блок «Подгрузка из МойСклад» — тоггл Вкл/Выкл
с причиной, подпись, состояние последнего прогона.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Автопроверка 52/52: scrollWidth≤clientWidth на всех плитках тарифа × 5 ширин.
Скриншоты k5-*.png, скрипт site-fixes-verify-5.mjs.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Добавочно к a5f885c: «по запросу» не сумма, не нужно держать её nowrap —
на 320–360px слово не влезало в колонку. Переносим по словам; суммы (nowrap)
и «/мес» под ними не трогаем.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Регрессия от a0f9e0b: whitespace-nowrap делал «14 000 ₸/мес» шире узкой
колонки плитки (~65px контента на 360px), хвост срезался → «14 000 ₸/ме».
Разношу: сумма+₸ одной неразрывной строкой, «/мес» — отдельной строкой под
суммой (плитки остаются в 3 колонки, сумма видна целиком, внутри суммы
переноса нет). Итог «Ваша конфигурация» и карточки главной — без изменений.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Автопроверка 44/44 на ширинах 320/375/390/402 × главная/pricing/signup —
скриншоты k4-*.png и скрипт site-fixes-verify-4.mjs.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Круг 3 закрыл только /pricing. Прогон в Safari на iPhone 17 (ширина 402)
нашёл ещё два разрыва: главная (hero: «5 / 000 ₸/мес») и /signup после
конфигуратора «Бизнес» (итог «14 000 ₸/ | мес» рвётся на слэше, плитки
тарифов тоже).
Системно, а не точечно:
- fmtKzt: разряды и пробел перед «₸» — неразрывные (U+00A0);
- новый fmtKztMonth: сумма + «₸» + «/мес» одним куском (word-joiner U+2060
вокруг «/»), используется в SignupForm (плитки + итог «Бизнес»);
- index.astro: hero-строка и карточки «Старт»/«Бизнес» — whitespace-nowrap + ;
- BusinessTariffBuilder: подпись «База 10 000 ₸» — nowrap;
- контент kb/billing.md, kb/faq.md, blog/launch.md, FAQ.tsx — nbsp + word-joiner
в суммах, чтобы цена не рвалась и в тексте.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Проверка на test.food-market.kz: касса подаётся одинаково честно (скачивание
«скоро») на главной/about как на /pos; «₸» не переносится в тарифах (1280 и 390).
Автопроверка 5/5. Реквизиты не трогал.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Круг 3 (финальный прогон этапа 1):
- Касса для Windows и Linux подаётся одинаково честно везде: приложение для
скачивания — «скоро» (как на /pos, /status, /kb/pos-setup). Правки на главной
(карточка «Продажи и касса») и /about («Что уже работает»).
- /pricing и конструктор «Бизнес»: сумма и знак «₸»/«₸/мес» не разрываются
(whitespace-nowrap + неразрывные пробелы) — «10 000 ₸», «14 000 ₸», «5 000 ₸/мес»
держатся в одну строку на 1280 и на мобильной.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Проверка задачи 11: интеграционный тест (эндпоинт), SQL по реальному датасету
МойСклад (org FOOD MARKET: в наличии 4746 / нулевые 23418 / минус 2829 / всего
30993; группа «Кондитерские…» зеро+минус 3848), живой stage-API на сид-данных и
скриншоты реальной админки (три галочки, URL states=…). StockReportPage не
менялся. Прод не трогали. Нужен рабочий пароль SuperAdmin для скриншота именно
org FOOD MARKET.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Поручение владельца (задача 11): галочки состояния остатка объединяются (ИЛИ),
группа/склад/поиск сужают (И). Пусто → positive+negative (нулевые скрыты).
- API StockController: параметр states (positive|zero|negative; через запятую или
повтором) на /api/inventory/stock и /stock/export. Один WHERE:
(positive И qty>0) ИЛИ (zero И qty=0) ИЛИ (negative И qty<0) — по остатку
(COALESCE подзапрос; товар без строки Stock = 0). total/пагинация/сортировка
корректны. Старые includeZero/negativeOnly оставлены для совместимости
(includeZero ≡ все три; negativeOnly ≡ negative); states приоритетнее.
- Веб-админка StockPage: три галочки «В наличии» (>0), «Нулевые» (=0), «В минусе»
(<0) вместо прежних двух; состояние в URL (states=…), экспорт учитывает галочки.
Ссылки NegativeStockBanner/OverdueNegativeStockBlock/NotificationCenter на
минусовые → states=negative.
- Интеграционный тест: сочетания (zero; negative; positive; zero+negative;
+группа; все три = весь каталог; пусто = positive+negative; со складом) и
числовые тождества (positive+negative=пусто; positive+zero+negative=весь
каталог) + совместимость старых флагов. 1/1 зелёный (EF8 переводит предикат).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- HwCheck: флаг --autofind (автопоиск при старте — для скриншотов/проверки).
- docs/pos-scale-2026-10-11: добавлен скриншот автопоиска на VM (COM1 в журнале,
без зависания), отчёт обновлён — новый zip hardware-check и его SHA256; полная
проверка с эмулятором/зависшим виртуальным портом ждёт com0com (решение владельца).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
На ноутбуке магазина автопоиск спотыкался о Bluetooth-порты (COM7/COM8 — Open/Write
висят), выбирал по умолчанию BT и не доходил до COM22 (USB-SERIAL CH340, где весы).
Парсер/протокол исправны (ручной выбор COM22 57600 работает) — баг только в поиске.
- ScaleAutodiscovery.DiscoverAsync: тирами по типу порта — USB-serial первыми,
неопознанные в середине, Bluetooth последними; на каждый порт ЖЁСТКИЙ таймаут
(Open обёрнут в задачу с гонкой против Task.Delay — SerialPort.Open на BT виснет);
порты перебираются параллельно (до 4), общий бюджет ~15 с; любая ошибка/таймаут →
следующий порт; по каждому порту строка в лог («COM22 CH340: ENQ→ACK, вес 0.000 кг»,
«COM7 Bluetooth: пропущен», «COM15: нет ответа»).
- HardwareProbe: Classify (CH340/Prolific/FTDI/CP210x → USB-serial; BTHENUM/Bluetooth
→ Bluetooth; ttyUSB/ttyACM → USB-serial), ClassifyPorts (без открытия портов),
OpenCloseBounded (жёсткий таймаут — листинг не виснет на BT). ListComPorts не
открывает Bluetooth-порты.
- HwCheck: по умолчанию выбирается НЕ Bluetooth-порт; окно показывает журнал
автопоиска по портам; список портов помечает [USB-serial]/[Bluetooth].
- Основная касса (экран «Оборудование») — та же DiscoverScaleAsync; --probe-hw не
открывает BT-порты.
- Из zip hardware-check убран ярлык «(с тестовой печатью).bat» (печать — отдельно
по слову владельца).
- Тесты: зависающий порт (Open 30 с) не задерживает поиск > таймаута, живой порт
вторым — найден; USB-serial проверяется раньше Bluetooth (BT не трогаем). 53/53.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Протокол и тулзы — готовы и проверены (50/50 юнит-тестов по реальным байтам;
окно «Проверка оборудования» запущено на Windows 11). НЕ выполнено: live-чтение
веса через виртуальную пару COM на VM (драйвер com0com требует доверия издателю —
решение владельца) и реальные весы с грузом в магазине (нужен человек с гирей).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Приоритет владельца: sysadmin проверяет весы/принтер/сканер на ноутбуке магазина
без входа в кассу. Отдельный exe (food-market.pos.hwcheck), ссылается ТОЛЬКО на
pos.core ради Hardware/* — не умеет быть кассой (нет логина, сервера, БД, токенов,
сетевых запросов).
- pos.core/Hardware/HardwareProbe.cs: детект COM-портов (занят/свободен, VID/PID,
описание) и принтеров Windows (имя/порт/в сети/число заданий) — только чтение,
очередь не трогаем. WMI под OperatingSystem.IsWindows(); на Linux — базовый COM.
- pos.core/Hardware/BarcodeScan.cs: контрольная цифра EAN-13/EAN-8 и оценка
«сканер vs ручной набор» по среднему интервалу между символами (чистая логика).
- food-market.pos.hwcheck: окно на Avalonia (код, без XAML), светлая тема, русский.
Весы (Найти/Прочитать/Запустить-Остановить, live-вес ~350 мс, сырой hex, ручной
выбор порта/скорости/протокола), COM-порты с пометкой «занят», принтеры (только
чтение), сканер (EAN + тип ввода), «Сохранить/Копировать отчёт». Тестовая печать
ВЫКЛ по умолчанию, включается только --allow-test-print.
- tests: EAN контрольная цифра (13/8, валид/битый) + классификация ввода. 50/50.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
По фактическому замеру с ноутбука магазина (11.10): весы Масса-К (USB-COM CH340)
отвечают только на 57600 8N1; рукопожатие ENQ(0x05)→ACK(0x06); запрос DC1(0x11) →
кадр SOH STX «флаг вес единица» CTRL ETX EOT.
- pos.core/Hardware/SerialScale.cs: ISerialTransport (абстракция для тестов) +
SystemSerialTransport (8N1, DTR/RTS), MassaK.ParseFrame/Handshake/ReadFrame/
ReadWeight. Control-байт НЕ валидируем (не подтверждён) — только сырой hex в лог.
Единицы kg по умолчанию, «г/g» → делим на 1000.
- pos.core/Hardware/ScaleDiscovery.cs: SerialScaleReader (+ стабильность по двум
одинаковым чтениям) и ScaleAutodiscovery — 57600 и Масса-К-кадр ПЕРВЫМИ, общий
бюджет, отдельно отмечаем занятые порты («порт занят», а не «весы не найдены»).
- pos: ComScale — тонкий адаптер к pos.core; AppServices хранит scale_proto и по
умолчанию MassaKFrame/57600; ProbeRunner (--probe-hw) печатает сырой hex кадра.
- tests: разбор реального нулевого кадра 01 02 53 20 20 30 2E 30 30 30 6B 67 71 03 04
и вариантов (1.235 / 12.500 / отрицательный / граммы / мусор до SOH / обрезанный /
без ACK) + рукопожатие на фейковом порту. 14/14 зелёных.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Закрыты хвосты (kb/quickstart, дубль H1 в cash-with-scales, 100k, перенос «₸/мес»),
передеплой на test; живой grep по /kb/* и /blog/* — чисто.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- kb/quickstart: убраны .msi/«ключ организации»/«импорт по API-токену» —
импорт из файла Excel/CSV, из других систем «в разработке»; касса Windows и
Linux «скоро», вход по адресу сервера + логин + PIN.
- blog/cash-with-scales: убран дублирующий <h1> в теле (как в launch/quick-start).
- kb/faq + og: неподтверждённое «до 100 000 товаров» → нейтрально «большие
каталоги / тысячи позиций» (точного лимита в коде нет; есть RequestSizeLimit 20МБ).
- Конструктор: цена «₸/мес» на кнопке «Выбрать конфигурацию» не переносится
(whitespace-nowrap).
- Форма регистрации: инлайн-ссылки «офертой»/«политикой» — увеличенная зона
нажатия (py-1) без сдвига вёрстки.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Проверка на живом test.food-market.kz после деплоя: React #418 ушёл, дефолтный
«Бизнес» 10 000, чужих систем учёта 0 (Kaspi/маркетплейсы только «в разработке»),
типографика KB, sitemap со слэшами, мобильные правки (Android «Назад», ползунки
−/+, состав панели), честные /status и /kb/billing.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Шапка: десктоп-меню с xl (чтобы на ~1050px не ломалось в 2 строки); CTA без
переноса; в мобильной панели добавлены «Интеграции», «Статус», «Что нового»;
Android «Назад» закрывает панель (pushState/popstate), Esc/тап/крестик остаются.
- Конструктор «Бизнес»: ползунки удобнее на тач — крупная ручка, touch-action
pan-y (вертикальный скролл не двигает значение), кнопки −/+; бейдж
«Популярный» (как на главной) и «90 дней бесплатно».
- Кнопка «Настроить тариф» на главной → /pricing#configurator со скроллом к
конструктору; на /pricing убран ложный пункт «Импорт из других систем» у «Старт».
- Типографика markdown (h2/h3, списки, таблицы, ссылки) вынесена в global.css —
/kb/* больше не плоский текст; эмодзи-фолбэк; увеличенная зона нажатия у
инлайн-ссылок; снят дублирующий inline-стиль в blog/[slug].
- Футер: «Status» → «Статус».
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- ?plan= и параметры конфигуратора читаются в useEffect ПОСЛЕ гидрации, поэтому
первый клиентский рендер совпадает с SSR-разметкой — ошибка React #418
(hydration mismatch) на /signup?plan=business&shops=… больше не возникает.
- plan=business без параметров → выбирается «Бизнес» с дефолтной конфигурацией
1/1/1/5 = 10 000 ₸; plan=network → «Сеть»; неизвестный план → «Старт».
- Клик по плитке тарифа обновляет URL (history.replaceState), ссылку можно
сохранить/поделиться.
- Плитка «Старт» теперь «5 000 ₸/мес»; цены плиток без переноса (whitespace-nowrap).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Чужие СИСТЕМЫ УЧЁТА (МойСклад, 1С) убраны со всего публичного сайта: тексты,
KB, блог, FAQ, og-картинки, meta. Платёжные системы и маркетплейсы (Kaspi,
Wildberries, Ozon и т.п.) оставлены только как честная пометка «в разработке»
на /integrations и главной.
- /integrations, /import, главная, about, features, pricing, blog, kb/faq:
«перенос из МойСклад/1С» → «импорт каталога из файлов Excel/CSV»; импорт из
других систем учёта — «в разработке, в личном кабинете магазина».
- kb/pos-setup: касса для Windows и Linux, вход по адресу сервера + логин + PIN,
установка «скоро»; чековые принтеры 58/80 мм (ESC/POS).
- kb/billing: переписан под реальность — биллинг-UI/подписки в продукте нет
(заглушка до Phase 4); оплата вручную через поддержку, онлайн-оплата «в
разработке»; убраны несуществующие «Настройки→Подписка→История», e-mail-
напоминания, баннер, формула кредита, SLA. Цены «тг» → «₸».
- kb/faq: бэкапы «каждые 24 ч» → «регулярно»; «TLS 1.3» → «TLS»; формулировка
про ЗРК смягчена; «триал» → «бесплатный период».
- /status: убраны фиктивные зелёные индикаторы (мониторинга нет) — честная
пометка «в разработке» + контакты для инцидентов.
- /changelog: убран внутренний жаргон (Phase N, SuperAdmin, retention, tenant,
inline) — человеческие формулировки.
- og.mjs: сабтайтлы без чужих брендов; касса Windows и Linux; «триал»→«бесплатно».
- sitemap.xml: канонические URL со слэшем + статьи KB и блога.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
docs/site-fixes-2026-10-10/{index.html,REPORT.md,screenshots}; tools/site-fixes-verify.mjs
(Playwright-проверка: signup plan/конфигурация/цена, мобильное меню, без промисов/REPLACE_ME).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
На реальном объёме перенесённого магазина список движений отдавал >2.5с из-за COUNT по
3-table join. Count теперь по stock_movements с фильтрами (join не меняет число строк).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- PosStore.FindAllByBarcode; SaleViewModel.ScanCandidates/IsScanPickerOpen + PickScanCandidate
- SaleView: модалка выбора; сервер by-barcode уже отдаёт items, веб-приёмка уже показывает выбор
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- docs/migration-debts-top20.md: топ-20 долгов (контрагент-уровень) + находка (paymentout agent=орг)
- MoneyAccountsPage: строка «Начальный остаток при переносе из МойСклад на <дата>» для МС-счетов
- systemd food-market-migration-delta.timer (каждые 10 мин) — непрерывная дельта до перехода
- прогресс: раздел «Исправления по ревью» (все 4 пункта)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- create: артикул-коллизия → суффикс msId (перенести карточку, не падать на unique)
- create/update: ШК не уникален → добавляем код каждой карточке (пары товар|код против
повторов), дубли ловит «Проверка данных»
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
DevDataSeeder по умолчанию (dev/stage) сидирует демо-орг; на проде SEED_DEMO_DATA=false
отключает демо-орг/demo-admin/привязку, сохраняя SuperAdmin+роли+глобальные ед.изм.+SystemSettings.
Нужно для чистого (пустого) старта реального магазина.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- ProbeRunner: COM-порты (имя/VID/PID/описание через WMI), open→close (занят/свободен без
удержания), опрос весов Масса-К+CAS 9600 (таймаут 1.5с), принтеры Windows (имя/порт/драйвер,
БЕЗ печати), HID-клавиатуры (возможные сканеры). --port COMx — один порт; занятый не трогаем.
- --test-print "<принтер>": отдельный флаг, ESC/POS тест-чек «ТЕСТ ALL MARKET» через spooler
(winspool RAW). Без флага ничего не печатается.
- WinExe → AttachConsole(parent) для видимого вывода; --out пишет чистый UTF-8 JSON.
- System.Management (WMI, только Windows, под guard'ами). Проверено на Win11 VM: выход <10с,
COM1/принтер/HID определяются, test-print на несуществующий принтер — мягкая ошибка (код 4).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- reconcile: выручка по документам (точно до копейки), plotseries как справка; чеки сходятся
- delta_sync: camelCase ключи job (created/skipped), повторный опрос, audit tolerant — дельта
подтверждена (новый чек из МС подтянут: created 1)
- НАЙДЕНО: 30000 строк stocks без движений (прежний прямой сид) → пересобрать из движений
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- StreamDocumentsAsync: Uri.EscapeDataString всего выражения updated>=<дата> (>= → %3E%3D),
не только даты — иначе часть форм 400/неоднозначна
- delta_sync: повторное чтение job после Succeeded (устранить гонку счётчиков), audit в try
- reconcile: розница демо/возвраты раздельно, URL-энкод фильтра чеков по месяцам
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- scripts/migration/delta_sync.py: раз в N мин updated>=lastSync по всем типам,
удаления через /audit, состояние в ~/.fm-watchdog, перекрытие окна 2 мин
- docs/migration-runbook.md: фазы A/B/C, откат на МойСклад, надёжность, ограничения токена
- reconcile.py: секции балансов счетов (report/money/byaccount) и долгов (403-ограничение)
- progress: Parts 5/6/7 закрыты
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>