1. Products.Update: добавление нового barcode'а к существующему товару
валилось с DbUpdateConcurrencyException 'Товар изменён в другом окне',
хотя никакой конкурентной правки не было. Тот же EF8-баг, который в
TD-6 чинили на Supplies/Demands/RetailSales: nav-collection.Add +
client-side Id путает EF, UPDATE родителя получает 0 affected. Чиним
тем же паттерном: ExecuteDelete старых ProductBarcodes/ProductPrices,
DbSet.Add новых. Воспроизводится: создать товар с 1 barcode, PUT с
2 barcodes → 409. После фикса → 204.
2. IX_products_OrganizationId_Article был обычным (не уникальным), хотя
контроллер ловил нарушение по имени индекса и возвращал 'Артикул уже
занят'. Catch-блок никогда не срабатывал. Делаем индекс уникальным
миграцией Phase8d. Перед созданием — нумеруем дубликаты по существующим
данным (если есть). NULL/пустые article остаются distinct (Postgres
NULL semantics).
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
stage-smoke (5 шагов): signup happy-path, bootstrap (Store/Roles/
Units/ProductGroup/PriceTypes/RetailPoint), login → access+refresh
+ /api/me с правильным orgId+role=Admin, edge-cases (дубликат
email, короткий пароль, пустое название, кривой телефон), проверка
public-сайта.
Informational gap: stage-public (test.food-market.kz) использует тот
же build что прод-public, поэтому его форма signup POST'ит в прод
admin. Для stage-testing регистрируемся напрямую POST на test.admin.
Чек-лист stage-testing: пункт 1 ✓.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- roles.steps.ts step08: было «задокументированный gap», стало реальная
проверка — кастомная роль без ProductsEdit → 403 на PUT товара, GET → 200.
Сценарий roles зелёный 8/8.
- RateLimiting:* конфиг (Enabled/PerMinute/PerHour): тесты с общим loopback-IP
поднимают/выключают лимит, чтобы повторные логины не упирались в 429.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Полная регрессия всех сценариев + 6 новых областей этой сессии (employees,
roles, superadmin-console, platform-smtp, auth-password, security-edge).
За день исправлено 4 бага: уволенный сотрудник логинится (P0), конкурентное
проведение приёмки ломает инвариант (critical), refresh не гасится после
ротации (high), change-owner принимал короткий reason (medium). Нереализованный
по ТЗ функционал (отчёты/склад-документы/POS/permission-authz/login-ratelimit)
зафиксирован как Logic gaps.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Итоги сессии системного тестирования:
- full-cycle: 12/12 ✓
- multi-tenant-isolation: 12/12 ✓ (новый сценарий)
Найдено и исправлено 10 P0-багов: 7 в миграциях (расхождения схемы
с domain, отсутствующие [Migration] атрибуты, rudiment колонки Kind),
1 в безопасности (edit-mode override блокировался Authorize-ролями).
См. tests/e2e/reports/systemic-2026-05-23.md для полного описания
каждого бага, gap'ов и команд воспроизведения.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Stage прогон против commit ee127b2:
- 9 ✓ / 0 ✗ / 0 ⚠ / 3 ◯ (baseline: 8/1/0/3)
- step05 Cashier полностью зелёный: Identity-role «Cashier» маппится,
/api/organization/employees → 403
- step01 новая проверка серверной phone-ФЛК → 400 на невалидном
- step08 «Нет ни одной единицы измерения» исчез — новая орга получает
5 active globals через junction сразу при создании
- HIGH bug сменился: теперь блокер «product требует штрихкод» (отдельный
вопрос — либо баг ProductsController, либо e2e-сценарий должен
передавать barcode)