Commit graph

707 commits

Author SHA1 Message Date
nns 8e719aeeb3 fix(кабинет/Android): выпадающие списки не закрываются от клавиатуры
Some checks failed
Auto-tag / Create date-tag (push) Has been cancelled
CI / Backend (.NET 8) (push) Has been cancelled
CI / Web (React + Vite) (push) Has been cancelled
CI / POS (WPF, Windows) (push) Has been cancelled
Docker Web / Build + push Web (push) Has been cancelled
Docker Web / Deploy Web on stage (push) Has been cancelled
На Android Select в кабинете («Тип счёта», «Счёт для наличных», «Магазин»…) не
открывались: автофокус в «Поиск…» выдвигал экранную клавиатуру → Chrome слал
window resize (только высота) и scroll к полю → слушатель
`() => setOpen(false)` тут же закрывал список.

Общий хук useDropdownViewport (для обоих Select и AsyncSelect):
- resize закрывает только при смене ШИРИНЫ (поворот); изменение высоты
  (клавиатура) — лишь пересчёт позиции, список остаётся открыт;
- scroll внутри самого списка игнорируется; внешний скролл пересчитывает
  позицию и закрывает, только если триггер ушёл за экран;
- visualViewport resize/scroll (клавиатура) — пересчёт позиции.
Автофокус в поле поиска: на сенсорных устройствах (pointer: coarse) не ставим
при коротком списке (≤8) — клавиатура мешала бы; при длинном поиск нужен.
На десктопе поведение прежнее (фокус, Esc и клик-вне закрывают).

Проверено в WebKit и Chromium (моб. 360×700 с эмуляцией клавиатуры через
изменение высоты вьюпорта, и десктоп): открытие по тапу, устойчивость к
клавиатуре, закрытие при повороте/уходе триггера за экран, Esc, клик вне — 19/19.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-10-14 19:15:20 +05:00
nns 022e09ef7d fix(кабинет/моб): модалка растёт по контенту; счёт-касса — магазин по умолчанию
Some checks are pending
Auto-tag / Create date-tag (push) Waiting to run
CI / Backend (.NET 8) (push) Waiting to run
CI / Web (React + Vite) (push) Waiting to run
CI / POS (WPF, Windows) (push) Waiting to run
Docker Web / Build + push Web (push) Waiting to run
Docker Web / Deploy Web on stage (push) Blocked by required conditions
1. Modal: на телефоне было items-stretch — панель фиксировалась по высоте экрана,
   и длинное содержимое (карточка кассира: Кассы, PIN, кнопки) вылезало за белый
   фон на затемнённый оверлей. Заменил на items-start (min-h-full сохранён): панель
   растёт по контенту, а короткое окно по-прежнему во всю высоту. Десктоп (sm:) не
   затронут. Проверено в WebKit (iPhone 402) и Chromium: длинное окно — белый фон до
   низа + прокрутка оверлея; короткое — на всю высоту.
2. Счета: при создании счёта типа «Касса», если в организации ровно один магазин,
   он подставляется в «Магазин» по умолчанию (иначе сохранить нельзя, а выбирать
   не из чего).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-10-14 18:48:10 +05:00
nns 5a12f2e8bd fix(кабинет): убрать техножаргон из подсказок
Some checks are pending
Auto-tag / Create date-tag (push) Waiting to run
CI / Backend (.NET 8) (push) Waiting to run
CI / Web (React + Vite) (push) Waiting to run
CI / POS (WPF, Windows) (push) Waiting to run
Docker Web / Build + push Web (push) Waiting to run
Docker Web / Deploy Web on stage (push) Blocked by required conditions
Подсказка под PIN кассира — простым языком («Быстрый вход кассира на кассе по
PIN — без email и пароля. Работает на кассах, к которым привязан кассир.»),
без «grant_type=pin». Заодно почистил жаргон в других подсказках кабинета:
«endpoint» → «список обновлений пуст» (Новые функции); «URL API (sandbox/dev)»
→ «Адрес сервера оператора (тестовый контур)», «production» → «рабочий режим»
(ОФД); «Идемпотентно» → «повторный запуск не создаёт дубликатов», «для
демонстрации стейджа» → «для демонстрации» (демо-данные, суперадмин).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-10-14 02:36:50 +05:00
nns 519e4073df fix(кабинет): этап «Настройка кабинета» — 15 правок (прогон 14.10)
Some checks failed
Auto-tag / Create date-tag (push) Waiting to run
CI / Backend (.NET 8) (push) Waiting to run
CI / Web (React + Vite) (push) Waiting to run
CI / POS (WPF, Windows) (push) Waiting to run
Docker Web / Build + push Web (push) Waiting to run
Docker Web / Deploy Web on stage (push) Blocked by required conditions
Docker API / Build + push API (push) Has been cancelled
Docker API / Deploy API on stage (push) Has been cancelled
1. Реквизиты организации: БИН/ИИН (12 цифр, проверка), юр.адрес, «Плательщик
   НДС» — в Настройках → Организация, сохраняются и отдаются в API (Organization.
   IsVatPayer + Bin/Address в OrgSettings).
2. Склад при регистрации — адрес пустой (была заглушка «Алматы, ул. Пример 1»);
   миграция чистит заглушку у существующих складов.
3. Кассы: блок скачивания кассы скрыт, пока нет ссылок на сборки (убраны
   мёртвые кнопки и технический текст про конфигурацию сервера).
4. Счета: в списке показывается валюта счёта (а не ₸ орг.); новый счёт по
   умолчанию в валюте организации (KZT), не первой в справочнике. Миграция:
   счета KZ-организаций в BYN без движений → KZT.
5. «Дата начала учёта» берётся по локальной дате (была UTC → ночью подставляла
   вчера). todayIso() переведён на локальное время.
6. Esc в выпадающем списке закрывает только список, не весь диалог (Select гасит
   всплытие + Modal закрывается лишь при !defaultPrevented).
7. Счёт-касса: подпись «Магазин (к которому относится касса)» вместо «привязана
   к точке» — список показывает склады/магазины.
8. Точка продаж: поля «Счёт для наличных» и «Счёт для оплаты картой»; автооткрытие
   смены берёт счета из точки (наличные→Cash, карта→Acquiring/Bank).
9. PIN кассира: в карточке сотрудника задать/сменить/снять PIN; в списке «PIN
   задан»; вход grant_type=pin по точке (сервер уже поддерживал).
10. «Сбросить пароль» в карточке сотрудника → новый временный пароль один раз.
11. Владелец в «Сотрудниках» — «Владелец» вместо «<название> Owner» (signup +
    миграция существующих).
12. Роли: матрица прав дополнена недостающими 6 правами (перемещения, деньги/
    смены, маркетинг) — цифра «N/38» теперь совпадает с галочками; текст без
    жаргона «CRUD».
13. Настройки: блок «Демо-данные» — только суперадмину; «Креды per-tenant» →
    человеческий текст.
15. Форма входа: сообщения «Укажите email» / «Введите пароль» (как в регистрации).
16. Суммы счетов без копеек, если в организации выключены дробные цены
    (useFormatCurrency учитывает allowFractionalPrices).

Тесты: CabinetSetupTests (реквизиты+валидация БИН, имя владельца, счета точки,
PIN+вход grant_type=pin, сброс пароля) 5/5; регрессия Plan/Markup/RegistryCopy 7/7.
Код весовых (27+5) НЕ трогал — весы на паузе. П.14 — см. отчёт (блок продажи в
минус не ставится; поведение «разрешено с предупреждением» уже соответствует).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-10-14 01:55:29 +05:00
nns b3daa889f4 fix(регистрация/iOS): перенос фокуса к первой ошибке при открытой клавиатуре
Some checks failed
Auto-tag / Create date-tag (push) Waiting to run
CI / Backend (.NET 8) (push) Waiting to run
CI / Web (React + Vite) (push) Waiting to run
CI / POS (WPF, Windows) (push) Waiting to run
Docker Public / Build + push Public (test + latest) (push) Has been cancelled
Docker Public / Deploy :test → test.food-market.kz (push) Has been cancelled
iOS Safari: если набрать пароль и, НЕ скрывая клавиатуру, нажать кнопку —
фокус не переходил на первое поле с ошибкой (email), оставался в пароле.
Причина: focusFirstError откладывал el.focus() через setTimeout(150) — вне
пользовательского жеста iOS игнорирует программный перенос фокуса (тем более
из поля с открытой клавиатурой).

Теперь focus() вызывается СИНХРОННО в обработчике жеста (pointerup/click/Enter)
с preventScroll, а плавная прокрутка к полю — отдельно. Тап/свайп из 87a4666
не затронуты.

Проверено на WebKit-движке (Playwright webkit, hasTouch, iPhone-вьюпорт):
пароль в фокусе → тап по кнопке → фокус переходит на email; и на Chromium
(тап/свайп/долгое нажатие, первое касание, один запрос) — регрессий нет.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-10-13 18:00:37 +05:00
nns 87a4666c25 fix(регистрация/моб): свайп с кнопки прокручивает, а не отправляет форму
Some checks are pending
Auto-tag / Create date-tag (push) Waiting to run
CI / Backend (.NET 8) (push) Waiting to run
CI / Web (React + Vite) (push) Waiting to run
CI / POS (WPF, Windows) (push) Waiting to run
Docker Public / Build + push Public (test + latest) (push) Waiting to run
Docker Public / Deploy :test → test.food-market.kz (push) Blocked by required conditions
Docker Web / Build + push Web (push) Waiting to run
Docker Web / Deploy Web on stage (push) Blocked by required conditions
Регрессия к 3322da0: submit запускался прямо на pointerdown, поэтому прокрутка,
начатая пальцем на широкой кнопке «Начать бесплатно»/«Войти», отправляла форму.

Теперь на pointerdown только preventDefault (держим фокус в поле — blur-ошибка
не сдвигает вёрстку) и запоминаем точку касания. Отправляем на pointerup,
только если палец не сдвинулся больше порога (10px); pointercancel (жест стал
прокруткой) сбрасывает — submit не происходит. Тап отправляет с первого раза,
свайп с кнопки просто прокручивает страницу. onSubmit формы сохранён для Enter,
submittingRef защищает от двойного запроса.

Применено к форме регистрации и форме входа кабинета.

Проверено настоящими touch-жестами в Chromium (mobile 360×676, CDP
dispatchTouchEvent): тап → submit; свайп вверх 250px с кнопки → страница
прокручивается, submit НЕ срабатывает; долгое нажатие без движения → submit;
валидная форма — ровно один запрос.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-10-13 17:37:30 +05:00
nns 3322da06a0 fix(регистрация/моб): первое касание кнопки всегда отправляет форму
Some checks are pending
Auto-tag / Create date-tag (push) Waiting to run
CI / Backend (.NET 8) (push) Waiting to run
CI / Web (React + Vite) (push) Waiting to run
CI / POS (WPF, Windows) (push) Waiting to run
Docker Public / Build + push Public (test + latest) (push) Waiting to run
Docker Public / Deploy :test → test.food-market.kz (push) Blocked by required conditions
Docker Web / Build + push Web (push) Waiting to run
Docker Web / Deploy Web on stage (push) Blocked by required conditions
На мобильном первое касание «Начать бесплатно»/«Войти» терялось: при касании
кнопки поле теряло фокус (blur), под ним вставлялась ошибка, вёрстка сдвигала
кнопку между touchstart и touchup — click не попадал в кнопку, срабатывала
только blur-валидация (одно поле), а submit — нет; нужен был второй тап.

Теперь submit запускается на onPointerDown кнопки (срабатывает в момент
касания, ДО перерисовки и возможного сдвига), с e.preventDefault() —
фокус остаётся на поле (blur-ошибка не вставляется) и подавляется повторный
click. Валидация всех полей + прокрутка и фокус к первой ошибке выполняются
на первом касании, независимо от blur-валидации. onSubmit формы сохранён для
Enter; submittingRef защищает от двойного сетевого запроса.

Применено к форме регистрации (SignupForm) и форме входа кабинета (LoginPage).

Проверено настоящим touch в Chromium (mobile 360×676, hasTouch): первое
касание — submit + фокус на первом поле с ошибкой; случай «ошибки уже
показаны» — submit; валидная форма — ровно один запрос (без дубля).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-10-13 17:16:59 +05:00
nns 164ad57ed7 fix(регистрация/моб): поля ввода 16px на мобильной ширине (iOS Safari без зума)
Some checks are pending
Auto-tag / Create date-tag (push) Waiting to run
CI / Backend (.NET 8) (push) Waiting to run
CI / Web (React + Vite) (push) Waiting to run
CI / POS (WPF, Windows) (push) Waiting to run
Docker Public / Build + push Public (test + latest) (push) Waiting to run
Docker Public / Deploy :test → test.food-market.kz (push) Blocked by required conditions
Docker Web / Build + push Web (push) Waiting to run
Docker Web / Deploy Web on stage (push) Blocked by required conditions
iOS Safari зумит страницу при фокусе на поле с font-size < 16px и оставляет её
увеличенной/сдвинутой. Делаем у текстовых полей text-base (16px) на мобильной
ширине и sm:text-sm (14px) на планшете+. Запрет масштабирования (user-scalable=no)
НЕ вводим — viewport-меты не трогаем.

Затронуто:
- public: SignupForm.inputCls (email/пароль/название + PhoneInput сайта);
- кабинет: общий inputClass в Field.tsx (TextInput/Textarea/Select/Money/Percent)
  + поиск внутри выпадашек, PhoneInput кабинета, инлайн-поля LoginPage.

Диапазон-слайдер конструктора тарифов не трогаем (type=range не зумится).
Проверено в браузере (Playwright): на ширине 390 все поля формы регистрации
16px, на 900 — 14px.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-10-13 14:11:13 +05:00
nns 043d5c0417 fix(регистрация): телефон — нестираемый префикс «+7 »
Some checks are pending
Auto-tag / Create date-tag (push) Waiting to run
CI / Backend (.NET 8) (push) Waiting to run
CI / Web (React + Vite) (push) Waiting to run
CI / POS (WPF, Windows) (push) Waiting to run
Docker Public / Build + push Public (test + latest) (push) Waiting to run
Docker Public / Deploy :test → test.food-market.kz (push) Blocked by required conditions
Docker Web / Build + push Web (push) Waiting to run
Docker Web / Deploy Web on stage (push) Blocked by required conditions
Стирание больше не превращает «7» кода страны в цифру номера. Причина: при
Backspace в префикс raw становился «+7», и парсер считал это номером «7»
(«+7 7», далее набор давал мусор «+7 010 000 00 07»). Теперь:
- извлечение тела номера идёт через stripPrefix (проход по совпадающим
  символам префикса) — повреждённый префикс даёт пустое тело, а не номер;
- onKeyDown глушит Backspace на границе префикса и Delete перед префиксом;
  выделение+стирание (Ctrl+A/Ctrl+X) очищает поле до «+7 ».
Полностью стёртое поле = «+7 » и пустой номер. Обе копии (сайт + кабинет).

Проверено настоящим вводом в Chromium (Playwright): Ctrl+A+Backspace,
Backspace до упора, Delete в начале, выделение+набор, Ctrl+A+Ctrl+X —
после каждого набор «7010000000» ⇒ «+7 701 000 00 00»; регрессия набора и
вставки тоже зелёная.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-10-12 22:29:51 +05:00
nns 6510ccafb5 fix(регистрация): вставка телефона + 3 мелочи перепроверки (12.10)
Some checks are pending
Auto-tag / Create date-tag (push) Waiting to run
CI / Backend (.NET 8) (push) Waiting to run
CI / Web (React + Vite) (push) Waiting to run
CI / POS (WPF, Windows) (push) Waiting to run
Docker Public / Build + push Public (test + latest) (push) Waiting to run
Docker Public / Deploy :test → test.food-market.kz (push) Blocked by required conditions
Docker Web / Build + push Web (push) Waiting to run
Docker Web / Deploy Web on stage (push) Blocked by required conditions
Маска телефона: onBeforeInput больше не блокирует ВСТАВКУ. Раньше он
отменял любой ввод с не-цифрами в data, из-за чего вставка «+7 701…» /
«8 (701) 000-00-00» через CDP insertText блокировалась целиком и номер
пропадал («+7 »). Теперь блокируется только одиночный набранный не-цифровой
символ; вставку нормализует handleChange. Обе копии (public + admin).
Проверено в реальном Chromium (Playwright): посимвольный ввод (delay 0 и 20),
все варианты вставки и Backspace посреди номера → «+7 701 000 00 00».

1. Мастер «Первые шаги», шаг каталога: число товаров с разделителем разрядов
   и склонением («30 951 товар»); текст исправлен — закупочная и себестоимость
   приходят из реестра вместе с товаром, оставлено «Проверьте продажные цены —
   они взяты из реестра».
2. Прибыль на главной: убрана фраза про «переход на FIFO» (внутренняя кухня);
   оставлено «Прибыль приблизительная — по текущей себестоимости из карточек».

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-10-12 22:10:20 +05:00
nns 0ce0e0df77 fix(регистрация): 7 правок этапа «Регистрация» (прогон 12.10)
Some checks are pending
Auto-tag / Create date-tag (push) Waiting to run
CI / Backend (.NET 8) (push) Waiting to run
CI / Web (React + Vite) (push) Waiting to run
CI / POS (WPF, Windows) (push) Waiting to run
Docker API / Build + push API (push) Waiting to run
Docker API / Deploy API on stage (push) Blocked by required conditions
Docker Public / Build + push Public (test + latest) (push) Waiting to run
Docker Public / Deploy :test → test.food-market.kz (push) Blocked by required conditions
Docker Web / Build + push Web (push) Waiting to run
Docker Web / Deploy Web on stage (push) Blocked by required conditions
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>
2026-10-12 21:46:15 +05:00
nns 005e5457af docs(registry): штрихкоды МойСклад на нескольких товарах (46 ШК → 47 пропущенных карточек)
Some checks are pending
Auto-tag / Create date-tag (push) Waiting to run
Список штрихкодов, стоящих в МойСклад более чем на одном товаре (barcode,
число товаров, наименования, артикулы). 46 штрихкодов на ≥2 товарах (один — на
трёх), что соответствует SkippedDuplicateBarcode=47 при наполнении реестра.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-10-12 21:02:35 +05:00
nns 8540be032e feat(supplies): автонаценка при приёмке — только по переключателю магазина
Some checks are pending
Auto-tag / Create date-tag (push) Waiting to run
CI / Backend (.NET 8) (push) Waiting to run
CI / Web (React + Vite) (push) Waiting to run
CI / POS (WPF, Windows) (push) Waiting to run
Docker API / Build + push API (push) Waiting to run
Docker API / Deploy API on stage (push) Blocked by required conditions
Docker Web / Build + push Web (push) Waiting to run
Docker Web / Deploy Web on stage (push) Blocked by required conditions
Настройка организации 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>
2026-10-12 20:07:31 +05:00
nns 81bf4c7b23 feat(registry): кнопка/эндпоинт «Запустить пополнение сейчас» (SuperAdmin)
Some checks are pending
Auto-tag / Create date-tag (push) Waiting to run
CI / Backend (.NET 8) (push) Waiting to run
CI / Web (React + Vite) (push) Waiting to run
CI / POS (WPF, Windows) (push) Waiting to run
Docker API / Build + push API (push) Waiting to run
Docker API / Deploy API on stage (push) Blocked by required conditions
Docker Web / Build + push Web (push) Waiting to run
Docker Web / Deploy Web on stage (push) Blocked by required conditions
Разовый запуск фонового пополнения реестра помимо расписания
(POST /api/super-admin/product-registry/enrich/run-now). Джоб проверяет флаг.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-10-12 19:43:49 +05:00
nns e39e4fe1d5 feat(registry+pricing): «Реестр товаров» + схема цен (закупочная/себестоимость/продажная)
Some checks are pending
Auto-tag / Create date-tag (push) Waiting to run
CI / Backend (.NET 8) (push) Waiting to run
CI / Web (React + Vite) (push) Waiting to run
CI / POS (WPF, Windows) (push) Waiting to run
Docker API / Build + push API (push) Waiting to run
Docker API / Deploy API on stage (push) Blocked by required conditions
Docker Web / Build + push Web (push) Waiting to run
Docker Web / Deploy Web on stage (push) Blocked by required conditions
РЕЕСТР ТОВАРОВ (глобальный системный шаблон карточек):
- Домен 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>
2026-10-12 19:19:47 +05:00
nns 42e4f630b1 feat(superadmin): переключатель подгрузки из МойСклад + состояние прогона
Some checks are pending
Auto-tag / Create date-tag (push) Waiting to run
CI / Backend (.NET 8) (push) Waiting to run
CI / Web (React + Vite) (push) Waiting to run
CI / POS (WPF, Windows) (push) Waiting to run
Docker API / Build + push API (push) Waiting to run
Docker API / Deploy API on stage (push) Blocked by required conditions
Docker Web / Build + push Web (push) Waiting to run
Docker Web / Deploy Web on stage (push) Blocked by required conditions
Суперадмин управляет дельта-подгрузкой МойСклад на стенд флагом в «Настройках
платформы» (по умолчанию ВЫКЛ), не трогая 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>
2026-10-12 17:08:41 +05:00
nns e4d756e004 docs(site): отчёт и скриншоты Круга 5 (плитки /signup не срезают цену, 320–402px)
Some checks are pending
Auto-tag / Create date-tag (push) Waiting to run
CI / Backend (.NET 8) (push) Waiting to run
CI / Web (React + Vite) (push) Waiting to run
CI / POS (WPF, Windows) (push) Waiting to run
Автопроверка 52/52: scrollWidth≤clientWidth на всех плитках тарифа × 5 ширин.
Скриншоты k5-*.png, скрипт site-fixes-verify-5.mjs.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-10-12 01:16:37 +05:00
nns ee5c7ecc56 fix(site): плитка «Сеть» — «по запросу» переносится по словам на узкой плитке
Some checks are pending
Auto-tag / Create date-tag (push) Waiting to run
CI / Backend (.NET 8) (push) Waiting to run
CI / Web (React + Vite) (push) Waiting to run
CI / POS (WPF, Windows) (push) Waiting to run
Docker Public / Build + push Public (test + latest) (push) Waiting to run
Docker Public / Deploy :test → test.food-market.kz (push) Blocked by required conditions
Добавочно к a5f885c: «по запросу» не сумма, не нужно держать её nowrap —
на 320–360px слово не влезало в колонку. Переносим по словам; суммы (nowrap)
и «/мес» под ними не трогаем.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-10-12 01:14:56 +05:00
nns a5f885cb80 fix(site): цена в плитках тарифа /signup не срезается на 320–360px
Some checks are pending
Auto-tag / Create date-tag (push) Waiting to run
CI / Backend (.NET 8) (push) Waiting to run
CI / Web (React + Vite) (push) Waiting to run
CI / POS (WPF, Windows) (push) Waiting to run
Docker Public / Build + push Public (test + latest) (push) Waiting to run
Docker Public / Deploy :test → test.food-market.kz (push) Blocked by required conditions
Регрессия от a0f9e0b: whitespace-nowrap делал «14 000 ₸/мес» шире узкой
колонки плитки (~65px контента на 360px), хвост срезался → «14 000 ₸/ме».
Разношу: сумма+₸ одной неразрывной строкой, «/мес» — отдельной строкой под
суммой (плитки остаются в 3 колонки, сумма видна целиком, внутри суммы
переноса нет). Итог «Ваша конфигурация» и карточки главной — без изменений.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-10-12 01:12:04 +05:00
nns 03c1dd98ce docs(site): отчёт и скриншоты Круга 4 (цена не разрывается, 320–402px, Safari)
Some checks are pending
Auto-tag / Create date-tag (push) Waiting to run
CI / Backend (.NET 8) (push) Waiting to run
CI / Web (React + Vite) (push) Waiting to run
CI / POS (WPF, Windows) (push) Waiting to run
Автопроверка 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>
2026-10-12 00:35:50 +05:00
nns a0f9e0b889 fix(site): цена «сумма + ₸ + /мес» не разрывается по строкам (320–402px)
Some checks are pending
Auto-tag / Create date-tag (push) Waiting to run
CI / Backend (.NET 8) (push) Waiting to run
CI / Web (React + Vite) (push) Waiting to run
CI / POS (WPF, Windows) (push) Waiting to run
Docker Public / Build + push Public (test + latest) (push) Waiting to run
Docker Public / Deploy :test → test.food-market.kz (push) Blocked by required conditions
Круг 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 + &nbsp;;
- 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>
2026-10-12 00:32:37 +05:00
nns 93e26dc8df docs(site): отчёт и скриншоты Круга 3 (касса «скоро» единообразно, «₸» без переноса)
Some checks are pending
Auto-tag / Create date-tag (push) Waiting to run
CI / Backend (.NET 8) (push) Waiting to run
CI / Web (React + Vite) (push) Waiting to run
CI / POS (WPF, Windows) (push) Waiting to run
Docker Public / Build + push Public (test + latest) (push) Waiting to run
Docker Public / Deploy :test → test.food-market.kz (push) Blocked by required conditions
Проверка на test.food-market.kz: касса подаётся одинаково честно (скачивание
«скоро») на главной/about как на /pos; «₸» не переносится в тарифах (1280 и 390).
Автопроверка 5/5. Реквизиты не трогал.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-10-11 22:23:11 +05:00
nns a25b940aaa fix(site): касса «скоро» единообразно (главная/about) + «₸» не переносится в тарифах
Круг 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>
2026-10-11 22:21:03 +05:00
nns e6cdaa9839 docs(stock): отчёт и скриншоты проверки фильтров остатков (stage, SQL, UI)
Some checks are pending
Auto-tag / Create date-tag (push) Waiting to run
CI / Backend (.NET 8) (push) Waiting to run
CI / Web (React + Vite) (push) Waiting to run
CI / POS (WPF, Windows) (push) Waiting to run
Проверка задачи 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>
2026-10-11 18:45:00 +05:00
nns d49b586904 feat(stock): фильтры остатков «В наличии / Нулевые / В минусе» (states, объединение ИЛИ)
Some checks are pending
Auto-tag / Create date-tag (push) Waiting to run
CI / Backend (.NET 8) (push) Waiting to run
CI / Web (React + Vite) (push) Waiting to run
CI / POS (WPF, Windows) (push) Waiting to run
Docker API / Build + push API (push) Waiting to run
Docker API / Deploy API on stage (push) Blocked by required conditions
Docker Web / Build + push Web (push) Waiting to run
Docker Web / Deploy Web on stage (push) Blocked by required conditions
Поручение владельца (задача 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>
2026-10-11 18:29:31 +05:00
nns 8371ef6683 docs(pos): фикс автопоиска весов (Bluetooth) проверен на Win11 + --autofind
Some checks are pending
Auto-tag / Create date-tag (push) Waiting to run
CI / Backend (.NET 8) (push) Waiting to run
CI / Web (React + Vite) (push) Waiting to run
CI / POS (WPF, Windows) (push) Waiting to run
- 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>
2026-10-11 09:09:37 +05:00
nns f15a12695c fix(pos): автопоиск весов не виснет на Bluetooth-портах (реальный баг на кассе 11.10)
На ноутбуке магазина автопоиск спотыкался о 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>
2026-10-11 09:03:45 +05:00
nns 6f97e327b1 docs(pos): отчёт по протоколу весов Масса-К + «Проверка оборудования» (скриншот Win11)
Some checks are pending
Auto-tag / Create date-tag (push) Waiting to run
CI / Backend (.NET 8) (push) Waiting to run
CI / Web (React + Vite) (push) Waiting to run
CI / POS (WPF, Windows) (push) Waiting to run
Docker API / Build + push API (push) Waiting to run
Docker API / Deploy API on stage (push) Blocked by required conditions
Протокол и тулзы — готовы и проверены (50/50 юнит-тестов по реальным байтам;
окно «Проверка оборудования» запущено на Windows 11). НЕ выполнено: live-чтение
веса через виртуальную пару COM на VM (драйвер com0com требует доверия издателю —
решение владельца) и реальные весы с грузом в магазине (нужен человек с гирей).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-10-11 08:54:53 +05:00
nns 19cbdbbf11 build(pos): скрипт сборки «Проверка оборудования» под Windows x64 (zip + ярлык + README)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-10-11 08:41:25 +05:00
nns ff1580d162 feat(pos): отдельная программа «ALL MARKET — Проверка оборудования» (без входа/сервера/БД)
Приоритет владельца: 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>
2026-10-11 08:37:55 +05:00
nns 25c37415bf feat(pos): реальный протокол весов Масса-К (57600, ENQ/ACK, DC1, кадр) вместо угаданного
По фактическому замеру с ноутбука магазина (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>
2026-10-11 08:29:06 +05:00
nns d04d1d53fa docs(site): отчёт/скриншоты круга 2 обновлены после догоняющих правок (44/44)
Some checks are pending
Auto-tag / Create date-tag (push) Waiting to run
CI / Backend (.NET 8) (push) Waiting to run
CI / Web (React + Vite) (push) Waiting to run
CI / POS (WPF, Windows) (push) Waiting to run
Docker Public / Build + push Public (test + latest) (push) Waiting to run
Docker Public / Deploy :test → test.food-market.kz (push) Blocked by required conditions
Закрыты хвосты (kb/quickstart, дубль H1 в cash-with-scales, 100k, перенос «₸/мес»),
передеплой на test; живой grep по /kb/* и /blog/* — чисто.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-10-11 01:36:02 +05:00
nns 28cc6a714b fix(site): хвосты круга 2 — kb/quickstart, дубль H1 в блоге, 100k, перенос строки
- 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>
2026-10-11 01:33:34 +05:00
nns 5c5f92de52 docs(site): отчёт и скриншоты проверки круга 2 (44/44) + verify-скрипт
Some checks are pending
Auto-tag / Create date-tag (push) Waiting to run
CI / Backend (.NET 8) (push) Waiting to run
CI / Web (React + Vite) (push) Waiting to run
CI / POS (WPF, Windows) (push) Waiting to run
Docker Public / Build + push Public (test + latest) (push) Waiting to run
Docker Public / Deploy :test → test.food-market.kz (push) Blocked by required conditions
Проверка на живом 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>
2026-10-11 01:29:07 +05:00
nns 6f229ebecc fix(site): мобильные и UX-правки по тесту (Android/iOS), типографика KB/блога
- Шапка: десктоп-меню с 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>
2026-10-11 01:22:14 +05:00
nns 5f2188a7f9 fix(signup): устранён React #418 (hydration) + дефолтная конфигурация «Бизнес»
- ?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>
2026-10-11 01:21:58 +05:00
nns 330032b13a fix(site): честность текстов + убраны чужие системы учёта; статус/changelog без фикции
Чужие СИСТЕМЫ УЧЁТА (МойСклад, 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>
2026-10-11 01:21:47 +05:00
nns 304b72dc04 docs(site): обновлён отчёт проверки (10/10, повторный прогон на живом test.food-market.kz)
Some checks are pending
Auto-tag / Create date-tag (push) Waiting to run
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 00:21:09 +05:00
nns ad747bf58c docs(site): отчёт и скриншоты проверки исправлений test.food-market.kz (10/10)
Some checks are pending
Auto-tag / Create date-tag (push) Waiting to run
CI / Backend (.NET 8) (push) Waiting to run
CI / Web (React + Vite) (push) Waiting to run
CI / POS (WPF, Windows) (push) Waiting to run
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>
2026-10-11 00:03:01 +05:00
nns 7fbf94a202 fix(site): /status «Касса (Windows)» — «Скоро» (согласовано с «Скачать · скоро»)
Some checks are pending
Auto-tag / Create date-tag (push) Waiting to run
CI / Backend (.NET 8) (push) Waiting to run
CI / Web (React + Vite) (push) Waiting to run
CI / POS (WPF, Windows) (push) Waiting to run
Docker Public / Build + push Public (test + latest) (push) Waiting to run
Docker Public / Deploy :test → test.food-market.kz (push) Blocked by required conditions
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 23:55:02 +05:00
nns b8e42e216c fix(site): критичные + честность текстов на test.food-market.kz (этап 1)
Some checks are pending
Auto-tag / Create date-tag (push) Waiting to run
CI / Backend (.NET 8) (push) Waiting to run
CI / Web (React + Vite) (push) Waiting to run
CI / POS (WPF, Windows) (push) Waiting to run
Docker Public / Build + push Public (test + latest) (push) Waiting to run
Docker Public / Deploy :test → test.food-market.kz (push) Blocked by required conditions
1. /signup читает ?plan= и конфигурацию (общий модуль lib/pricing.ts): предвыбор тарифа,
   для «Бизнес» — конфигурация и цена (15 500 ₸ для 3/4/1); неизвестный план → «Старт».
2. Мобильная шапка: гамбургер + панель со всеми пунктами (aria-expanded, Esc/клик-вне, ≥44px).
3. og-картинки без ОФД/REST API/ABC — перегенерированы.
4. KB/блог: убраны несуществующие обещания (Kaspi Pay/Halyk/Visa, REST API, «Скачать установщик»,
   Kaspi Magazin Q3, маркировка, платные консультации, скидки 3/6/12, «Триал» как тариф).
   Противоречия сведены к оферте (удаление данных 30 дн, возврат по заявлению, Старт=2 сотр.).
5. /import: чужой HR-скриншот заменён на скриншот каталога продукта.
6. KB рендерился как сырой front-matter в code-блоке — развёрнут, дубль # убран.
7. Аналитика без реальных ID не подключается (нет data-id=REPLACE_ME).
8. robots.txt → рабочий /sitemap.xml.
9. Футер: дубль «Дорожная карта»/«Changelog» убран; 10. зоны нажатия футера + width/height у lazy-картинок.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 23:53:58 +05:00
nns 5cb2c5934c test(uat): покрытие P1-P2 98% / P3 81% — цели go/no-go достигнуты
Some checks are pending
Auto-tag / Create date-tag (push) Waiting to run
CI / Backend (.NET 8) (push) Waiting to run
CI / Web (React + Vite) (push) Waiting to run
CI / POS (WPF, Windows) (push) Waiting to run
- browser-прогон доведён правками СМЫСЛА: filter:period (react-datepicker), точный sort
  по заголовку, смены (сид+драйвер открытия→POST), sort:vat (showVat), фильтр товаров (панель)
- build-coverage: цели go/no-go (P1-P2 95, P3 80, P4 70)
- матрица/цифры → docs/uat-coverage.html

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 21:53:59 +05:00
nns a2183e9532 perf(stock-report): покрывающий индекс движений (Phase45) — отчёт остатков 2.4с→1.1с на реальном объёме
Some checks failed
Auto-tag / Create date-tag (push) Waiting to run
CI / Backend (.NET 8) (push) Waiting to run
CI / Web (React + Vite) (push) Waiting to run
CI / POS (WPF, Windows) (push) Waiting to run
Docker API / Build + push API (push) Has been cancelled
Docker API / Deploy API on stage (push) Has been cancelled
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 21:29:27 +05:00
nns 6a7806ff08 perf(movements): считать total по базовой таблице без join (287k движений: count 1.1с→65мс)
Some checks are pending
Auto-tag / Create date-tag (push) Waiting to run
CI / Backend (.NET 8) (push) Waiting to run
CI / Web (React + Vite) (push) Waiting to run
CI / POS (WPF, Windows) (push) Waiting to run
Docker API / Build + push API (push) Waiting to run
Docker API / Deploy API on stage (push) Blocked by required conditions
На реальном объёме перенесённого магазина список движений отдавал >2.5с из-за COUNT по
3-table join. Count теперь по stock_movements с фильтрами (join не меняет число строк).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 21:27:37 +05:00
nns b04d3f0d0c feat(pos): окно выбора товара при скане ШК с несколькими карточками (дубли ШК)
Some checks are pending
Auto-tag / Create date-tag (push) Waiting to run
CI / Backend (.NET 8) (push) Waiting to run
CI / Web (React + Vite) (push) Waiting to run
CI / POS (WPF, Windows) (push) Waiting to run
- PosStore.FindAllByBarcode; SaleViewModel.ScanCandidates/IsScanPickerOpen + PickScanCandidate
- SaleView: модалка выбора; сервер by-barcode уже отдаёт items, веб-приёмка уже показывает выбор

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 21:04:20 +05:00
nns 30b39a7bcb docs(migration): сверка после фикса ревью — остатки 0, документы точны, долги по контрагенту
Some checks are pending
Auto-tag / Create date-tag (push) Waiting to run
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 20:58:26 +05:00
nns 1ee3c9b598 fix(migration): import — ChangeTracker.Clear при сбое товара (устранить каскад потери прогона)
Some checks are pending
Auto-tag / Create date-tag (push) Waiting to run
CI / Backend (.NET 8) (push) Waiting to run
CI / Web (React + Vite) (push) Waiting to run
CI / POS (WPF, Windows) (push) Waiting to run
Docker API / Build + push API (push) Waiting to run
Docker API / Deploy API on stage (push) Blocked by required conditions
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 20:48:18 +05:00
nns 99c2fc1e5a feat(migration-review): долги топ-20, UI «начальный остаток при переносе», дельта-таймер, прогресс
Some checks failed
Auto-tag / Create date-tag (push) Waiting to run
CI / Backend (.NET 8) (push) Waiting to run
CI / Web (React + Vite) (push) Waiting to run
CI / POS (WPF, Windows) (push) Waiting to run
Docker Web / Build + push Web (push) Has been cancelled
Docker Web / Deploy Web on stage (push) Has been cancelled
- 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>
2026-10-09 20:43:44 +05:00
nns 150947c5fb fix(migration): импорт переносит дубль-ШК и дубль-артикул карточки (дизамбиг артикула, пары товар-ШК)
Some checks are pending
Auto-tag / Create date-tag (push) Waiting to run
CI / Backend (.NET 8) (push) Waiting to run
CI / Web (React + Vite) (push) Waiting to run
CI / POS (WPF, Windows) (push) Waiting to run
Docker API / Build + push API (push) Waiting to run
Docker API / Deploy API on stage (push) Blocked by required conditions
- create: артикул-коллизия → суффикс msId (перенести карточку, не падать на unique)
- create/update: ШК не уникален → добавляем код каждой карточке (пары товар|код против
  повторов), дубли ловит «Проверка данных»

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 20:21:03 +05:00
nns b1bdf5c228 fix(migration): не схлопывать разные карточки МойСклада по артикулу + актуализировать объяснение сверки
Some checks are pending
Auto-tag / Create date-tag (push) Waiting to run
CI / Backend (.NET 8) (push) Waiting to run
CI / Web (React + Vite) (push) Waiting to run
CI / POS (WPF, Windows) (push) Waiting to run
Docker API / Build + push API (push) Waiting to run
Docker API / Deploy API on stage (push) Blocked by required conditions
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 20:11:06 +05:00