Files
shop-server/docs/superpowers/specs/2026-05-28-admin-orders-improvements-design.md
T
2026-05-28 21:20:35 +05:00

115 lines
7.6 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.
# Дизайн: Доработки админки заказов (маркер цены + быстрые статусы)
**Дата:** 2026-05-28
**Статус:** Draft
## Контекст
Нужно улучшить UX в админке заказов по двум направлениям:
1. Явно показывать в списке заказов, что требуется подтверждение цены (итоговой стоимости для оплаты).
2. Сделать смену статуса заказа более удобной для администратора.
Ограничения, согласованные в обсуждении:
- Не вводим новый статус заказа для подтверждения цены.
- Используем короткий текст для индикатора.
- Для смены статуса выбираем формат быстрых кнопок доступных переходов (вместо выпадающего списка).
## Цели
- Сократить время на обнаружение заказов, требующих подтверждения цены.
- Упростить и ускорить смену статуса до 1 клика.
- Сохранить существующие API-контракты и логику допустимых переходов.
## Не в рамках этой итерации
- Изменение серверной статусной модели.
- Добавление новых серверных полей или эндпоинтов.
- Массовая смена статусов из таблицы без открытия деталки.
- Редизайн всей таблицы заказов.
## Решение (утвержденный вариант A)
### 1) Маркер в списке заказов
В `client/src/pages/admin-orders/ui/AdminOrdersPage.tsx` добавить короткий бейдж `Цена не подтверждена` для строк, где:
- `status === 'PENDING_PAYMENT'`
- `deliveryType === 'delivery'`
- `deliveryFeeLocked === false`
Размещение: в колонке `ID` рядом с коротким номером заказа (`o.id.slice(-8)`), чтобы не расширять таблицу и чтобы сигнал был виден до открытия деталки.
### 2) Быстрая смена статуса в деталке заказа
В `client/src/features/order-detail/ui/OrderDetailContent.tsx` заменить текущий `Select` "Сменить статус" на набор кнопок быстрых переходов:
- Источник переходов остается прежним: `getAdminNextOrderStatuses(detail.status, detail.deliveryType)`
- Для каждого допустимого статуса рендерится отдельная кнопка
- Клик вызывает текущую мутацию `setAdminOrderStatus` через `statusMut.mutate(next)`
Поведение кнопок:
- Пока мутация выполняется (`statusMut.isPending`) все кнопки отключены
- Если доступных переходов нет — показываем текст `Статус финальный, смена недоступна`
- Для `CANCELLED` использовать визуально менее акцентную кнопку (`outlined`), чтобы снизить риск случайного нажатия
## Архитектурные границы и переиспользование
- Используем существующие данные `deliveryFeeLocked`, `status`, `deliveryType`.
- Правила переходов не дублируем в UI, берем из `getAdminNextOrderStatuses`.
- API слой (`client/src/entities/order/api/admin-order-api.ts`) без изменений.
- React Query инвалидация сохраняется текущая:
- `['admin', 'orders']`
- `['admin', 'orders', 'detail']`
- `['admin', 'orders', 'summary']`
## Поток данных
1. Страница списка получает `items` из `fetchAdminOrders`.
2. Для каждой строки вычисляется `needsPriceApproval`.
3. Если `needsPriceApproval === true`, отображается бейдж `Цена не подтверждена`.
4. В деталке рассчитывается `nextStatuses`.
5. Клик по кнопке статуса вызывает `statusMut`.
6. После успеха инвалидация обновляет список/деталку/summary; маркер в списке исчезает автоматически, когда условие перестает выполняться.
## Обработка ошибок
- Ошибка смены статуса: показать локальный `Alert` в деталке с текстом `Не удалось сменить статус`, дать возможность повторить действие.
- Ошибка загрузки списка: сохранить текущее поведение (`Не удалось загрузить заказы.`).
- Пустой список переходов: показать явное сообщение о финальном статусе.
## Тестирование
Минимальный набор:
1. Unit: проверка условия `needsPriceApproval`.
2. Component (`OrderDetailContent`):
- рендерит кнопки только допустимых переходов
- вызывает `setAdminOrderStatus` при клике
- блокирует кнопки в pending-состоянии
3. Component/Smoke (`AdminOrdersPage`):
- показывает `Цена не подтверждена` для целевых заказов
- не показывает бейдж для остальных
## Критерии готовности
- В списке заказов видно короткий маркер `Цена не подтверждена` для релевантных заказов.
- В деталке смена статуса выполняется через быстрые кнопки допустимых переходов.
- Список и деталка синхронизируются после успешной смены статуса.
- Для `CANCELLED` используется менее акцентный стиль кнопки.
- Проходят `npm run lint` и `npm run format:check` в `client`.
## План изменений по файлам
- `client/src/pages/admin-orders/ui/AdminOrdersPage.tsx` — маркер `Цена не подтверждена` в строках списка.
- `client/src/features/order-detail/ui/OrderDetailContent.tsx` — замена select на быстрые кнопки.
- (опционально) `client/src/shared/lib/` — небольшой хелпер `needsPriceApproval`, если нужно переиспользование или unit-тест вне компонента.
## Риски и меры
- Риск перегруза UI в деталке при большом количестве кнопок: низкий, так как число допустимых переходов обычно 1-2.
- Риск случайного нажатия на отмену: снижается стилем `outlined` для `CANCELLED`.
- Риск расхождения логики переходов: отсутствует, т.к. используется единый источник `getAdminNextOrderStatuses`.