WellNuo/PRD-WEB.md
Sergei 8af7a11cd9 Fix WiFi credentials cache implementation in SecureStore
- Fix saveWiFiPassword to use encrypted passwords map instead of decrypted
- Fix getWiFiPassword to decrypt from encrypted storage
- Fix test expectations for migration and encryption functions
- Remove unused error variables to fix linting warnings
- All 27 tests now passing with proper encryption/decryption flow

The WiFi credentials cache feature was already implemented but had bugs
where encrypted and decrypted password maps were being mixed. This commit
ensures proper encryption is maintained throughout the storage lifecycle.
2026-01-31 15:55:24 -08:00

37 KiB
Raw Blame History

PRD — WellNuo Web

Overview

Полноценная веб-версия WellNuo для настройки и мониторинга BLE-сенсоров с ноутбука/десктопа.

Ключевое преимущество: Удобная настройка сенсоров с большого экрана, полная клавиатура для ввода WiFi паролей.


Browser Compatibility

Поддерживаемые браузеры (Web Bluetooth API)

Браузер Платформа Статус
Chrome 70+ Windows 10+, macOS Полная поддержка
Edge 79+ Windows 10+ Полная поддержка
Opera 57+ Windows, macOS Полная поддержка

НЕ поддерживаемые

Браузер Причина
Safari Apple не реализовали Web Bluetooth
Firefox Mozilla отказались по privacy concerns
Chrome iOS iOS блокирует Web Bluetooth
Любой браузер на iOS iOS ограничения

Browser Check Flow

┌─────────────────────────────────────────────────────────────┐
│                     Пользователь заходит                     │
└─────────────────────────────────────────────────────────────┘
                              │
                              ▼
              ┌───────────────────────────────┐
              │  navigator.bluetooth exists?  │
              └───────────────────────────────┘
                     │              │
                    YES            NO
                     │              │
                     ▼              ▼
            ┌─────────────┐  ┌─────────────────────────────┐
            │  Продолжить │  │  Показать Unsupported Page  │
            │  в приложение│  │  + ссылки на Chrome/Edge   │
            └─────────────┘  │  + ссылка на мобильное app  │
                             └─────────────────────────────┘

Tech Stack

Компонент Технология Почему
Framework Next.js 14 (App Router) Похож на Expo Router, SSR, API routes
Styling Tailwind CSS Быстрая разработка, responsive
State Zustand Легковесный, как в мобилке
API Client Fetch + custom hooks Переиспользуем логику из мобилки
BLE Web Bluetooth API Нативный браузерный API
Auth JWT (тот же что в мобилке) Один backend
Deployment Vercel One-click deploy

Backend Integration

КРИТИЧЕСКИ ВАЖНО: Используем СУЩЕСТВУЮЩИЙ backend!

┌─────────────────────────────────────────────────────────────────┐
│                        WellNuo Web                               │
├─────────────────────────────────────────────────────────────────┤
│                                                                  │
│  ┌────────────────────┐           ┌────────────────────────┐    │
│  │    WellNuo API     │           │      Legacy API        │    │
│  │ wellnuo.smartlaunch│           │   eluxnetworks.net     │    │
│  │    hub.com/api     │           │  /function/well-api    │    │
│  ├────────────────────┤           ├────────────────────────┤    │
│  │ • Auth (OTP)       │           │ • device_form          │    │
│  │ • /me/beneficiaries│           │ • device_list          │    │
│  │ • /auth/profile    │           │ • sensor data          │    │
│  │ • Subscriptions    │           │ • deployments          │    │
│  └────────────────────┘           └────────────────────────┘    │
│                                                                  │
│  ТОТ ЖЕ КОД ИЗ services/api.ts — АДАПТИРУЕМ ДЛЯ ВЕБА            │
└─────────────────────────────────────────────────────────────────┘

Screens & Features

1. Browser Check Page (entry point)

URL: / (redirect logic)

┌─────────────────────────────────────────────────────────────┐
│                                                              │
│  Поддерживаемый браузер?                                    │
│  │                                                          │
│  ├─ YES → redirect to /login или /dashboard (if logged)    │
│  │                                                          │
│  └─ NO  → показать /unsupported                             │
│                                                              │
└─────────────────────────────────────────────────────────────┘

2. Unsupported Browser Page

URL: /unsupported

┌─────────────────────────────────────────────────────────────┐
│                                                              │
│                    ⚠️ Браузер не поддерживается              │
│                                                              │
│  Для работы с Bluetooth-сенсорами используйте:              │
│                                                              │
│  ┌──────────────┐  ┌──────────────┐  ┌──────────────┐       │
│  │   Chrome     │  │    Edge      │  │    Opera     │       │
│  │  [Скачать]   │  │  [Скачать]   │  │  [Скачать]   │       │
│  └──────────────┘  └──────────────┘  └──────────────┘       │
│                                                              │
│  ────────────────── или ──────────────────                  │
│                                                              │
│  Используйте мобильное приложение:                          │
│                                                              │
│  ┌──────────────┐  ┌──────────────┐                         │
│  │  App Store   │  │ Google Play  │                         │
│  └──────────────┘  └──────────────┘                         │
│                                                              │
└─────────────────────────────────────────────────────────────┘

3. Auth Flow

URLs: /login, /verify-otp, /enter-name, /add-loved-one

Полностью повторяет мобильное приложение:

/login
┌─────────────────────────────────────────┐
│                                         │
│           WellNuo                       │
│                                         │
│  ┌───────────────────────────────────┐  │
│  │  Email                            │  │
│  └───────────────────────────────────┘  │
│                                         │
│  ┌───────────────────────────────────┐  │
│  │         Получить код              │  │
│  └───────────────────────────────────┘  │
│                                         │
└─────────────────────────────────────────┘

/verify-otp
┌─────────────────────────────────────────┐
│                                         │
│  Введите код из письма                  │
│                                         │
│  ┌───┐ ┌───┐ ┌───┐ ┌───┐ ┌───┐ ┌───┐   │
│  │ _ │ │ _ │ │ _ │ │ _ │ │ _ │ │ _ │   │
│  └───┘ └───┘ └───┘ └───┘ └───┘ └───┘   │
│                                         │
│  Отправить повторно (59 сек)           │
│                                         │
└─────────────────────────────────────────┘

4. Dashboard

URL: /dashboard

┌─────────────────────────────────────────────────────────────────┐
│  WellNuo                                        [Profile Icon]  │
├─────────────────────────────────────────────────────────────────┤
│                                                                  │
│  Добро пожаловать, {firstName}!                                 │
│                                                                  │
│  ┌─────────────────────────────────────────────────────────┐    │
│  │  👵 Мама                                                 │    │
│  │  ──────────────────────────────────────────────────────  │    │
│  │  Сенсоры: 3 активных                                     │    │
│  │  Последняя активность: 5 минут назад                     │    │
│  │                                                          │    │
│  │  [Открыть]                              [Настройки]      │    │
│  └─────────────────────────────────────────────────────────┘    │
│                                                                  │
│  ┌─────────────────────────────────────────────────────────┐    │
│  │  👴 Папа                                                 │    │
│  │  ──────────────────────────────────────────────────────  │    │
│  │  Сенсоры: 2 активных                                     │    │
│  │  Последняя активность: 1 час назад                       │    │
│  │                                                          │    │
│  │  [Открыть]                              [Настройки]      │    │
│  └─────────────────────────────────────────────────────────┘    │
│                                                                  │
│  ┌─────────────────────────────────────────────────────────┐    │
│  │                  + Добавить близкого                     │    │
│  └─────────────────────────────────────────────────────────┘    │
│                                                                  │
└─────────────────────────────────────────────────────────────────┘

5. Beneficiary Detail

URL: /beneficiaries/[id]

┌─────────────────────────────────────────────────────────────────┐
│  ← Назад                                       👵 Мама          │
├─────────────────────────────────────────────────────────────────┤
│                                                                  │
│  ┌──────────┐  ┌──────────┐  ┌──────────┐  ┌──────────┐        │
│  │ Обзор    │  │ Сенсоры  │  │ История  │  │ Настройки│        │
│  └──────────┘  └──────────┘  └──────────┘  └──────────┘        │
│                                                                  │
│  ═══════════════════════════════════════════════════════════    │
│                                                                  │
│  Сенсоры (3)                                  [+ Добавить]      │
│                                                                  │
│  ┌─────────────────────────────────────────────────────────┐    │
│  │  🟢 WP_523_81A14C                                       │    │
│  │  Кухня • Онлайн • Последнее: 2 мин назад                │    │
│  │                                            [Настройки]  │    │
│  └─────────────────────────────────────────────────────────┘    │
│                                                                  │
│  ┌─────────────────────────────────────────────────────────┐    │
│  │  🟡 WP_524_92B25D                                       │    │
│  │  Спальня • Онлайн • Последнее: 15 мин назад             │    │
│  │                                            [Настройки]  │    │
│  └─────────────────────────────────────────────────────────┘    │
│                                                                  │
│  ┌─────────────────────────────────────────────────────────┐    │
│  │  🔴 WP_525_A3C36E                                       │    │
│  │  Гостиная • Оффлайн • Последнее: 2 часа назад           │    │
│  │                                            [Настройки]  │    │
│  └─────────────────────────────────────────────────────────┘    │
│                                                                  │
└─────────────────────────────────────────────────────────────────┘

6. Add Sensor (BLE Scan)

URL: /beneficiaries/[id]/add-sensor

┌─────────────────────────────────────────────────────────────────┐
│  ← Назад                              Добавить сенсор           │
├─────────────────────────────────────────────────────────────────┤
│                                                                  │
│  ┌─────────────────────────────────────────────────────────┐    │
│  │                                                          │    │
│  │  1. Включите сенсор (зажмите кнопку на 3 сек)           │    │
│  │  2. Убедитесь что Bluetooth включён на компьютере       │    │
│  │  3. Нажмите "Начать поиск"                               │    │
│  │                                                          │    │
│  └─────────────────────────────────────────────────────────┘    │
│                                                                  │
│  ┌─────────────────────────────────────────────────────────┐    │
│  │                   🔍 Начать поиск                        │    │
│  └─────────────────────────────────────────────────────────┘    │
│                                                                  │
│  ─────────────────────────────────────────────────────────────  │
│                                                                  │
│  Найденные устройства:                                          │
│                                                                  │
│  ┌─────────────────────────────────────────────────────────┐    │
│  │  📶 WP_526_B4D47F                    Сигнал: ████░░ -65dBm   │
│  │                                             [Подключить]│    │
│  └─────────────────────────────────────────────────────────┘    │
│                                                                  │
│  ┌─────────────────────────────────────────────────────────┐    │
│  │  📶 WP_527_C5E58G                    Сигнал: ██░░░░ -78dBm   │
│  │                                             [Подключить]│    │
│  └─────────────────────────────────────────────────────────┘    │
│                                                                  │
└─────────────────────────────────────────────────────────────────┘

7. WiFi Setup

URL: /beneficiaries/[id]/setup-wifi

┌─────────────────────────────────────────────────────────────────┐
│  ← Назад                              Настройка WiFi            │
├─────────────────────────────────────────────────────────────────┤
│                                                                  │
│  Подключено к: WP_526_B4D47F                                    │
│                                                                  │
│  ─────────────────────────────────────────────────────────────  │
│                                                                  │
│  Шаг 2 из 4: Настройка WiFi                                     │
│  ████████████░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 50%        │
│                                                                  │
│  ─────────────────────────────────────────────────────────────  │
│                                                                  │
│  Доступные сети:                                                │
│                                                                  │
│  ┌─────────────────────────────────────────────────────────┐    │
│  │  📶 Home_WiFi_5G                     ████░░ -45dBm       │    │
│  │  🔒 Защищённая                              [Выбрать]   │    │
│  └─────────────────────────────────────────────────────────┘    │
│                                                                  │
│  ┌─────────────────────────────────────────────────────────┐    │
│  │  📶 Home_WiFi                        ███░░░ -58dBm       │    │
│  │  🔒 Защищённая                              [Выбрать]   │    │
│  └─────────────────────────────────────────────────────────┘    │
│                                                                  │
│  ─────────────────────────────────────────────────────────────  │
│                                                                  │
│  Или введите вручную:                                           │
│                                                                  │
│  ┌───────────────────────────────────────────────────────────┐  │
│  │  Название сети (SSID)                                     │  │
│  └───────────────────────────────────────────────────────────┘  │
│                                                                  │
│  ┌───────────────────────────────────────────────────────────┐  │
│  │  Пароль                                            👁️    │  │
│  └───────────────────────────────────────────────────────────┘  │
│                                                                  │
│  ┌─────────────────────────────────────────────────────────┐    │
│  │                    Подключить сенсор                     │    │
│  └─────────────────────────────────────────────────────────┘    │
│                                                                  │
└─────────────────────────────────────────────────────────────────┘

8. Profile / Settings

URL: /profile

┌─────────────────────────────────────────────────────────────────┐
│  ← Назад                                     Профиль            │
├─────────────────────────────────────────────────────────────────┤
│                                                                  │
│  ┌───────────────────────────────────────────────────────────┐  │
│  │  👤                                                        │  │
│  │  John Doe                                                  │  │
│  │  john@example.com                                          │  │
│  │                                                [Изменить]  │  │
│  └───────────────────────────────────────────────────────────┘  │
│                                                                  │
│  ─────────────────────────────────────────────────────────────  │
│                                                                  │
│  Настройки                                                      │
│                                                                  │
│  ┌───────────────────────────────────────────────────────────┐  │
│  │  🌙 Тёмная тема                                    [OFF]  │  │
│  └───────────────────────────────────────────────────────────┘  │
│                                                                  │
│  ┌───────────────────────────────────────────────────────────┐  │
│  │  🔔 Уведомления                                    [ON]   │  │
│  └───────────────────────────────────────────────────────────┘  │
│                                                                  │
│  ─────────────────────────────────────────────────────────────  │
│                                                                  │
│  ┌───────────────────────────────────────────────────────────┐  │
│  │                        Выйти                               │  │
│  └───────────────────────────────────────────────────────────┘  │
│                                                                  │
└─────────────────────────────────────────────────────────────────┘

Error Handling

BLE Errors

Ошибка Сообщение Действие
Bluetooth disabled "Bluetooth выключен на вашем устройстве" Инструкция как включить
Permission denied "Доступ к Bluetooth запрещён" Кнопка "Разрешить" + инструкция
Device not found "Сенсор не найден. Убедитесь что он включён" Кнопка "Повторить поиск"
Connection lost "Соединение потеряно. Переподключение..." Auto-retry 3 раза
GATT error "Ошибка связи с сенсором" Кнопка "Попробовать снова"

Network Errors

Ошибка Сообщение Действие
No internet "Нет подключения к интернету" Retry button
API timeout "Сервер не отвечает" Retry button
401 Unauthorized Redirect to /login Clear token
500 Server Error "Ошибка сервера, попробуйте позже" Retry button

WiFi Setup Errors

Ошибка Сообщение Действие
Wrong password "Неверный пароль WiFi" Показать поле ввода снова
Network not found "Сеть не найдена" Кнопка "Обновить список"
Connection timeout "Сенсор не смог подключиться к WiFi" Инструкция + retry

Web Bluetooth Implementation

Service UUIDs (из мобильного приложения)

const BLE_CONFIG = {
  // WP Sensor Service
  SERVICE_UUID: 'xxxx-xxxx-xxxx-xxxx', // TODO: взять из BLEManager.ts

  // Characteristics
  WIFI_SSID_UUID: 'xxxx',
  WIFI_PASSWORD_UUID: 'xxxx',
  COMMAND_UUID: 'xxxx',
  STATUS_UUID: 'xxxx',
};

Web Bluetooth API vs React Native BLE

Операция React Native (текущий) Web Bluetooth
Scan bleManager.startDeviceScan() navigator.bluetooth.requestDevice()
Connect device.connect() device.gatt.connect()
Read characteristic.read() characteristic.readValue()
Write characteristic.writeWithResponse() characteristic.writeValue()
Subscribe characteristic.monitor() characteristic.startNotifications()

Project Structure

wellnuo-web/
├── app/
│   ├── (auth)/
│   │   ├── login/page.tsx
│   │   ├── verify-otp/page.tsx
│   │   ├── enter-name/page.tsx
│   │   └── add-loved-one/page.tsx
│   ├── (main)/
│   │   ├── dashboard/page.tsx
│   │   ├── beneficiaries/[id]/
│   │   │   ├── page.tsx
│   │   │   ├── add-sensor/page.tsx
│   │   │   ├── setup-wifi/page.tsx
│   │   │   └── device-settings/[deviceId]/page.tsx
│   │   └── profile/page.tsx
│   ├── unsupported/page.tsx
│   ├── layout.tsx
│   └── page.tsx (redirect logic)
├── components/
│   ├── ui/ (buttons, inputs, cards)
│   ├── BrowserCheck.tsx
│   ├── BLEScanner.tsx
│   ├── WiFiSetup.tsx
│   └── SensorCard.tsx
├── services/
│   ├── api.ts (адаптированный из мобилки)
│   ├── webBluetooth.ts (новый, Web Bluetooth API)
│   └── auth.ts
├── hooks/
│   ├── useBLE.ts
│   ├── useAuth.ts
│   └── useBeneficiaries.ts
├── stores/
│   └── authStore.ts (Zustand)
├── lib/
│   └── browserCheck.ts
└── types/
    └── index.ts

Implementation Phases

Phase 1: Foundation (Week 1)

  • Next.js project setup + Tailwind
  • Browser compatibility check
  • Unsupported browser page
  • Basic layout + navigation

Phase 2: Auth (Week 1-2)

  • Login page (email input)
  • OTP verification
  • Enter name (new users)
  • JWT token management
  • Protected routes

Phase 3: Dashboard & Beneficiaries (Week 2)

  • Dashboard with beneficiary cards
  • Beneficiary detail page
  • Add beneficiary flow
  • API integration (reuse from mobile)

Phase 4: BLE Integration (Week 2-3)

  • Web Bluetooth service
  • BLE scan page
  • Device connection
  • WiFi setup flow
  • Sensor attachment to API

Phase 5: Polish (Week 3)

  • Error handling (all cases)
  • Loading states
  • Responsive design
  • Dark mode (optional)
  • PWA setup (optional)

Success Criteria

  • Работает в Chrome/Edge/Opera на Windows и macOS
  • Показывает понятную ошибку в Safari/Firefox
  • Auth flow идентичен мобилке
  • BLE сканирование находит WP сенсоры
  • WiFi setup работает полностью
  • Сенсоры успешно attach'атся к beneficiary
  • Все ошибки обрабатываются с понятными сообщениями
  • Responsive дизайн (laptop + большой монитор)

Questions to Clarify

Вопрос 1: BLE UUIDs

Нужно взять Service UUID и Characteristic UUIDs из services/ble/BLEManager.ts. Это критично для Web Bluetooth.

Вопрос 2: Домен

Где будет хоститься? Варианты:

  • web.wellnuo.com
  • app.wellnuo.com
  • wellnuo.smartlaunchhub.com (поддомен)

Вопрос 3: PWA

Делать как PWA (можно "установить" на рабочий стол)? Это добавит ~1 день работы.


Notes

  • Backend остаётся ТОТ ЖЕ — никаких изменений на сервере
  • Код API вызовов переиспользуем из services/api.ts
  • BLE логику пишем заново на Web Bluetooth API
  • UI пишем на React + Tailwind (не React Native)