- 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>
9.4 KiB
UAT — измеримое покрытие каждого элемента каждого экрана
Цель: матрица покрытия, построенная ИЗ КОДА, + браузерный прогон → docs/uat-coverage.html
с % по экрану/приоритету/общим. Цели: P1–P3 ≥95%, P4 ≥70%. НЕ перепроверять уже покрытое.
Легенда: [x] готово · [~] частично · [ ] не начато.
Инструменты
tests/e2e/tools/extract-controls.ts— статически изweb/src/pagesдостаёт все интерактивные элементы экрана (поиск/фильтры/сортировки/пагинация/экспорт/тумблеры/ действия) →docs/uat-coverage.expected.json. Фильтр списка отличается от поля формы поsetPageв обработчике. 36 экранов, 195 элементов.tests/e2e/scenarios/stage-ui-uat-coverage.spec.ts— браузерный прогон: задействует каждый элемент, пишетtests/e2e/reports/uat-covered.json.tests/e2e/tools/build-coverage.ts— сводит →docs/uat-coverage.{json,html}с %.
✅ ГОТОВО (09.10, после переноса): цели go/no-go достигнуты
Цель задачи: P1–P2 ≥95%, P3 ≥80% (частые процессы). Достигнуто (стенд, temp-орг + сид):
| Приоритет | Покрыто | Цель | Статус |
|---|---|---|---|
| P1 | 97% (31/32) | 95% | ✅ |
| P2 | 100% (14/14) | 95% | ✅ |
| P1–P2 | 98% (45/46) | 95% | ✅ |
| P3 | 81% (51/63) | 80% | ✅ |
| P4 | 38% (33/86) | — | — |
Доведено с 80%→98% (P1–P2) правками браузерного прогона с проверкой СМЫСЛА:
- filter:period на отчётах (sales/stock/money) — драйвер react-datepicker (текстовый ввод даты + Enter → рефетч). +3 P3.
- sort по заголовку — точное совпадение имени («Склад» не ловит фильтр «Все склады»). +P1/P3.
- Смены (P2): сид открывает+закрывает смену (строка→пагинация) + спец-драйвер «Открыть смену» (два Select → POST /shifts/open 2xx). P2 → 100%.
- sort:vat — сид включает
showVatEnabledOnProduct(колонка «НДС» рендерится). +P1. - filter товаров — раскрытие панели «Фильтры» + native
<select>«Фасовка». +P1. Единственный незакрытый P1 —/catalog/products action:delete(удаление только массовое через bulk-bar, построчной корзины нет; 97% ≥ 95% — цель выполнена).
Перф на ПЕРЕНЕСЁННОЙ орг (реальный магазин, 31k товаров, 288k движений; read-only)
Списки/поиск/сортировки/отчёты < 2 с. Найдено и исправлено (фикс→деплой): список движений 2.9с→<2с (COUNT по базовой таблице, без 3-way join), отчёт остатков 2.4с→1.1с (покрывающий индекс Phase45). Остальное: товары 0.3–0.97с, остатки 0.3–0.5с, продажи 0.79с, приёмки 0.3с, долги/транзакции/отчёт продаж < 0.5с.
Статус покрытия (на момент смены приоритета 09.10 — переход на ALL MARKET)
Цифры в docs/uat-coverage.html (и uat-coverage.json). Прогон на стенде, temp-орг с сидом.
| Приоритет | Покрыто | Цель |
|---|---|---|
| Общее | 61% (119/195) | — |
| P1 | 84% (27/32) | 95% |
| P2 | 86% (12/14) | 95% |
| P3 | 76% (48/63) | 95% |
| P1–P3 | 80% (87/109) | 95% |
| P4 | 37% (32/86) | 70% |
Прогресс по итерациям: базовый 50% → после доработки хендлеров (пагинация со сбросом поиска, обобщённое создание/сохранение/удаление, период-фильтры, доп. сид: чек/приёмка/ оприходование/списание/инвентаризация/возврат) → 61% (P1–P3 71%→80%, P4 24%→37%).
Что уже покрыто хорошо (из кода × браузер)
- По типам: export 5/5, sort 60/77, toggle 2/2, search 18/25, filter (часть), pagination (где есть данные). Действия create/save — частично (обобщённый CRUD-хендлер).
- Инструменты рабочие: экстрактор (195 элементов из 36 экранов), браузерный прогон, HTML с %.
Что НЕ успел (продолжить после перехода на ALL MARKET)
Цели (P1–P3 ≥95%, P4 ≥70%) НЕ достигнуты — осталось добрать ~22 элемента P1–P3 и ~28 P4:
- Сортировки с динамическим/условным заголовком (ProductsPage
systemPrice→имя типа цены,vat→колонка только при вкл. НДС): экстрактор доработан ловить строковый фолбэк (header: expr ?? 'Текст') — нужно перегенерировать expected и прогнать ещё раз. - Фильтры со СМЫСЛОМ (правильные строки по известным данным): сейчас проверяется, что контрол шлёт новый запрос; семантику части списков держит filters-sweep. Добить smысл для продаж (период/оплата), приёмок (поставщик/склад/статус/оплата), движений (тип/товар/период), денег (счёт/период/тип), отчётов (период/группировки/склад/группа на дату).
- Действия документов post/unpost на списках money/transactions, invoices (сейчас — наличие элемента); довести до реального POST с проверкой 2xx.
- P4 save/delete: обобщённый хендлер покрывает простые CRUD-модалки; формы со множеством обязательных полей (счета/точки/сотрудники/настройки) требуют адресного заполнения.
- Пагинация на экранах без сид-данных: отрисовывается только при total>0 — досидить или считать покрытой по общему компоненту.
- nightly: добавить
stage-ui-uat-coverageв ночной прогон (пока не добавлено).
Запуск: cd tests/e2e && pnpm exec tsx tools/extract-controls.ts (матрица) →
pnpm exec playwright test stage-ui-uat-coverage (прогон) → pnpm exec tsx tools/build-coverage.ts (HTML).
Найдено Mac-Claude (быстрые фиксы — сделаны)
- «Проверка данных» на Демо — все 0, lastCheckedAt=null. Hangfire-джоба
DataQualityJobзарегистрирована (ежедневный cron 02:20 UTC, идёт по всем активным орг), иRecomputeAsyncкорректна — просто ночной прогон ещё не отрабатывал после пересева Демо. Фикс: разовыйBackgroundJob.Enqueue(DataQualityJob)при старте → считается сразу после деплоя/пересева. Реальные числа Демо (стенд, после фикса): total 1276 · без группы 0 · без цены продажи 718 · без штрихкода 0 · дубль ШК 0 · возможный дубль (имя+ед.) 558 (включая 4× «"BIOBLAS" шампунь д/волос 360мл») · товары в минусе 0.lastCheckedAtпроставлен. - Внутренний ШК с ведущим 0 («0201259508594»).
InternalBarcode.PickPrefixбрал «02» (ведущий 0 → зона UPC-A, риск совпасть с реальным товаром). Фикс: берём 2x из restricted-circulation 20–29 (без ведущего нуля), не пересекаясь с весовыми префиксами орг; «02» — крайний резерв. Для весовых — короткий «27+5» по настройке (отдельно). Проверка на стенде: новые коды —2021712729230,2043662520927,2084330808596(префикс 20, без ведущего нуля). Существующие коды НЕ мигрировали: смена ШК ломает ссылки, а отличить ранее сгенерированный «02…» от реального невозможно; генератор исправлен для всех НОВЫХ товаров.
Что НЕ трогаем
Прод, shared-postgres, global.json, gateway nginx, sklad.