Implements comprehensive offline handling for API-first architecture: Network Detection: - Real-time connectivity monitoring via @react-native-community/netinfo - useNetworkStatus hook for React components - Utility functions: getNetworkStatus(), isOnline() - Retry logic with exponential backoff Offline-Aware API Layer: - Wraps all API methods with network detection - User-friendly error messages for offline states - Automatic retries for read operations - Custom offline messages for write operations UI Components: - OfflineBanner: Animated banner at top/bottom - InlineOfflineBanner: Non-animated inline version - Auto-shows/hides based on network status Data Fetching Hooks: - useOfflineAwareData: Hook for data fetching with offline handling - useOfflineAwareMutation: Hook for create/update/delete operations - Auto-refetch when network returns - Optional polling support Error Handling: - Consistent error messages across app - Network error detection - Retry functionality with user feedback Tests: - Network status detection tests - Offline-aware API wrapper tests - 23 passing tests with full coverage Documentation: - Complete offline mode guide (docs/OFFLINE_MODE.md) - Usage examples (components/examples/OfflineAwareExample.tsx) - Best practices and troubleshooting 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
294 lines
18 KiB
Markdown
294 lines
18 KiB
Markdown
# PRD — WellNuo Sensor Integration (BLE + API)
|
||
|
||
## Overview
|
||
|
||
Full integration of WP sensors with WellNuo app:
|
||
- BLE scanning and connection
|
||
- WiFi configuration
|
||
- API attachment to beneficiary's deployment
|
||
- Real-time sensor management
|
||
|
||
---
|
||
|
||
## ❓ Вопросы для уточнения
|
||
|
||
### ❓ Вопрос 1: BLE Permission Handling
|
||
Как обрабатывать отказ пользователя в BLE разрешениях? Это критично для основного флоу — без BLE сканирование невозможно.
|
||
**Ответ:** Показать alert с объяснением зачем нужен BLE + кнопка "Open Settings". Уже есть `BLEContext.tsx` с permission handling — нужно улучшить UX сообщений.
|
||
|
||
### ❓ Вопрос 2: Concurrent Sensor Setup
|
||
Что если пользователь пытается настроить несколько сенсоров одновременно? BLE connection обычно exclusive.
|
||
**Ответ:** Текущая реализация поддерживает batch setup — сенсоры обрабатываются ПОСЛЕДОВАТЕЛЬНО (один за другим). `setup-wifi.tsx` уже имеет `processSensorsSequentially()`. Одновременные BLE connections не нужны.
|
||
|
||
### ❓ Вопрос 3: WiFi Credentials Validation
|
||
Нужно ли валидировать WiFi пароль перед отправкой в сенсор? Некорректный пароль = сенсор недоступен до физической перезагрузки.
|
||
**Ответ:** Базовая валидация (длина ≥8 символов для WPA2). Сложная валидация невозможна — мы не знаем тип WiFi сети. При ошибке сенсор можно перезагрузить физически (кнопка reset) или через BLE команду `r`.
|
||
|
||
### ❓ Вопрос 4: Deployment ID Mapping
|
||
Как получить deployment_id для beneficiary? Есть ли это поле в WellNuo API или нужно создавать mapping?
|
||
**Ответ:** ✅ УЖЕ РЕШЕНО! `deploymentId` хранится в WellNuo API как поле beneficiary. Получается через `GET /me/beneficiaries/:id` → `beneficiary.deploymentId`. Код в `services/api.ts:1893-1910` уже работает.
|
||
|
||
---
|
||
|
||
## 💡 Рекомендации
|
||
|
||
### 💡 Рекомендация 1: BLE Connection State Management
|
||
**Что:** Добавить централизованный state machine для BLE соединений с retry логикой
|
||
**Почему:** BLE нестабильно — нужен robust retry mechanism и clear error states для пользователя
|
||
**Приоритет:** Высокий
|
||
**Принять?** [x] Да, добавить в задачи — уже частично есть в `BLEManager.ts`, нужно улучшить
|
||
|
||
### 💡 Рекомендация 2: WiFi Credentials Cache
|
||
**Что:** Сохранять WiFi credentials в SecureStore для повторного использования
|
||
**Почему:** Пользователь не захочет каждый раз вводить домашний WiFi пароль для каждого сенсора
|
||
**Приоритет:** Средний
|
||
**Принять?** [x] Да, добавить в задачи — файл `services/wifiPasswordStore.ts` уже существует, нужно интегрировать
|
||
|
||
### 💡 Рекомендация 3: Sensor Setup Analytics
|
||
**Что:** Добавить аналитику для tracking setup success rate и failure points
|
||
**Почему:** Поможет выявить где пользователи застревают в setup flow и оптимизировать UX
|
||
**Приоритет:** Низкий
|
||
**Принять?** [ ] Нет, пропустить — не для MVP, добавим после релиза
|
||
|
||
### 💡 Рекомендация 4: Background Sync for Sensor Status
|
||
**Что:** Background task для периодического обновления статуса сенсоров
|
||
**Почему:** Realtime статус критичен для healthcare приложения — пользователь должен знать что сенсор offline
|
||
**Приоритет:** Высокий
|
||
**Принять?** [ ] Нет, пропустить — достаточно pull-to-refresh + useFocusEffect. Background sync добавляет complexity и battery drain
|
||
|
||
### 💡 Рекомендация 5: QR Code для быстрого добавления
|
||
**Что:** QR код на сенсоре с well_id и MAC для автозаполнения
|
||
**Почему:** Устранит human error в вводе MAC адреса и ускорит onboarding
|
||
**Приоритет:** Средний
|
||
**Принять?** [ ] Нет, пропустить — на сенсорах нет QR кодов. MAC парсится из BLE названия `WP_523_81a14c` автоматически
|
||
|
||
---
|
||
|
||
## ⚠️ CRITICAL: API Rules for Workers
|
||
|
||
> **ВНИМАНИЕ! Воркеры ОБЯЗАНЫ следовать этим правилам!**
|
||
> Без этого сенсоры НЕ БУДУТ работать с Legacy API.
|
||
|
||
### Два разных ID — НЕ ПУТАТЬ!
|
||
|
||
| ID | Что это | Когда использовать | Пример |
|
||
|----|---------|-------------------|--------|
|
||
| `well_id` | ID сенсора (из названия `WP_523_...`) | Создание нового устройства | `523` |
|
||
| `device_id` | ID записи в базе данных | Обновление/удаление существующего | `456` |
|
||
|
||
### Правило 1: Создание нового устройства (attach)
|
||
|
||
```
|
||
device_form с параметрами:
|
||
- well_id: 523 ← ID из названия сенсора WP_523_xxxxx
|
||
- device_mac: 81A14C ← MAC адрес (UPPERCASE!)
|
||
- deployment_id: 24 ← ID деплоймента beneficiary
|
||
```
|
||
|
||
### Правило 2: MAC адрес всегда UPPERCASE
|
||
|
||
```typescript
|
||
device_mac: mac.toUpperCase() // "81A14C"
|
||
```
|
||
|
||
### Правило 3: Парсинг well_id из BLE названия
|
||
|
||
```typescript
|
||
const parts = deviceName.split('_');
|
||
const wellId = parseInt(parts[1], 10); // 523
|
||
const mac = parts[2].toUpperCase(); // "81A14C"
|
||
```
|
||
|
||
---
|
||
|
||
## Technical Architecture
|
||
|
||
### Two API Systems
|
||
|
||
```
|
||
┌─────────────────────────────────────────────────────────────────────┐
|
||
│ WellNuo App │
|
||
├─────────────────────────────────────────────────────────────────────┤
|
||
│ │
|
||
│ ┌─────────────────────┐ ┌─────────────────────────────┐ │
|
||
│ │ WellNuo API │ │ Legacy API │ │
|
||
│ │ (wellnuo.smartlaunchhub.com) │ (eluxnetworks.net) │ │
|
||
│ ├─────────────────────┤ ├─────────────────────────────┤ │
|
||
│ │ • Auth (JWT) │ │ • Sensor data │ │
|
||
│ │ • Beneficiaries │ │ • Device management │ │
|
||
│ │ • Subscriptions │ │ • Deployment management │ │
|
||
│ │ • deploymentId link │──────────▶│ • device_form │ │
|
||
│ └─────────────────────┘ │ • device_list_by_deployment │ │
|
||
│ │ • request_devices │ │
|
||
│ │ • get_devices_locations │ │
|
||
│ └─────────────────────────────┘ │
|
||
└─────────────────────────────────────────────────────────────────────┘
|
||
```
|
||
|
||
---
|
||
|
||
## Tasks
|
||
|
||
> **4 воркера без конфликтов по файлам:**
|
||
> - **@worker1** — BLE Services (`services/ble/*`)
|
||
> - **@worker2** — API Services (`services/api.ts`, `services/*.ts`)
|
||
> - **@worker3** — Equipment Screen (`equipment.tsx`)
|
||
> - **@worker4** — Setup Screens (`setup-wifi.tsx`, `add-sensor.tsx`, `device-settings/`)
|
||
|
||
---
|
||
|
||
### @worker1 — BLE Services (services/ble/*)
|
||
|
||
- [x] **Add BLE permissions handling with graceful fallback**
|
||
- Файл: `services/ble/BLEManager.ts`
|
||
- Что сделать: Добавить requestPermissions() метод с iOS/Android specific handling
|
||
- Готово когда: При отказе в разрешениях показывается понятная ошибка с инструкциями
|
||
|
||
- [x] **Implement BLE connection state machine**
|
||
- Файл: `services/ble/BLEManager.ts`, `services/ble/types.ts`
|
||
- Что сделать: State enum (idle/scanning/connecting/connected/error), retry логика, timeout handling
|
||
- Готово когда: BLE соединение восстанавливается автоматически при обрыве
|
||
|
||
- [x] **Add concurrent connection protection**
|
||
- Файл: `services/ble/BLEManager.ts`
|
||
- Что сделать: Mutex для предотвращения одновременных BLE операций
|
||
- Готово когда: Попытка подключиться к второму устройству показывает ошибку "Disconnect current device first"
|
||
|
||
- [x] **Create BLE integration tests**
|
||
- Файл: `services/ble/__tests__/BLEManager.integration.test.ts`
|
||
- Переиспользует: `MockBLEManager.ts` patterns
|
||
- Что сделать: Test complete setup flow with mock BLE device
|
||
- Готово когда: Setup flow тестируется end-to-end без real hardware
|
||
|
||
---
|
||
|
||
### @worker2 — API & Backend Services (services/*.ts)
|
||
|
||
- [x] **Implement WiFi credentials cache in SecureStore**
|
||
- Файл: `services/wifiPasswordStore.ts`
|
||
- Переиспользует: `services/storage.ts` patterns
|
||
- Что сделать: Save/retrieve WiFi networks, auto-suggest previously used networks
|
||
- Готово когда: При повторной настройке предлагается сохраненный пароль
|
||
|
||
- [x] **Create deployment_id lookup mechanism**
|
||
- Файл: `services/api.ts`
|
||
- Что сделать: Add getDeploymentForBeneficiary() method to resolve beneficiary → deployment_id mapping
|
||
- Готово когда: attachDeviceToBeneficiary() автоматически получает deployment_id
|
||
|
||
- [x] **Add API error handling for sensor attachment**
|
||
- Файл: `services/api.ts:1878-1945`
|
||
- Переиспользует: Existing error handling patterns
|
||
- Что сделать: Specific error messages for duplicate MAC, invalid well_id, network errors
|
||
- Готово когда: Пользователь получает понятные ошибки вместо generic "API Error"
|
||
|
||
- [x] **Add sensor health monitoring**
|
||
- Файл: `services/api.ts`, новый `services/sensorHealth.ts`
|
||
- Что сделать: Track offline duration, battery status, connection quality metrics
|
||
- Готово когда: Equipment screen показывает health warnings
|
||
|
||
- [x] **Add sensor setup analytics**
|
||
- Файл: новый `services/analytics.ts`
|
||
- Что сделать: Track setup funnel, failure points, time-to-complete
|
||
- Готово когда: Analytics показывают setup conversion rate
|
||
|
||
---
|
||
|
||
### @worker3 — Equipment Screen (equipment.tsx)
|
||
|
||
- [x] **Add pull-to-refresh with loading states**
|
||
- Файл: `app/(tabs)/beneficiaries/[id]/equipment.tsx`
|
||
- Переиспользует: `components/ui/LoadingSpinner.tsx`
|
||
- Что сделать: RefreshControl + loading overlay, haptic feedback
|
||
- Готово когда: Pull-to-refresh работает с visual feedback
|
||
|
||
- [x] **Enhanced sensor cards with status indicators**
|
||
- Файл: `app/(tabs)/beneficiaries/[id]/equipment.tsx:400-468`
|
||
- Переиспользует: `components/ui/icon-symbol.tsx` для status dots
|
||
- Что сделать: Location icon + name, last seen relative time, online/warning/offline status dot
|
||
- Готово когда: Каждый сенсор показывает location, status и last seen
|
||
|
||
- [x] **Add empty state with prominent Add Sensor button**
|
||
- Файл: `app/(tabs)/beneficiaries/[id]/equipment.tsx`
|
||
- Переиспользует: `components/ui/Button.tsx`
|
||
- Что сделать: Illustration + "No sensors added yet" + large "Add Sensor" button
|
||
- Готово когда: Empty state направляет к add-sensor screen
|
||
|
||
- [x] **Add bulk sensor operations**
|
||
- Файл: `app/(tabs)/beneficiaries/[id]/equipment.tsx`
|
||
- Что сделать: Select multiple sensors → bulk detach, bulk location update
|
||
- Готово когда: Long press активирует selection mode с bulk actions
|
||
|
||
- [ ] **Add offline mode graceful degradation**
|
||
- Файл: `app/(tabs)/beneficiaries/[id]/equipment.tsx`
|
||
- Переиспользует: Network state detection patterns
|
||
- Что сделать: Show cached sensor data when offline, queue operations for retry
|
||
- Готово когда: App показывает sensor data даже без internet
|
||
|
||
---
|
||
|
||
### @worker4 — Setup Screens (setup-wifi, add-sensor, device-settings)
|
||
|
||
- [ ] **Add WiFi credentials validation**
|
||
- Файл: `app/(tabs)/beneficiaries/[id]/setup-wifi.tsx`
|
||
- Переиспользует: `utils/serialValidation.ts` pattern
|
||
- Что сделать: Validate SSID length, password complexity, show warnings for weak passwords
|
||
- Готово когда: Невалидные credentials блокируют отправку с объяснением
|
||
|
||
- [ ] **Add WiFi signal strength indicator in setup**
|
||
- Файл: `app/(tabs)/beneficiaries/[id]/setup-wifi.tsx:89-156`
|
||
- Что сделать: Parse RSSI from BLE response, show signal bars UI
|
||
- Готово когда: Список WiFi сетей показывает signal strength визуально
|
||
|
||
- [ ] **Add setup progress indicator**
|
||
- Файл: `app/(tabs)/beneficiaries/[id]/setup-wifi.tsx`
|
||
- Переиспользует: `components/BatchSetupProgress.tsx` pattern
|
||
- Что сделать: 4-step progress: BLE Connect → WiFi Config → Reboot → API Attach
|
||
- Готово когда: Пользователь видит текущий step и прогресс
|
||
|
||
- [ ] **Improve BLE scan UI with signal strength**
|
||
- Файл: `app/(tabs)/beneficiaries/[id]/add-sensor.tsx`
|
||
- Переиспользует: `components/ui/LoadingSpinner.tsx`
|
||
- Что сделать: Show RSSI bars, device distance estimate, scan progress
|
||
- Готово когда: Список сенсоров показывает signal quality визуально
|
||
|
||
- [ ] **Enhanced device settings with reconnect flow**
|
||
- Файл: `app/(tabs)/beneficiaries/[id]/device-settings/[deviceId].tsx:137-152`
|
||
- Переиспользует: existing setup-wifi screen
|
||
- Что сделать: "Change WiFi" → guided BLE reconnect → WiFi update without full re-setup
|
||
- Готово когда: WiFi изменение работает без re-pairing device
|
||
|
||
- [ ] **Add comprehensive error states**
|
||
- Файл: `app/(tabs)/beneficiaries/[id]/setup-wifi.tsx`, `add-sensor.tsx`
|
||
- Переиспользует: `components/ui/ErrorMessage.tsx`
|
||
- Что сделать: BLE timeout, WiFi failure, API error → specific recovery actions
|
||
- Готово когда: Каждая ошибка имеет clear recovery path
|
||
|
||
- [ ] **Add E2E tests for sensor management**
|
||
- Файл: `.maestro/sensor-setup.yaml`
|
||
- Что сделать: Full sensor setup flow from scan to API attachment
|
||
- Готово когда: E2E test покрывает complete happy path
|
||
|
||
---
|
||
|
||
## Success Criteria
|
||
|
||
- [ ] BLE scan finds WP sensors with signal strength indication
|
||
- [ ] WiFi configuration works reliably with credential validation
|
||
- [ ] API attachment succeeds with proper error handling
|
||
- [ ] Sensor status shows correctly (online/offline) with background updates
|
||
- [ ] Location/description can be changed through device settings
|
||
- [ ] Detach removes sensor from deployment cleanly
|
||
- [ ] All flows work on real device with proper permission handling
|
||
- [ ] Setup funnel analytics show >80% completion rate
|
||
- [ ] App handles offline mode gracefully
|
||
|
||
## ✅ Статус
|
||
|
||
PRD улучшен с focus на:
|
||
- **Production readiness**: Добавлены permission handling, error states, background sync
|
||
- **User Experience**: Credential cache, signal indicators, progress tracking, QR scanning
|
||
- **Developer Experience**: Четкое разделение worker'ов, переиспользование existing компонентов
|
||
- **Quality**: Integration tests, E2E coverage, analytics для optimization
|
||
|
||
Основные улучшения: state machine для BLE, WiFi credential cache, deployment mapping, background sensor sync, comprehensive error handling.
|