food-market/docs/sprint-incident-1791428701.md
nns 87eb48cca9
Some checks are pending
Auto-tag / Create date-tag (push) Waiting to run
docs(incident): menu-walk demo-cashier 403 — root cause + фикс + retest
Инцидент #1791428701 (quality-watchdog): кассир получал 403 на /api/money/accounts
на странице смен. Фикс — узкий /api/money/shifts/accounts (см. 9dc033d). Retest на
стенде: menu-walk 3/3 роли зелёные.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-08 08:40:44 +05:00

67 lines
4.4 KiB
Markdown
Raw 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.

# Инцидент quality-watchdog #1791428701 — menu-walk, demo-cashier 403
- **Время:** 2026-10-08T08:05:01+05:00
- **Шаг watchdog:** `menu_walk` — `stage-ui-menu-walk.spec.ts` › demo-cashier.
- **Подряд падений:** 2.
- **Стенд:** https://test.admin.food-market.kz
## Симптом
E2E «каждый пункт меню для каждой демо-роли без 4xx/5xx/toast.error/console.error»
падал на роли **demo-cashier**:
```
NET: 403 GET https://test.admin.food-market.kz/api/money/accounts?pageSize=100&isActive=true
```
(4 раза — заход на пункт меню + reload). Воспроизведено локально:
`npx playwright test scenarios/stage-ui-menu-walk.spec.ts -g "demo-cashier"`.
Sidebar кассира: `/ /dashboard /catalog/products /inventory/stock /sales/retail
/money/shifts /help /whats-new`. Падало на `/money/shifts`.
## Root cause
Страница смен `CashShiftsPage` (`/money/shifts`) для выбора кассы/эквайринга при
открытии смены дёргала `GET /api/money/accounts` (хук `useMoneyAccounts(true)`).
Этот эндпоинт — под правом **`MoneyView`**. Но у роли «Кассир»
(`DevDataSeeder.SeedEmployeeRolesAsync`) по требованию владельца
**`MoneyView = false`** («кассир не видит денег»), есть только
`CashShiftOperate = true`. Итог: кассир может открыть смену, но страница падала
403 при загрузке списка счетов.
Эндпоинты самих смен (`/api/money/shifts` List/Get/Report/open/close/drawer) уже
принимали право по ИЛИ-семантике `MoneyView OR CashShiftOperate`, а список счетов —
нет. Это несоответствие и было дырой (пред-существующий баг модуля «Деньги»,
проявился на стенде). Не связано с другими правками спринта.
## Исправление
- Новый узкий эндпоинт **`GET /api/money/shifts/accounts`**
(`RequiresPermission("MoneyView,CashShiftOperate")`): возвращает только активные
**наличные кассы + эквайринг**, минимальные поля (id, name, kind, storeId,
currency) — **без остатков и банковских счетов**. Кассиру хватает для выбора
кассы при открытии смены, но модуль «Деньги» (остатки/платежи/чужие счета)
по-прежнему недоступен — инвариант «кассир не видит денег» сохранён.
- Веб: `CashShiftsPage` использует новый хук `useShiftAccounts()` вместо
`useMoneyAccounts(true)`. Админ-страница счетов (`/api/money/accounts`) не тронута.
Файлы: `CashShiftsController.cs` (+эндпоинт), `web/src/lib/money.ts` (+`useShiftAccounts`),
`web/src/pages/money/CashShiftsPage.tsx`.
## Тесты
`tests/food-market.IntegrationTests/PermissionTests.cs` (Testcontainers):
- `Cashier_can_list_shift_accounts_but_not_money_accounts` — кассир (CashShiftOperate,
без MoneyView): `GET /api/money/shifts/accounts` → 200 (только kind 1/4, без банка);
`GET /api/money/accounts` → 403 (инвариант).
- `Me_permissions_for_cashier_role` — /api/me permissions кассира (ProductsView есть,
advanced-only скрыт в простом режиме).
Результат: PermissionTests 4/4 зелёные.
## Деплой и retest
- `~/deploy-stage.sh` — OK: guard isolation OK, api+web собраны/запушены,
stage-api Healthy, https://test.admin.food-market.kz OK.
- Ручной retest menu-walk **demo-cashier** на стенде — **1 passed (40.8s)**,
0 ошибок (ранее 403 на /api/money/accounts). Прогон всех трёх ролей (admin/
keeper/cashier) — зелёный (admin/keeper не задеты: их страница смен теперь
тоже через /shifts/accounts, у них есть MoneyView по ИЛИ).
## Коммит
`9dc033d` fix(money): кассир открывает смену без доступа к модулю «Деньги» (403).