food-market/docs/site-fixes-2026-10-11/REPORT.md
nns e4d756e004
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): отчёт и скриншоты Круга 5 (плитки /signup не срезают цену, 320–402px)
Автопроверка 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

285 lines
23 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.

# Исправления публичного сайта test.food-market.kz — круг 2 (11.10.2026)
**Деплой:** только тестовый сайт через `~/.fm-watchdog/deploy-public-test.sh`
(commit `6f229eb`, статус `OK`). Прод, gateway nginx, прод-БД — не трогались.
**Образ отката:** `192.168.1.193:5001/food-market-public:test-pre-site-fixes-2`
(создан из текущего `:test` ДО деплоя). Откат: перетегировать его в `:test` и
`docker compose up -d public` на prod-vm.
**Автопроверка (Playwright, как человек):** 44/44 — см. `index.html` (desktop 1440
@2x + mobile 390 @3x, 13 скриншотов), сырые данные — `verify.json`.
---
## Уточнение поручения владельца по брендам (важно)
Было два сообщения владельца. Итоговая (уточнённая) трактовка, по которой сделано:
- **Убрать со всего сайта — ТОЛЬКО чужие СИСТЕМЫ УЧЁТА** рознцы (конкуренты):
«МойСклад» / «Мой склад» / MoySklad, «1С» / 1C. Grep по `dist`: **0 вхождений**
вне `/legal/*` (в `/legal/*` их и нет — проверено).
- **Платёжные системы, банки, маркетплейсы** (Kaspi Pay, Kaspi Magazin, Halyk,
Jusan, Forte, Wildberries, Ozon, Visa, Mastercard) — **НЕ** чужие системы учёта,
удалять не требовалось. Оставлены **только как честная пометка «в разработке»**
на `/integrations` и главной (без дат и обещаний), нигде — как готовая функция.
- Промежуточное (ошибочно расширенное) удаление Kaspi/маркетплейсов со страницы
`/integrations` **откатил** — вернул их в блок «В разработке» в прежнем виде
(Kaspi Pay, Kaspi Magazin, Ozon, Wildberries; ОФД РК).
- Из KB/блога/FAQ обещания уже подключённых способов оплаты/интеграций всё равно
убраны — но по причине «**этого нет в продукте**», а не «чужой бренд».
Где Kaspi/маркетплейсы остались (проверено): `/integrations` (блок «В разработке»)
и главная (FAQ — «в планах, сроков не называем»). Больше нигде.
---
## Сделано — по пунктам круга 2
### 1. Оставшиеся «ложные обещания» / честность текстов
- **`/kb/pos-setup`** — касса для **Windows и Linux**; вход = адрес сервера + логин
+ PIN (не «ключ организации»); установка «скоро»; принтеры «58/80 мм (ESC/POS)».
- **`/blog/quick-start`** — убран дубль `# H1`; «Импорт через API» → «Импорт из
других систем учёта — в разработке»; шаги установки .msi/ключ → сервер+логин+PIN;
меню лояльности/маркетинга → «раздел «Акции и скидки»», «лояльность — в расширенном
режиме»; обложка — скриншот продукта (не чужое стоковое фото).
- **`/blog/launch`** — убран дубль H1; «триал» → «честный бесплатный период»;
«Касса для Windows» → «Windows и Linux … приложение — скоро»; маркетплейсы/оплаты
→ «в разработке» (без дат); «все возможности CRM/лояльность/…» → «без доплат за
модули».
- **`/kb/faq`** — бэкапы «каждые 24 ч» → «регулярные»; «TLS 1.3» → «TLS» (без
версии); формулировка про ЗРК смягчена до «в соответствии с законодательством РК»;
импорт — файлы Excel/CSV, из других систем «в разработке»; **«триал» → «бесплатный
период»** (унифицировано); «с SLA» убрано.
- **Унификация «триал» → «бесплатный период»** по сайту (og.mjs тоже). В `/legal/*`
термин «Триал» оставлен как есть (юр. документы не трогаем).
- **og-картинки** перегенерированы (`node scripts/og.mjs`): без чужих систем учёта;
касса «Windows и Linux»; «90 дней бесплатно».
### 2. React #418 (hydration mismatch) на `/signup`
`SignupForm.tsx`: `?plan=` и параметры конфигуратора теперь читаются в `useEffect`
**после** гидрации, поэтому первый клиентский рендер совпадает с SSR-разметкой.
Проверка консоли на `/`, `/pricing`, `/signup?plan=business&…` и `/signup?plan=business`
— **ошибок нет, #418 отсутствует** (8/8 авто-проверок).
### 3. `/signup` без параметров конфигуратора
- `plan=business` без параметров → выбран **«Бизнес»** с дефолтной конфигурацией
**1/1/1/5 = 10 000 ₸** (показана карточка «Ваша конфигурация»). ✓ проверено.
- `plan=network` → «Сеть»; неизвестный план → «Старт». ✓
- Клик по плитке тарифа обновляет URL (`history.replaceState`).
- Плитка «Старт»: «5 000 ₸» → **«5 000 ₸/мес»**; цены плиток без переноса.
### 4. Типографика KB/блога
- `.prose-md` (h2/h3, списки, таблицы, ссылки, код, цитаты) вынесена в
`global.css` — грузится на всех страницах; `/kb/*` больше **не плоский текст**
(раньше стиль был только на странице блога). ✓ проверено (`h2`, `ul li` в
`.prose-md`).
- Блог: убран дублирующий `<h1>` (в теле статей) — на странице ровно один H1. ✓
### 5. Мелочи
- **sitemap.xml** — канонические URL **со слэшем** (убраны 301), добавлены статьи
KB и блога. ✓
- **Footer** «Status» → **«Статус»**.
- **`/changelog`** — убран внутренний жаргон (Phase N, SuperAdmin, retention
period, tenant, inline, Read-only/Edit-mode) → человеческие формулировки;
заголовок «Что нового». ✓
- **`/pricing`** — на конструкторе «Бизнес» бейдж **«Популярный»** (как на главной)
+ **«90 дней бесплатно»**; у «Старт» убран ложный пункт «Импорт из других систем».
- Шапка ~1050px: десктоп-меню переведено на `xl` (до 1280px — гамбургер), CTA без
переноса → на ~1050px и на мобильном меню/кнопка **не ломаются в 2 строки**. ✓
- Инлайн-ссылки в тексте — увеличенная зона нажатия (padding без сдвига вёрстки).
- Эмодзи-фолбэк-стек в `body` (чтобы эмодзи не были квадратами там, где нет
цветного emoji-шрифта).
### 6. Не трогал
`/legal/*` и контакты-плейсхолдеры («[НАЗВАНИЕ ТОО]», «[БИН]», «+7 (___)») — без
изменений. Бренд ALL MARKET, цвета, шрифты — без изменений.
---
## Дополнение по тесту на Android (Firefox 157) — сделано
1. **Мобильное меню + кнопка «Назад» Android.** При открытии панели кладём запись
в историю (`pushState`), закрываем по `popstate` → системная «Назад» закрывает
меню, а не уводит со страницы. Esc/тап-вне/крестик остались. ✓ проверено
(`m-after-back.png` — после «Назад» панель закрыта, остались на `/`).
2. **Состав мобильной панели.** Добавлены «Интеграции» (в основную навигацию) и
внизу панели вторичные ссылки **«Статус»** и **«Что нового»** (раньше были только
в футере). ✓
3. **«Настроить тариф» (главная)** → `/pricing#configurator` со скроллом к
конструктору (у блока `id="configurator"` + `scroll-mt-20`). ✓ якорь есть.
4. **Ползунки конструктора на тач.** Крупная ручка (28px), `touch-action: pan-y`
на инпуте (вертикальный свайп скроллит страницу, а не двигает значение), и
кнопки **«−/+»** у каждого значения (менять без перетаскивания). ✓ проверено.
5. **`/kb/billing`.** Проверено по коду `src/food-market.*`: биллинг/подписки в
продукте **нет** (в вебе явная заглушка «до Phase 4 «Подписки»»; единственная
сущность `Subscription` — это `WebPushSubscription`, push-уведомления). Поэтому
убраны несуществующие: «Настройки → Подписка → История» (скачивание счетов/чеков),
e-mail-напоминания, баннер в админке, формула кредита при понижении, SLA для
«Сеть». Переписано честно: оплата на раннем доступе — вручную через поддержку,
онлайн-оплата и личный кабинет «в разработке». Цены «тг» → **«₸»**. ✓
6. **`/status`.** Убраны фиктивные зелёные «● Работает» (мониторинга нет) — честная
страница «в разработке» + контакты для инцидентов (реальный `/health` не
подключал: это требует серверной части, вне правки статического сайта). ✓
---
## Решения, требующие внимания владельца
1. **Контракт API регистрации.** Форма отправляет `plan`, а для «Бизнес» ещё и
`shops/cashes/warehouses/employees` (вперёд-совместимо). **Текущий серверный
контракт `SignupInput` принимает только `plan`** — конфигурация конструктора на
бэкенде пока игнорируется. Нужно решение: принимать ли её на сервере (тогда —
отдельная задача по API) или оставить как сейчас.
2. **Оборудование на `/integrations`.** В «Уже работает» вернул конкретику «весы
CAS, Масса-К и совместимые» (это производители **весов**, не системы учёта, —
под уточнённое поручение не попадают). Если хотите — заменю на нейтральное
«популярные протоколы».
3. **Юр. документы / реквизиты.** В `/legal/*` чужих систем учёта и брендов нет —
список пуст, ничего выносить не требуется. Плейсхолдеры реквизитов не трогал.
---
## Проверка (как в задаче)
| Критерий | Результат |
|---|---|
| Консоль чистая на `/`, `/pricing`, `/signup` (вариации), React #418 нет | ✓ |
| `plan=business` без параметров → «Бизнес» 10 000 (1/1/1/5) | ✓ |
| `dist`/живой сайт: 0 «МойСклад/Мой склад/moysklad/1С/1C» вне `/legal/*` | ✓ |
| Kaspi/маркетплейсы — только «в разработке» на `/integrations` и главной | ✓ |
| Унификация «бесплатный период»; «тг» → «₸» в KB | ✓ |
| Типографика KB (h2/списки) + один H1 в блоге | ✓ |
| sitemap — канонические URL со слэшем + KB/блог | ✓ |
| Моб.: «Назад» закрывает меню; состав панели; ползунки −/+ | ✓ |
| `/status` без фиктивного статуса; `/changelog` без жаргона; `/kb/billing` честный | ✓ |
Итог авто-проверки: **44/44**.
---
## Догоняющие правки (сверка с канонической редакцией задачи)
При повторной сверке с полным списком задачи закрыты оставшиеся хвосты
(commit `28cc6a7`, передеплой на test — `OK`):
- **`/kb/quickstart`** (отдельный файл от блога — его пропускал ранее): убраны
`.msi`, «ключ организации», «импорт по API-токену» → импорт из файла Excel/CSV,
из других систем «в разработке»; касса Windows и Linux «скоро», вход по адресу
сервера + логин + PIN.
- **`/blog/cash-with-scales`** — убран дублирующий `<h1>` в теле (теперь во всех
трёх статьях блога ровно один H1 — проверено в `dist`).
- **«до 100 000 товаров»** (kb/faq + og) — в коде точного лимита нет (есть только
`RequestSizeLimit(20MB)` на эндпоинте импорта), поэтому заменено на нейтральное
«большие каталоги — тысячи позиций».
- **Кнопка «Выбрать конфигурацию»** — цена «₸/мес» больше не переносится
(`whitespace-nowrap`).
- **Инлайн-ссылки «офертой»/«политикой»** в форме регистрации — увеличенная зона
нажатия (`py-1`) без изменения вида.
**ОС кассы — проверено по коду:** `food-market.pos.csproj` → `TargetFramework
net8.0` (не `net8.0-windows`) + Avalonia (кроссплатформенный UI) → сборка под
**Windows и Linux** реальна, формулировка на сайте честна (приложение для
скачивания — «скоро»).
**Живой grep (curl) по всем страницам `/kb/*` и `/blog/*`:** нет `.msi`,
`API-токен`, `ОКП`, `Kaspi Magazin`, `Wildberries`, `Ozon`, `TLS 1.3`,
`100 000`, `триал`, `SIN EXCEPCION`. Обложка `/blog/quick-start` =
`/screenshots/catalog.webp` (скриншот продукта, без чужого фото).
---
## Круг 3 (финальный прогон этапа 1, 11.10 — Chrome/Win11 VM)
Две мелкие правки, деплой только на тест (`test.food-market.kz`, commit `a25b940`,
статус `OK`; образ отката `test-pre-site-fixes-3` создан до деплоя).
1. **Касса подаётся единообразно честно.** Раньше /status, /pos, /kb/pos-setup
писали «скоро», а главная и /about — как готовую. Привёл к одному виду: касса
для Windows и Linux, **приложение для скачивания — «скоро»** (как на /pos).
- главная — карточка «Продажи и касса»: «…для Windows и Linux, работает без
интернета. Приложение для скачивания — скоро.»
- /about, «Что уже работает»: «Касса … для Windows и Linux, работает без
интернета (приложение для скачивания — скоро).»
Проверено живым grep и скриншотами (главная/ about) на 1280 и 390.
2. **Знак «₸» не переносится в тарифах.** `whitespace-nowrap` + неразрывные
пробелы: «10 000 ₸» / «14 000 ₸» (конструктор «Бизнес»), «5 000 ₸/мес» («Старт»),
CTA «… 10 000 ₸/мес». Проверка: высота строки цены конструктора 36px (одна
строка) на 1280 и 390 — не разрывается.
Скриншоты: `k3-pricing-1280.png`, `k3-pricing-390.png`, `k3-about-1280.png`.
Автопроверка (Playwright): 5/5. Юридические реквизиты не трогал (отложены до
продакшна). Прод-сайт не трогал.
---
## Круг 4 (прогон этапа 1 в Safari на iPhone 17, ширина 402 — 12.10)
Круг 3 закрыл разрыв цены **только на /pricing**. Прогон в Safari (симулятор
iPhone 17) нашёл ещё два места, где «сумма + ₸ + /мес» рвётся по строкам:
1. **Главная, строка под кнопками героя** — «Подписка от 5 000 ₸/мес»: «5» на
одной строке, «000 ₸/мес» на следующей.
2. **/signup после конфигуратора «Бизнес»** — итог «14 000 ₸/мес» рвался после
«₸/» (слэш — точка переноса), плитки тарифов — так же.
Исправлено **системно**, а не точечно (commit `a0f9e0b`, деплой только на тест
`test.food-market.kz`, статус `OK`):
- **`lib/pricing.ts` — единый источник правды:**
- `fmtKzt` теперь ставит неразрывные пробелы (U+00A0) между разрядами и перед
«₸» → сумма с «₸» никогда не рвётся;
- новый `fmtKztMonth` = сумма + «₸» + «/мес» одним куском: word-joiner (U+2060)
вокруг «/» запрещает перенос на слэше.
- **`SignupForm.tsx`** — плитки «Старт»/«Бизнес» и итог «Ваша конфигурация
„Бизнес“» используют `fmtKztMonth` (+ `whitespace-nowrap` на итоге).
- **`index.astro`** — hero-строка и карточки «Старт»/«Бизнес» (`whitespace-nowrap`
+ `&nbsp;`); «от» в «Бизнес» остаётся переносимым, цена — нет.
- **`BusinessTariffBuilder.tsx`** — подпись «База 10 000 ₸» обёрнута в `nowrap`.
- **Контент `kb/billing.md`, `kb/faq.md`, `blog/launch.md`, `FAQ.tsx`** — суммы
с nbsp + word-joiner, чтобы цена не рвалась и в тексте статей/ответов.
**Автопроверка (Playwright, Safari-UA iPhone 17):** ширины **320, 375, 390, 402**
× страницы **главная, /pricing, /signup?plan=start, /signup после «Бизнес»** —
**44/44 passed**. Высоты строк цен: hero 15px, плитки 16px, итог «Бизнес» 20px,
конструктор 36px — везде **одна строка**. Горизонтальной прокрутки нет ни на одной
ширине. Текст итога «Бизнес» = `14 000 ₸⁠/⁠мес` (неразрывный).
Скриншоты (`docs/site-fixes-2026-10-11/`): `k4-home-{320,375,390,402}.png`,
`k4-pricing-*.png`, `k4-signup-start-*.png`, `k4-signup-biz-*.png`.
Скрипт: `tests/e2e/tools/site-fixes-verify-4.mjs`.
Остальное в прогоне владельца чисто (меню, «Назад», тарифы, выбор
Старт/Бизнес/Сеть, нет горизонтальной прокрутки на 25 страницах) — не трогал.
Юридические реквизиты не трогал. Прод-сайт не трогал. Весы — пауза в силе.
---
## Круг 5 (прогон этапа 1 в Chrome 154 на dev-android, 360css — 12.10)
Регрессия от Круга 4 (`a0f9e0b`): на /signup `whitespace-nowrap` делал цену
плитки тарифа **шире узкой колонки** (плитка ~87px, контента ~65px на 360px).
«14 000 ₸/мес» (scrollWidth 77 > 65) срезался — на экране «14 000 ₸/ме».
Исправлено (commits `a5f885c`, `ee5c7ec`; деплой только на тест, статус `OK`):
- **Плитки тарифа `/signup` — сумма и «/мес» на разных строках.** Сумма+«₸» —
одной неразрывной строкой (`whitespace-nowrap`, видна целиком), «/мес» —
отдельной строкой под суммой (меньшим кеглем). Плитки остаются в 3 колонки,
внутри суммы переноса нет, хвост не срезается.
- **Плитка «Сеть» — «по запросу» переносится по словам** (это не сумма, nowrap
ей не нужен; на 320px слово не влезало в колонку).
- Итог «Ваша конфигурация „Бизнес“» и карточки тарифов на главной — без
изменений (там полноширинные строки, запаса хватает).
**Автопроверка (Playwright, Chrome-154/Android-UA):** ширины **320, 360, 375,
390, 402** × `/signup?plan=start` и `/signup?plan=business&shops=3&cashes=5&
warehouses=5&employees=10` (итог **18 000 ₸/мес**) + главная. Для каждой плитки
проверено, что `scrollWidth ≤ clientWidth` (нет переполнения/среза): **52/52
passed**. Суммы «5 000 ₸», «10 000 ₸», «18 000 ₸» — `priceOver=0` на всех
ширинах. Итог «Бизнес» = `18 000 ₸⁠/⁠мес`, одна строка (20px). Горизонтальной
прокрутки нет.
Скриншоты (`docs/site-fixes-2026-10-11/`): `k5-signup-start-{320,360,375,390,402}.png`,
`k5-signup-biz-*.png`, `k5-home-360.png`. Скрипт: `tests/e2e/tools/site-fixes-verify-5.mjs`.
Весы — пауза в силе, не трогал. Прод-сайт и реквизиты не трогал.