# E2E report: full-cycle Запущен: 2026-05-26T07:01:50.662Z Длительность: 10.6с **Итог:** 12 ✓ / 0 ✗ / 0 ⚠ / 0 ◯ (всего 12) ## ✓ Step step01_create_organization: SuperAdmin создаёт «Test Shop {timestamp}» (KZ, KZT, ФЛК телефона) Длительность: 1707мс | Тип | Проверка | Результат | |---|---|---| | api | POST /api/super-admin/organizations → 200 | ✓ org=Test Shop 1779778910662 | | api | GET /api/super-admin/organizations включает созданную org | ✓ | | api | Невалидный phone отвергается | ✓ 400 | ## ✓ Step step02_create_first_admin: SuperAdmin создаёт первого Admin сотрудника организации (Employee + AppUser) Длительность: 664мс | Тип | Проверка | Результат | |---|---|---| | 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 Длительность: 416мс | Тип | Проверка | Результат | |---|---|---| | api | /connect/token password-grant выдал токен | ✓ | | api | /api/me содержит role=Admin | ✓ Admin | | api | /api/me содержит правильный orgId | ✓ 5546bb9a-eb4c-4fea-b54b-059a3e65c249 | ## ✓ Step step04_create_storekeeper_and_cashier: Admin создаёт Storekeeper и Cashier через /settings/employees Длительность: 1320мс | Тип | Проверка | Результат | |---|---|---| | 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) Длительность: 450мс | Тип | Проверка | Результат | |---|---|---| | api | /api/me содержит роль соответствующую системной Cashier | ✓ Cashier | | api | Cashier → GET /api/organization/employees → 403 | ✓ 403 | | api | Cashier → GET /api/sales/retail — доступен | ✓ 200 | ## ✓ Step step06_create_counterparty: Admin создаёт «ТОО Тест Поставщик» (БИН + телефон) Длительность: 386мс | Тип | Проверка | Результат | |---|---|---| | api | POST /api/catalog/counterparties | ✓ 201 | ## ✓ Step step07_ensure_main_store: Проверить что есть main store (из bootstrap), иначе создать Длительность: 51мс | Тип | Проверка | Результат | |---|---|---| | api | GET /api/catalog/stores | ✓ 200 | | db | Main store существует (от bootstrap) | ✓ Основной склад | ## ✓ Step step08_create_supply: Admin создаёт Supply Draft (3-5 товаров) и проводит (Posted) Длительность: 2821мс | Тип | Проверка | Результат | |---|---|---| | api | Создано 3 product (валидный barcode + price + group) | ✓ e2e Product 1 1779778910662, e2e Product 2 1779778910662, e2e Product 3 1779778910662 | | api | Supply без supplierId → 400/409 | ✓ 400 {"error":"Поле SupplierId обязательно.","field":"SupplierId"} | | api | Supply с пустым lines[] → 400 | ✓ 400 | | api | POST /api/purchases/supplies (Draft) | ✓ 201 | | api | POST /api/purchases/supplies/{id}/post (Draft → Posted) | ✓ 204 | | api | Повторный post Supply → 409 (idempotency) | ✓ 409 {"error":"Документ уже проведён."} | | db | stock_movements содержат запись на каждую строку Supply | ✓ count=3, expected=3 | ## ✓ Step step09_check_stock_after_supply: GET /api/inventory/stock — quantity увеличился на supplied amount Длительность: 889мс | Тип | Проверка | Результат | |---|---|---| | api | stock(e2e Product 1 1779778910662) +10 (было 0, стало 10) | ✓ delta=10, expected=10 | | api | stock(e2e Product 2 1779778910662) +15 (было 0, стало 15) | ✓ delta=15, expected=15 | | api | stock(e2e Product 3 1779778910662) +20 (было 0, стало 20) | ✓ delta=20, expected=20 | | api | GET /api/inventory/stock без storeId возвращает строки на каждый склад | ✓ rows=1, stores=5e62ff98 | | db | stocks.Quantity == SUM(stock_movements.Quantity) для e2e Product 1 1779778910662… | ✓ sum_movements=10 stocks.Quantity=10 | | db | stocks.Quantity == SUM(stock_movements.Quantity) для e2e Product 2 1779778910662… | ✓ sum_movements=15 stocks.Quantity=15 | | db | stocks.Quantity == SUM(stock_movements.Quantity) для e2e Product 3 1779778910662… | ✓ sum_movements=20 stocks.Quantity=20 | ## ✓ Step step10_ensure_retail_point: Проверить или создать розничную точку (кассу) Длительность: 132мс | Тип | Проверка | Результат | |---|---|---| | api | RetailPoint существует | ✓ Касса 1 | | api | RetailPoint с несуществующим storeId → 400/404 | ✓ 400 | ## ✓ Step step11_create_retail_sale: Admin создаёт RetailSale, 2 позиции из приёмки, cash, Post Длительность: 1000мс | Тип | Проверка | Результат | |---|---|---| | api | Продажа qty>остатка → /post должен 4xx | ✓ 400 | | api | Продажа с отрицательным qty/price → 400 | ✓ 400 | | api | discount=10 на line(price=100,qty=1) → lineTotal=90 | ✓ lineTotal=90 | | api | POST /api/sales/retail (Draft) | ✓ 201 | | api | POST /retail/{id}/post | ✓ 204 | | api | Повторный post RetailSale → 409 | ✓ 409 | ## ✓ Step step12_check_stock_after_sale: GET /api/inventory/stock — quantity уменьшился на sold amount Длительность: 762мс | Тип | Проверка | Результат | |---|---|---| | api | stock product=a9e517d5… −2 (было 10, стало 8) | ✓ delta=2, expected=2 | | api | stock product=0f3d33e8… −2 (было 15, стало 13) | ✓ delta=2, expected=2 | | db | stock_movements запись на sale-line a9e517d5… | ✓ count=1, sum=-2 (expected sum=-2) | | db | stock_movements запись на sale-line 0f3d33e8… | ✓ count=1, sum=-2 (expected sum=-2) | | db | stock_movements.Type = RetailSale (2) для sale документа | ✓ types=2 | ## Summary - Passed: 12 - Failed: 0 - Warnings: 0 - Skipped: 0 ## Critical bugs Нет.