feat: improve notifications - fix auth code tg duplicate, double order notify, add PAID label, expand text, add deliveryFeeAdjusted event
This commit is contained in:
@@ -0,0 +1,112 @@
|
||||
# Улучшение системы оповещений
|
||||
|
||||
**Дата:** 2026-05-18
|
||||
|
||||
## Проблемы
|
||||
|
||||
1. **Дублирование кода входа в Telegram** — настройка `authCodeDuplicate` не работает, т.к. `resolveAuthCodeTargets` импортирован, но не вызывается в диспетчере уведомлений.
|
||||
2. **Двойное уведомление о новом заказе** — `order:created` и `order:created:admin` оба проходят через `resolveAdminNotificationTargets('order:created')`, что даёт 2 одинаковых оповещения админу.
|
||||
3. **Пропущен `PAID` в русских лейблах статусов** — в `telegram-templates.js` и `email-templates.js` нет ключа `PAID`.
|
||||
4. **Текст оповещений слишком краткий** — нет подсказок о следующих действиях для пользователя и админа.
|
||||
|
||||
## Решения
|
||||
|
||||
### 1. Дублирование кода входа (гибридный подход)
|
||||
|
||||
- Письмо с кодом входа уходит **мгновенно** через прямой вызов `sendLoginCodeEmail` в `issueEmailCode` (без изменений).
|
||||
- В `dispatchNotification` для `AUTH_CODE_REQUESTED` используется отдельный резолвер `resolveAuthCodeTargets` вместо общих `resolveUserNotificationTargets` / `resolveAdminNotificationTargets`.
|
||||
- `resolveAuthCodeTargets` уже правильно реализован: отправляет email пользователю, а Telegram — только если `payload.isAdmin === true` и включена настройка `authCodeDuplicate`.
|
||||
|
||||
**Изменяемые файлы:**
|
||||
- `server/src/index.js` — добавить условие в `dispatchNotification` для `AUTH_CODE_REQUESTED`
|
||||
|
||||
### 2. Двойное уведомление о новом заказе
|
||||
|
||||
- Удалить `ORDER_CREATED` из `adminEventFieldMap` в `preferences.js`.
|
||||
- Админ получает уведомление о новом заказе только через событие `'order:created:admin'`.
|
||||
|
||||
**Изменяемые файлы:**
|
||||
- `server/src/lib/notifications/preferences.js` — удалить `[ORDER_CREATED]: "newOrder"` из `adminEventFieldMap`
|
||||
|
||||
### 3. Добавление PAID в лейблы статусов
|
||||
|
||||
- `PAID: 'Оплачен'` в `telegram-templates.js` и `email-templates.js`.
|
||||
|
||||
**Изменяемые файлы:**
|
||||
- `server/src/lib/notifications/templates/telegram-templates.js`
|
||||
- `server/src/lib/notifications/templates/email-templates.js`
|
||||
|
||||
### 4. Расширение текста оповещений
|
||||
|
||||
#### 4a. Пользователь: Заказ создан
|
||||
|
||||
В событие `ORDER_CREATED` передаётся `deliveryType`:
|
||||
- `deliveryType === 'pickup'` → *"Ваш заказ №XXX успешно создан. Товаров: X | Сумма: XXX ₽. Ожидает оплаты."*
|
||||
- `deliveryType === 'delivery'` → *"Ваш заказ №XXX успешно создан. Товаров: X | Сумма: XXX ₽. Оплата будет доступна после уточнения стоимости доставки."*
|
||||
|
||||
**Изменяемые файлы:**
|
||||
- `server/src/routes/user-orders.js` — добавить `deliveryType` в payload события `ORDER_CREATED`
|
||||
- `server/src/lib/notifications/templates/telegram-templates.js` — обновить `renderOrderCreatedTg`
|
||||
- `server/src/lib/notifications/templates/email-templates.js` — обновить `renderOrderCreatedEmail`
|
||||
|
||||
#### 4b. Новое событие: deliveryFeeAdjusted
|
||||
|
||||
При корректировке стоимости доставки (`PATCH /api/admin/orders/:id/delivery-fee`) отправлять пользователю уведомление:
|
||||
- Текст: *"Стоимость доставки скорректирована. Ожидает оплаты."*
|
||||
|
||||
Событие: `'order:deliveryFeeAdjusted'` — добавляется в `NOTIFICATION_EVENTS`.
|
||||
|
||||
**Изменяемые файлы:**
|
||||
- `shared/constants/notification-events.js` — добавить `DELIVERY_FEE_ADJUSTED`
|
||||
- `shared/constants/notification-events.d.ts` — добавить `'order:deliveryFeeAdjusted'`
|
||||
- `server/src/lib/notifications/preferences.js` — добавить `DELIVERY_FEE_ADJUSTED` в `userEventFieldMap`
|
||||
- `server/src/routes/api/admin-orders.js` — emit `DELIVERY_FEE_ADJUSTED` после обновления
|
||||
- `server/src/routes/user/notifications.js` — добавить поле в API
|
||||
- `client/src/pages/me/ui/sections/NotificationsPage.tsx` — добавить переключатель
|
||||
- `server/src/lib/notifications/templates/telegram-templates.js` — новый рендерер
|
||||
- `server/src/lib/notifications/templates/email-templates.js` — новый рендерер
|
||||
- `server/src/lib/notifications/channels/telegram-channel.js` — зарегистрировать шаблон
|
||||
- `server/src/lib/notifications/channels/email-channel.js` — зарегистрировать шаблон
|
||||
- `server/src/index.js` — подписаться на событие
|
||||
|
||||
Также нужно добавить миграцию Prisma для поля `deliveryFeeAdjusted` в `NotificationPreference`.
|
||||
|
||||
#### 4c. Админ: Новый заказ
|
||||
|
||||
В событие `'order:created:admin'` передаётся `deliveryType`:
|
||||
- `deliveryType === 'delivery'` → добавить *"Скорректируйте стоимость доставки"*
|
||||
- `deliveryType === 'pickup'` → как сейчас
|
||||
|
||||
**Изменяемые файлы:**
|
||||
- `server/src/routes/user-orders.js` — добавить `deliveryType` в payload `'order:created:admin'`
|
||||
- `server/src/lib/notifications/templates/telegram-templates.js` — обновить `renderAdminOrderCreatedTg`
|
||||
- `server/src/lib/notifications/templates/email-templates.js` — обновить `renderAdminOrderCreatedEmail`
|
||||
|
||||
## Схема данных
|
||||
|
||||
### NotificationPreference (добавить поле)
|
||||
|
||||
```prisma
|
||||
model NotificationPreference {
|
||||
id String @id @default(cuid())
|
||||
userId String @unique
|
||||
globalEnabled Boolean @default(true)
|
||||
orderCreated Boolean @default(true)
|
||||
orderStatusChanged Boolean @default(true)
|
||||
orderMessageReceived Boolean @default(true)
|
||||
paymentStatusChanged Boolean @default(true)
|
||||
deliveryFeeAdjusted Boolean @default(true) // НОВОЕ
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
}
|
||||
```
|
||||
|
||||
## Обработка ошибок
|
||||
|
||||
- Если при delivery-fee эмите не указан `userId` — событие не отправляется.
|
||||
- Если рендерер не найден для события — `telegram-channel.js` и `email-channel.js` логируют warning (существующее поведение).
|
||||
|
||||
## Тестирование
|
||||
|
||||
- `server/src/lib/notifications/__tests__/preferences.test.js` — добавить тест для `resolveAuthCodeTargets` в контексте `dispatchNotification`
|
||||
- Проверить, что после удаления `ORDER_CREATED` из `adminEventFieldMap` админ не получает дубликат
|
||||
Reference in New Issue
Block a user