- setWiFi() now throws detailed errors instead of returning false - Shows specific error messages: "WiFi credentials rejected", timeout etc. - Added logging throughout BLE WiFi configuration flow - Fixed WiFi network deduplication (keeps strongest signal) - Ignore "Operation cancelled" error (normal cleanup behavior) - BatchSetupProgress shows actual error in hint field 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
176 lines
8.1 KiB
Markdown
176 lines
8.1 KiB
Markdown
# PRD — WellNuo Push Notifications System
|
||
|
||
## Цель
|
||
Полноценная система push-уведомлений от IoT датчиков через MQTT с настройками по типам алертов и ролям пользователей.
|
||
|
||
## Контекст проекта
|
||
- **Mobile App:** Expo 54 (React Native) с expo-router
|
||
- **Backend:** Express.js на Node.js (PM2: wellnuo-api)
|
||
- **API URL:** https://wellnuo.smartlaunchhub.com/api
|
||
- **MQTT:** mqtt.eluxnetworks.net:1883 (уже подключен, работает)
|
||
- **БД:** PostgreSQL на eluxnetworks.net
|
||
|
||
## Текущий статус
|
||
- ✅ MQTT подключен к брокеру, получает сообщения
|
||
- ✅ Таблица `mqtt_alerts` создана
|
||
- ✅ API `/api/push-tokens` существует
|
||
- ✅ API `/api/notification-settings` существует
|
||
- ❌ `expo-notifications` не установлен
|
||
- ❌ Push токены не регистрируются (0 в БД)
|
||
- ❌ Настройки не используются при отправке
|
||
|
||
## User Flow
|
||
|
||
| # | Кто | Действие | API/Система | Результат |
|
||
|---|-----|----------|-------------|-----------|
|
||
| 1 | User | Логин в приложение | POST /api/auth/verify-otp | JWT токен |
|
||
| 2 | App | Запрос разрешения push | expo-notifications | Expo Push Token |
|
||
| 3 | App | Регистрация токена | POST /api/push-tokens | Токен в БД |
|
||
| 4 | Sensor | Отправка алерта | MQTT /well_{id} | Сообщение |
|
||
| 5 | Backend | Получение MQTT | mqtt.js service | Парсинг алерта |
|
||
| 6 | Backend | Поиск пользователей | SQL JOIN | Список с токенами |
|
||
| 7 | Backend | Проверка настроек | notification_settings | Фильтрация |
|
||
| 8 | Backend | Отправка push | expo-server-sdk | Push на устройство |
|
||
| 9 | User | Получение push | iOS/Android | Уведомление |
|
||
|
||
---
|
||
|
||
## Задачи
|
||
|
||
### @worker1 — Backend (API, MQTT)
|
||
|
||
**Файлы:** `backend/src/services/mqtt.js`, `backend/src/routes/notification-settings.js`
|
||
|
||
- [ ] @worker1 **[TASK-1] Улучшить sendPushNotifications с проверкой настроек**
|
||
- Файл: `backend/src/services/mqtt.js`
|
||
- Что сделать:
|
||
1. Перед отправкой push проверять notification_settings пользователя
|
||
2. Фильтровать по типу алерта (emergency_alerts, activity_alerts, low_battery)
|
||
3. Проверять quiet_hours (если включены и текущее время в диапазоне — не отправлять non-critical)
|
||
- Результат: Push отправляется только если настройки разрешают
|
||
|
||
- [ ] @worker1 **[TASK-2] Добавить notification_history таблицу и логирование**
|
||
- Файл: SQL миграция + `backend/src/services/mqtt.js`
|
||
- Что сделать:
|
||
1. Создать таблицу notification_history (user_id, beneficiary_id, alert_type, channel, status, skip_reason, created_at)
|
||
2. Логировать каждую попытку отправки (sent/skipped/failed)
|
||
- Результат: История всех уведомлений в БД
|
||
|
||
- [ ] @worker1 **[TASK-3] API для получения истории алертов**
|
||
- Файл: `backend/src/routes/mqtt.js`
|
||
- Что сделать:
|
||
1. GET /api/mqtt/alerts/history — история из notification_history
|
||
2. Фильтры: beneficiary_id, date_from, date_to, status
|
||
- Результат: Можно посмотреть историю уведомлений
|
||
|
||
- [ ] @worker1 **[TASK-4] Деплой backend изменений**
|
||
- Команда: `rsync backend/ → server + pm2 restart wellnuo-api`
|
||
- Результат: Изменения на проде
|
||
|
||
---
|
||
|
||
### @worker2 — Mobile App (Push, UI)
|
||
|
||
**Файлы:** `app/`, `services/`, `package.json`
|
||
|
||
- [ ] @worker2 **[TASK-5] Установить expo-notifications**
|
||
- Файл: `package.json`
|
||
- Команда: `npx expo install expo-notifications`
|
||
- Результат: Пакет установлен
|
||
|
||
- [ ] @worker2 **[TASK-6] Создать сервис pushNotifications.ts**
|
||
- Файл: `services/pushNotifications.ts`
|
||
- Что сделать:
|
||
1. registerForPushNotificationsAsync() — запрос разрешения + получение Expo Push Token
|
||
2. registerTokenOnServer(token) — отправка на POST /api/push-tokens
|
||
3. unregisterToken() — удаление при logout
|
||
- Результат: Сервис для работы с push токенами
|
||
|
||
- [ ] @worker2 **[TASK-7] Интеграция при логине**
|
||
- Файл: `app/(auth)/verify-otp.tsx` или `contexts/AuthContext.tsx`
|
||
- Что сделать:
|
||
1. После успешного логина вызывать registerForPushNotificationsAsync()
|
||
2. Отправлять токен на сервер
|
||
- Результат: Push токен регистрируется автоматически
|
||
|
||
- [ ] @worker2 **[TASK-8] Обработка входящих push уведомлений**
|
||
- Файл: `app/_layout.tsx`
|
||
- Что сделать:
|
||
1. Настроить notification listeners
|
||
2. При тапе на push — навигация к соответствующему экрану
|
||
- Результат: Push уведомления работают в foreground/background
|
||
|
||
- [ ] @worker2 **[TASK-9] UI настроек уведомлений**
|
||
- Файл: `app/(tabs)/profile/notifications.tsx`
|
||
- Что сделать:
|
||
1. Загружать текущие настройки GET /api/notification-settings
|
||
2. Переключатели для: Emergency Alerts, Activity Alerts, Low Battery, Daily Summary
|
||
3. Quiet Hours: toggle + time pickers (start/end)
|
||
4. Сохранение через PATCH /api/notification-settings
|
||
- Результат: Пользователь может настроить уведомления
|
||
|
||
---
|
||
|
||
## Как проверить
|
||
|
||
### После @worker1 (Backend)
|
||
```bash
|
||
# Отправить тестовый алерт
|
||
node mqtt-test.js send "Test alert from PRD"
|
||
|
||
# Проверить логи
|
||
ssh root@91.98.205.156 "pm2 logs wellnuo-api --lines 20 | grep MQTT"
|
||
|
||
# Проверить notification_history
|
||
PGPASSWORD='W31153Rg31' psql -h eluxnetworks.net -U sergei -d wellnuo_app \
|
||
-c "SELECT * FROM notification_history ORDER BY created_at DESC LIMIT 5;"
|
||
```
|
||
|
||
### После @worker2 (Mobile)
|
||
1. Запустить приложение на симуляторе: `expo-sim 8081`
|
||
2. Залогиниться
|
||
3. Проверить что токен появился в БД:
|
||
```bash
|
||
PGPASSWORD='W31153Rg31' psql -h eluxnetworks.net -U sergei -d wellnuo_app \
|
||
-c "SELECT * FROM push_tokens;"
|
||
```
|
||
4. Отправить тестовый алерт
|
||
5. Убедиться что push пришёл
|
||
|
||
---
|
||
|
||
## Чеклист верификации
|
||
|
||
### Функциональность
|
||
- [ ] Push токен регистрируется при логине
|
||
- [ ] MQTT алерты сохраняются в mqtt_alerts
|
||
- [ ] Push отправляется с учётом настроек
|
||
- [ ] Notification history записывается
|
||
- [ ] UI настроек работает
|
||
|
||
### Код
|
||
- [ ] Нет TypeScript ошибок
|
||
- [ ] Backend деплоится без ошибок
|
||
- [ ] App собирается без ошибок
|
||
|
||
---
|
||
|
||
## Распределение файлов (проверка на конфликты)
|
||
|
||
| Worker | Файлы | Конфликт? |
|
||
|--------|-------|-----------|
|
||
| @worker1 | `backend/src/services/mqtt.js` | — |
|
||
| @worker1 | `backend/src/routes/mqtt.js` | — |
|
||
| @worker1 | `backend/src/routes/notification-settings.js` | — |
|
||
| @worker2 | `services/pushNotifications.ts` (новый) | — |
|
||
| @worker2 | `app/(auth)/verify-otp.tsx` | — |
|
||
| @worker2 | `app/_layout.tsx` | — |
|
||
| @worker2 | `app/(tabs)/profile/notifications.tsx` | — |
|
||
| @worker2 | `package.json` | — |
|
||
|
||
**Пересечений нет ✅**
|
||
|
||
---
|
||
|
||
**Минимальный балл: 8/10**
|