food-market/tests/e2e/reports/full-cycle-2026-05-07-baseline.md
nns 7bb941259a
Some checks are pending
CI / POS (WPF, Windows) (push) Waiting to run
CI / Backend (.NET 8) (push) Successful in 1m20s
CI / Web (React + Vite) (push) Successful in 42s
feat(e2e): infrastructure + first full-cycle scenario + baseline report
Декларативные end-to-end сценарии в tests/e2e/. YAML описывает шаги,
TypeScript-handler — конкретные API/UI/DB-проверки. Отчёт в Markdown.

Структура:
- runner.ts        : entry, парсит YAML, прогоняет steps, пишет report
- run.sh           : pnpm install + tsx
- lib/api.ts       : axios + login() (через /connect/token + /api/me)
- lib/db.ts        : docker exec psql, resetTenantData(), countRows()
- lib/report.ts    : Markdown-аккумулятор (steps + bugs + ux + gap + perf)
- scenarios/full-cycle.yml       : 12 шагов
- scenarios/full-cycle.steps.ts  : handlers (один на шаг)
- README.md        : как добавить новый сценарий

reset_db в preconditions:
- TRUNCATE tenant-таблиц CASCADE
- AspNet*/users — оставляем только admin@food-market.local
- OpenIddict tokens — все valid → revoked
- Реестр products + системные справочники + миграции + platform_settings — НЕ трогаем

Запуск: tests/e2e/run.sh full-cycle [--api-only]

Первый прогон (--api-only, baseline в reports/full-cycle-2026-05-07-baseline.md):
- 8 ✓ / 1 ✗ / 3 ◯ из 12.
- Critical bug: Cashier видит /api/organization/employees через API
  (нет [Authorize(Roles="Admin")] на List endpoint).
- High: при CreateOrg через SuperAdmin не сидируются tenant-units —
  пустой каталог измерений у новой org (DevDataSeeder.SeedTenantReferencesAsync
  должен вызываться, но не вызывается).
- Logic gaps: реестр products tenant-scoped и новая org стартует с
  пустым каталогом; SuperAdmin /organizations не валидирует ФЛК
  телефона; Cashier не получает Identity-роль "Cashier" при создании
  через /employees.

UI-шаги (Playwright) в этом коммите не покрыты — runner работает в
--api-only режиме. UI-extension добавим следующим коммитом, не блокирует
получение полезного отчёта.
2026-05-08 00:05:52 +05:00

127 lines
5.8 KiB
Markdown
Raw Permalink 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.

# E2E report: full-cycle
Запущен: 2026-05-07T19:05:02.083Z
Длительность: 5.2с
**Итог:** 8 ✓ / 1 ✗ / 0 ⚠ / 3 ◯ (всего 12)
## ✓ Step step01_create_organization: SuperAdmin создаёт «Test Shop {timestamp}» (KZ, KZT, ФЛК телефона)
Длительность: 1444мс
| Тип | Проверка | Результат |
|---|---|---|
| api | POST /api/super-admin/organizations → 200 | ✓ org=Test Shop 1778180702083 |
| api | GET /api/super-admin/organizations включает созданную org | ✓ |
## ✓ Step step02_create_first_admin: SuperAdmin создаёт первого Admin сотрудника организации (Employee + AppUser)
Длительность: 576мс
| Тип | Проверка | Результат |
|---|---|---|
| api | Temp password возвращён CreateOrgResult | ✓ len=12 |
| db | employees содержит ровно 1 запись для новой org | ✓ count=1 |
| db | AspNetUserRoles содержит role=Admin для нового user | ✓ Admin |
## ✓ Step step03_login_as_admin: Логин под admin (не SuperAdmin override) — JWT с org_id и role=Admin
Длительность: 588мс
| Тип | Проверка | Результат |
|---|---|---|
| api | /connect/token password-grant выдал токен | ✓ |
| api | /api/me содержит role=Admin | ✓ Admin |
| api | /api/me содержит правильный orgId | ✓ 5c99fced-3182-4b7e-9575-27111c29419d |
## ✓ Step step04_create_storekeeper_and_cashier: Admin создаёт Storekeeper и Cashier через /settings/employees
Длительность: 1398мс
| Тип | Проверка | Результат |
|---|---|---|
| api | employee-roles list | ✓ 200, total=3 |
| api | Системная роль «Кладовщик» существует | ✓ |
| api | Системная роль «Кассир» существует | ✓ |
| api | POST /api/organization/employees (Кладовщик) | ✓ 200 |
| api | POST /api/organization/employees (Кассир) | ✓ 200 |
| db | employees total = 3 (admin + keeper + cashier) | ✓ count=3 |
| api | Невалидный email отвергается при createAccount | ✓ 400 |
## ✗ Step step05_login_as_cashier: Логин под Cashier — role-guard проверяется (sidebar/role guard)
Длительность: 699мс
| Тип | Проверка | Результат |
|---|---|---|
| api | /api/me содержит роль соответствующую системной Cashier | ✗ no Identity roles |
| api | Cashier → GET /api/organization/employees → 403 | ✗ 200 |
| api | Cashier → GET /api/sales/retail-sales — доступен | ✓ 404 |
## ✓ Step step06_create_counterparty: Admin создаёт «ТОО Тест Поставщик» (БИН + телефон)
Длительность: 183мс
| Тип | Проверка | Результат |
|---|---|---|
| api | POST /api/catalog/counterparties | ✓ 201 |
## ✓ Step step07_ensure_main_store: Проверить что есть main store (из bootstrap), иначе создать
Длительность: 90мс
| Тип | Проверка | Результат |
|---|---|---|
| api | GET /api/catalog/stores | ✓ 200 |
| db | Main store существует (от bootstrap) | ✓ Основной склад |
## ✓ Step step08_create_supply: Admin создаёт Supply Draft (3-5 товаров) и проводит (Posted)
Длительность: 168мс
## ◯ Step step09_check_stock_after_supply: GET /api/inventory/stock — quantity увеличился на supplied amount
Длительность: 1мс
## ✓ Step step10_ensure_retail_point: Проверить или создать розничную точку (кассу)
Длительность: 84мс
| Тип | Проверка | Результат |
|---|---|---|
| api | RetailPoint существует | ✓ Касса 1 |
## ◯ Step step11_create_retail_sale: Admin создаёт RetailSale, 2 позиции из приёмки, cash, Post
Длительность: 1мс
## ◯ Step step12_check_stock_after_sale: GET /api/inventory/stock — quantity уменьшился на sold amount
Длительность: 0мс
## Summary
- Passed: 8
- Failed: 1
- Warnings: 0
- Skipped: 3
## Critical bugs
### CRITICAL
- **[05] Cashier ВИДИТ список сотрудников через API**
- GET /api/organization/employees вернул 200 для Cashier; ожидается 403 (нет [Authorize(Roles="Admin")] на List? или Cashier имеет Identity-Admin)
- Fix: Поставить [Authorize(Roles="Admin")] на List + проверить что AddToRoleAsync(...,"Cashier") а не "Admin")
### HIGH
- **[08] Нет ни одной единицы измерения для нового tenant**
- Bootstrap должен сидить системные units (шт, кг, л) при создании org.
## Logic gaps
- SuperAdmin /organizations принимает любой текст в поле phone — серверной валидации ФЛК нет (только в /api/auth/signup для самозаполнения).
- Cashier у созданного через POST /employees не получает Identity-роль "Cashier" — серверная авторизация на /api/sales/retail требует роли Admin или Cashier; нужно либо сидить Identity-роль из org-роли, либо переделать [Authorize] на permissions.
- Реестр products tenant-scoped: новая org стартует с пустым каталогом, хотя в БД лежат products другой org. e2e-сценарий компенсирует созданием 3 products через API.