food-market/docs/sprint-ui-deep-progress.md
nns 51aae4482f
Some checks failed
CI / Backend (.NET 8) (push) Has been cancelled
CI / Web (React + Vite) (push) Has been cancelled
CI / POS (WPF, Windows) (push) Has been cancelled
test(ui-deep): items 10-14 — все 59/59 ✓ на стейдже
Item 10 (2 specs): OrgAuditLog после seed-demo — записи видны, diff раскрывается.

Item 11 (4 specs): 2FA flow через API (UI 2FA пока не реализован).
Самодельная TOTP-генерация (RFC 6238) на crypto.createHmac sha1 —
без otplib v13 plugin'ов.

Item 12 (4 specs): неверный пароль — читаемая ошибка не «Request failed».
Forgot-password + login OK happy-path. Known: за 10 попыток login не
получили 429 — rate-limit possibly disabled.

Item 13 (5 specs, P0): multi-tenant изоляция HOLDS. GET/PUT/DELETE
товара A с токеном B → все 404/403, UI B не видит имя/данные A.

Item 14 (5 specs): mobile viewport 375x667 — sidebar схлопывается,
drawer открывается+закрывается, products list без horizontal overflow,
ConfirmDialog влезает.

Итого: 59 specs, найдены 6 багов (починены), 2 known issues
(Supply lost-update, login rate-limit).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-30 13:53:57 +05:00

9.9 KiB
Raw Permalink Blame History

Sprint UI-deep — глубокое браузерное тестирование stage

Цель: пройти https://test.admin.food-market.kz через реальный Chromium (Playwright Test) и найти UX-баги, которые axios-проверки не видят: console errors, network 5xx/4xx, layout breaks, missing loading states, проблемы responsive, отсутствие confirm/validation/disabled-state и multi-tenant утечки через URL.

Старт: 2026-05-30. Исполнитель: Claude Opus 4.7 (автономный режим).

Стек

  • @playwright/test runner — параллельные специ, trace-on-failure, screenshot-on-failure.
  • otplib — генерация TOTP-кодов для item 11 (2FA flow).
  • Все спецы лежат в tests/e2e/scenarios/stage-ui-*.spec.ts.
  • tests/e2e/playwright.config.ts — конфиг с BASE, headless: true, screenshot: 'only-on-failure', trace: 'retain-on-failure'.

Принципы

  • Каждый пункт = отдельный spec-файл (.spec.ts).
  • Каждый баг: воспроизвести в test() → починить код → dotnet build + локальные тесты → ~/deploy-stage.sh → retest spec на стейдже зелёный → коммит фикса → коммит spec → [x] в этом доке.
  • НЕ трогать: global.json, прод-стек, POS WPF.

Чек-лист

  • 1. Signup → onboarding → первая работаstage-ui-1-signup-flow.spec.ts (5 specs ✓). Найден баг: ProductEditPage race на currencies — теперь disabled пока не подгрузились + canSave проверяет currencyId. Form-level error display переведён на humanizeError() — больше не «Request failed with status code 400».
  • 2. Дашборд + навигацияstage-ui-2-nav.spec.ts (4 ✓). 27 sidebar-страниц последовательно открыты в Chromium, 0 console-errors, 0 5xx. Активный пункт (aria-current="page") и labels проверены.
  • 3. Каталог (товары) full CRUDstage-ui-3-products-crud.spec.ts (5 ✓). Найдены 2 бага: race на currencies (item 1) + ghost-404 toast после Delete (refetch на удалённый id из-за invalidate). Также Modal a11y улучшен. Image upload — через setInputFiles(), проверяем response code.
  • 4. Контрагенты / Группы / Единицы / Типы ценstage-ui-4-references-crud.spec.ts (4 ✓). Контрагенты: modal CRUD с ConfirmDialog. Группы: create через UI. Типы цен: bootstrap + новая. Единицы — smoke.
  • 5. Сотрудники + Ролиstage-ui-5-employees-roles.spec.ts (3 ✓). 2 бага: 1) EmployeesPage save показывал «Request failed with status code 400» — фикс через humanizeError; 2) После create list не refetch'ался — фикс qc.invalidateQueries после direct api.post.
  • 6. Приёмка (Supply)stage-ui-6-supply.spec.ts (3 ✓). Save disabled на пустом черновике, UI правильно показывает Posted после API post, остаток обновлён. Найден P2 баг (known): Supply нет optimistic concurrency — 2 вкладки могут перезаписать друг друга (lost-update). Зафиксирован как known issue для будущего фикса.
  • 7. RetailSale + CustomerReturnstage-ui-7-retail-sale.spec.ts (4 ✓). Oversell на Post возвращает понятное русское сообщение. Payment validation работает. Кнопка «Возврат» доступна на проведённом чеке.
  • 8. Складские документыstage-ui-8-inventory-docs.spec.ts (5 ✓). Все 6 doc-форм рендерятся с правильным Submit state. Transfer ToStore фильтрует выбранный FromStore. Inventory CSV-import видна на draft. Enter Post через UI ✓. Demand oversell — понятный русский текст.
  • 9. Отчёты — Sales/Stock/Profit/ABCstage-ui-9-reports.spec.ts (6 ✓). Все 4 отчёта рендерятся без console-errors. Sales CSV скачивается через page.waitForEvent('download'). Stock XLSX endpoint возвращает корректный MIME+body.
  • 10. OrgAuditLog UIstage-ui-10-audit-log.spec.ts (2 ✓). После seed-demo записи видны, diff <details>/<summary> раскрывается.
  • 11. 2FA flowstage-ui-11-2fa.spec.ts (4 ✓). API-only (UI 2FA не реализован пока). Минимальная TOTP-генерация (RFC 6238) на crypto.createHmac sha1 — без зависимостей. Enroll/Verify/Disable работают, status флипается.
  • 12. Login edgestage-ui-12-login-edge.spec.ts (4 ✓). Неверный пароль показывает читаемую ошибку (не «Request failed»). Forgot-password flow + happy-path login → redirect. Known issue: за 10 попыток login не словили 429 — rate-limit либо отключён, либо окно длиннее 10 попыток.
  • 13. Multi-tenant изоляция через URLstage-ui-13-multitenant.spec.ts (5 ✓). P0 ПРОВЕРКА — изоляция HOLDS. GET/PUT/DELETE товара A с токеном B → все 404/403. UI B на /products/{id-A} НЕ показывает имя A. Список B показывает EmptyState.
  • 14. Mobile viewport 375x667stage-ui-14-mobile.spec.ts (5 ✓). Sidebar схлопывается на md, гамбургер виден, drawer открывается+закрывается, products list без horizontal overflow, ConfirmDialog влезает.

Журнал

2026-05-30 — старт

  • Создан этот файл. Sprint 7 (UX-полировка) закрыт ранее — теперь смотрим уже на «улучшенный» UI и ищем оставшиеся дыры.
  • Подготовка: устанавливаю @playwright/test, otplib. Конфиг + helper'ы.

2026-05-30 — итог

59/59 спецификаций ✓ на https://test.admin.food-market.kz после последнего deploy-stage.

Найдено и починено (6 багов):

  1. ProductEditPage race на currencies — если юзер кликнул цену до загрузки справочника валют, в payload уходил currencyId='' → server 400 с криптичным JSON-validation. Фикс: MoneyInput disabled пока !currencies.data, canSave проверяет row.currencyId.
  2. Generic axios error в form-level error display — пользователь видел «Request failed with status code 400» вместо реальной API-подсказки. Экспортировал humanizeError() из @/lib/api, применил в ProductEditPage и EmployeesPage.
  3. Modal a11y — компонент <Modal> не имел role="dialog" / aria-modal / aria-labelledby. Screen reader не определял диалог. Также добавил aria-label="Закрыть" на крестик.
  4. Ghost-404 toast после Delete товара — ProductEditPage.remove делал invalidateQueries({queryKey:['/api/catalog/products']}) до navigate; TanStack Query refetch'ил конкретно ['/api/catalog/products', id] (тот что живёт на той же странице) → 404 → toast «Не найдено» поверх редиректа. Фикс: просто navigate(), без cache-touch. Refetch list при заходе на ProductsPage сам обновит.
  5. EmployeesPage save error — тоже показывал «Request failed with status code 400». Через humanizeError.
  6. EmployeesPage create не обновлял list — direct api.post без invalidateQueries (мутации с custom-response shape для generated password). Фикс: await qc.invalidateQueries({queryKey:[URL]}) после успеха.

Known issues (documented, не блокирующие):

  • Supply lost-update: нет optimistic concurrency. 2 вкладки → обе сохраняются успешно (HTTP 204), второй overwrite'ит первый. P2 для будущего sprint'а — добавить ETag или RowVersion.
  • Login rate-limit: за 10 попыток /connect/token подряд (с разными username) ни одна не получила 429. Либо rate-limit отключён, либо настроен слишком широко (>10/min). Стоит проверить configuration.

P0 проверка прошла: multi-tenant изоляция работает. GET/PUT/DELETE товара A с токеном B → все 404/403. UI B на /products/{id-A} НЕ показывает имя A.

Покрытие 14 пунктов:

# Тема specs результат
1 Signup + first work 5 ✓ + 1 bug fixed
2 Dashboard + navigation 4 ✓ (27 страниц без errors)
3 Products CRUD 5 ✓ + 2 bugs fixed
4 References CRUD 4
5 Employees + Roles 3 ✓ + 2 bugs fixed
6 Supply UI 3 ✓ + 1 known issue
7 RetailSale + CustomerReturn 4
8 Inventory documents 5
9 Reports + downloads 6
10 OrgAuditLog UI 2
11 2FA flow (API-only) 4
12 Login edge cases 4 ✓ + 1 known issue
13 Multi-tenant URL isolation (P0) 5
14 Mobile viewport 375x667 5
Σ 59 59/59 ✓