WellNuo/.ralphy/progress.txt
Sergei 91e677178e Add offline mode graceful degradation
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>
2026-01-31 16:49:15 -08:00

121 lines
12 KiB
Plaintext
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.

# Ralphy Progress Log
- [✓] 2026-01-20 06:35 - **TASK-1.1: Add updateDeviceMetadata method to api.ts**
- [✓] 2026-01-20 06:38 - **TASK-2.1: Add location/description editing to Device Settings screen**
- [✓] 2026-01-20 06:38 - **TASK-3.1: Show placeholder for empty location in Equipment screen**
- [✓] 2026-01-20 06:39 - **TASK-3.2: Add quick navigation to Device Settings from Equipment screen**
- [✓] 2026-01-20 06:41 - **TASK-4.1: Add checkbox selection to Add Sensor screen**
- [✓] 2026-01-20 06:43 - **TASK-4.2: Update navigation to pass selected devices**
- [✓] 2026-01-20 06:48 - **TASK-5.1: Refactor Setup WiFi screen for batch processing**
- [✓] 2026-01-20 06:51 - **TASK-5.2: Implement batch setup processing logic**
- [✓] 2026-01-20 06:55 - **TASK-5.3: Add progress UI for batch setup**
- [✓] 2026-01-20 06:58 - **TASK-6.1: Add error handling UI with retry/skip options**
- [✓] 2026-01-20 07:00 - **TASK-6.2: Add results screen after batch setup**
- [✓] 2026-01-20 07:01 - **TASK-7.1: Add attachDeviceToDeployment method to api.ts**
- [✓] 2026-01-20 07:04 - Can view sensors list for any beneficiary
- [✓] 2026-01-20 07:06 - Can scan and find WP_* sensors via BLE
- [✓] 2026-01-20 07:07 - Can select multiple sensors with checkboxes
- [✓] 2026-01-20 07:09 - Can configure WiFi for all selected sensors
- [✓] 2026-01-20 07:09 - Progress UI shows status for each device
- [✓] 2026-01-20 07:11 - Errors show retry/skip options
- [✓] 2026-01-20 07:14 - Results screen shows success/failure summary
- [✓] 2026-01-20 07:16 - Can edit sensor location in Device Settings
- [✓] 2026-01-20 07:16 - Location placeholder shows in Equipment screen
- [✓] 2026-01-20 07:17 - Can tap location to go to Device Settings
- [✓] 2026-01-20 07:18 - Mock BLE works in iOS Simulator
- [✓] 2026-01-22 20:34 - **Migration: добавить custom_name в user_access**
- [✓] 2026-01-22 20:36 - **API: изменить GET /me/beneficiaries (список)**
- [✓] 2026-01-22 20:37 - **API: изменить GET /me/beneficiaries/:id (детали)**
- [✓] 2026-01-22 20:39 - **API: изменить PATCH /me/beneficiaries/:id (обновление)**
- [✓] 2026-01-22 20:40 - **Деплой миграции на сервер**
- [✓] 2026-01-22 20:41 - **Types: обновить Beneficiary interface**
- [✓] 2026-01-22 20:41 - **API service: обновить типы ответов**
- [✓] 2026-01-22 20:42 - **UI: список beneficiaries — показывать displayName**
- [✓] 2026-01-22 20:43 - **UI: header в BeneficiaryDetail — показывать displayName**
- [✓] 2026-01-22 20:45 - **UI: Edit модал — разная логика для ролей**
- [✓] 2026-01-22 20:46 - **UI: MockDashboard — показывать displayName**
- [✓] 2026-01-22 20:48 - Custodian может редактировать оригинальное имя (`beneficiaries.name`)
- [✓] 2026-01-22 20:50 - Guardian/Caretaker могут редактировать своё персональное имя (`user_access.custom_name`)
- [✓] 2026-01-22 20:51 - Список beneficiaries показывает `displayName` (custom_name || name)
- [✓] 2026-01-22 20:54 - Header на детальной странице показывает `displayName`
- [✓] 2026-01-22 20:55 - Edit модал показывает разные labels для разных ролей
- [✓] 2026-01-22 20:56 - При первом открытии (custom_name = NULL) показывается оригинальное имя
- [✓] 2026-01-22 20:58 - Миграция применена без ошибок
- [✓] 2026-01-22 21:00 - GET `/me/beneficiaries` возвращает `displayName`, `originalName`
- [✓] 2026-01-22 21:02 - GET `/me/beneficiaries/:id` возвращает `displayName`, `originalName`, `customName`
- [✓] 2026-01-22 21:03 - PATCH `/me/beneficiaries/:id` правильно определяет что обновлять по роли
- [✓] 2026-01-22 21:13 - Нет TypeScript ошибок (`npx tsc --noEmit`)
- [✓] 2026-01-22 21:15 - Backend работает без ошибок в логах PM2
- [✓] 2026-01-22 21:33 - Нет console.log в продакшн коде (кроме отладочных с `[DEBUG]`)
- [✓] 2026-01-22 21:37 - Имена отображаются корректно во всех местах
- [✓] 2026-01-22 21:37 - Edit модал понятен для обоих типов редактирования
- [✓] 2026-01-22 21:39 - Нет визуальных багов
- [✓] 2026-01-22 21:40 - custom_name = NULL → показывается originalName
- [✓] 2026-01-22 21:41 - Пустая строка custom_name = "" → считается как NULL
- [✓] 2026-01-22 21:43 - Длинные имена не ломают UI
- [✓] 2026-01-24 22:13 - **1. Обновить Legacy API credentials**
- [✓] 2026-01-24 22:14 - **2. Добавить константы ROOM_LOCATIONS в api.ts**
- [✓] 2026-01-24 22:17 - **3. Исправить updateDeviceMetadata для location codes**
- [✓] 2026-01-24 22:21 - **4. Device Settings: заменить TextInput на Picker**
- [✓] 2026-01-24 22:25 - **5. Конвертировать location code → name при загрузке**
- [✓] 2026-01-24 22:26 - **6. Добавить стили для Picker**
- [✓] 2026-01-24 22:28 - **7. Установить @react-native-picker/picker**
- [✓] 2026-01-24 22:29 - Credentials обновлены на `robster/rob2` в .env
- [✓] 2026-01-24 22:30 - PM2 перезапущен
- [✓] 2026-01-24 22:42 - Тест: создать beneficiary → в логах видно "Created Legacy deployment: XXX"
- [✓] 2026-01-24 22:43 - Device Settings показывает Picker/Dropdown вместо TextInput для location
- [✓] 2026-01-24 22:43 - Picker содержит все 10 комнат
- [✓] 2026-01-24 22:44 - При выборе комнаты — сохраняется location_code (число) на Legacy API
- [✓] 2026-01-24 22:46 - При загрузке — location_code конвертируется в название
- [✓] 2026-01-24 22:47 - Description остаётся TextInput
- [✓] 2026-01-24 22:47 - Сохранение работает без ошибок
- [✓] 2026-01-24 22:55 - Создать beneficiary → deployment создан на Legacy API
- [✓] 2026-01-24 22:57 - Подключить BLE сенсор → привязан к deployment
- [✓] 2026-01-24 22:58 - Открыть Device Settings → видно Dropdown
- [✓] 2026-01-24 23:02 - Выбрать "Kitchen" → Save → проверить в Legacy API что location=104
- [✓] 2026-01-25 - Перезагрузить экран → показывает "Kitchen" (добавлена конвертация label→id)
- [✓] 2026-01-24 23:06 - Перезагрузить экран → показывает "Kitchen"
- [✓] 2026-01-27 00:42 - @worker1 **VULN-001: Stripe Webhook Required** — В файле `backend/src/routes/webhook.js` добавить проверку на старте сервера что `STRIPE_WEBHOOK_SECRET` установлен. Если не установлен — выбросить ошибку и остановить сервер: `if (!process.env.STRIPE_WEBHOOK_SECRET) { console.error('STRIPE_WEBHOOK_SECRET is required!'); process.exit(1); }`. Убрать fallback на `JSON.parse` без проверки подписи.
- [✓] 2026-01-27 00:42 - @worker1 **VULN-003: JWT Secret Validation** — В файле `backend/src/index.js` добавить проверку на старте что `JWT_SECRET` существует и имеет длину минимум 32 символа: `if (!process.env.JWT_SECRET || process.env.JWT_SECRET.length < 32) { console.error('JWT_SECRET must be at least 32 characters!'); process.exit(1); }`.
- [✓] 2026-01-27 00:43 - @worker1 **VULN-008: npm audit fix** — Выполнить `cd backend && npm update qs && npm audit fix` для исправления известной DoS уязвимости в пакете `qs`.
- [✓] 2026-01-27 00:44 - @worker2 **VULN-004: OTP Rate Limiting** — В файле `backend/src/routes/auth.js` добавить rate limiting для endpoint `/verify-otp`. Установить пакет `express-rate-limit`. Создать limiter: 5 попыток за 15 минут, ключ по email или IP. Применить к роуту `router.post('/verify-otp', otpLimiter, ...)`. Также добавить rate limit на `/send-otp`: 3 попытки за 15 минут.
- [✓] 2026-01-27 00:47 - @worker3 **VULN-005: Input Validation** — Установить пакет `express-validator`. Добавить валидацию во все POST/PATCH endpoints: `backend/src/routes/beneficiaries.js` (name: string 1-200, email: optional email), `backend/src/routes/stripe.js` (priceId: string), `backend/src/routes/invitations.js` (email: valid email, role: enum). Использовать паттерн: `body('field').isString().trim()...`, затем `validationResult(req)` для проверки ошибок.
- [✓] 2026-01-27 00:48 - @worker4 **VULN-007: Doppler Setup** — НЕ ВЫПОЛНЯТЬ АВТОМАТИЧЕСКИ! Это требует ручной работы. Создать файл `backend/DOPPLER_SETUP.md` с инструкцией: 1) Зарегистрироваться на doppler.com, 2) Создать проект WellNuo, 3) Добавить все секреты (DB_PASSWORD, JWT_SECRET, BREVO_API_KEY, STRIPE_SECRET_KEY, STRIPE_WEBHOOK_SECRET, ADMIN_API_KEY, LEGACY_API_PASSWORD, LIVEKIT_API_KEY, LIVEKIT_API_SECRET), 4) Установить CLI: `curl -Ls https://cli.doppler.com/install.sh | sh`, 5) Изменить запуск в PM2: `doppler run -- node index.js`, 6) Удалить .env файл после миграции.
- [✓] 2026-01-29 18:49 - **@backend** **Заменить устаревшие credentials (anandk → robster) и вынести в .env**
- [✓] 2026-01-29 18:53 - **@backend** **Fix displayName undefined в API response**
- [✓] 2026-01-29 18:58 - **@frontend** **BLE cleanup при logout**
- [✓] 2026-01-29 19:03 - **@frontend** **Fix race condition с AbortController**
- [✓] 2026-01-29 19:06 - **@backend** **Обработка missing deploymentId**
- [✓] 2026-01-29 19:13 - **@frontend** **WiFi password в SecureStore**
- [✓] 2026-01-29 19:18 - **@backend** **Проверить equipmentStatus mapping**
- [✓] 2026-01-29 19:23 - **@frontend** **Fix avatar caching после upload**
- [✓] 2026-01-29 19:27 - **@frontend** **Retry button в error state**
- [✓] 2026-01-29 19:34 - **@frontend** **Улучшить serial validation**
- [✓] 2026-01-29 19:39 - **@frontend** **Role-based UI для Edit кнопки**
- [✓] 2026-01-29 19:44 - **@frontend** **Debouncing для refresh button**
- [✓] 2026-01-29 19:47 - **@backend** **Удалить mock data из getBeneficiaries**
- [✓] 2026-01-29 19:53 - **@backend** **Константы для magic numbers**
- [✓] 2026-01-29 19:58 - **@backend** **Удалить console.logs**
- [✓] 2026-01-29 20:05 - **@frontend** **Null safety в navigation**
- [✓] 2026-01-29 20:08 - **@frontend** **BLE scanning cleanup**
- [✓] 2026-01-29 20:13 - Нет hardcoded credentials в коде
- [✓] 2026-01-29 20:20 - BLE соединения отключаются при logout
- [✓] 2026-01-29 20:29 - WiFi пароли зашифрованы
- [✓] 2026-01-29 20:44 - Console.logs удалены
- [✓] 2026-01-29 20:46 - Нет race conditions при быстром переключении
- [✓] 2026-01-29 20:51 - Avatar caching исправлен
- [✓] 2026-01-29 20:59 - Role-based доступ работает корректно
- [✓] 2026-01-31 23:23 - **Add BLE permissions handling with graceful fallback**
- [✓] 2026-01-31 23:34 - **Implement BLE connection state machine**
- [✓] 2026-01-31 23:39 - **Add concurrent connection protection**
- [✓] 2026-01-31 23:51 - **Create BLE integration tests**
- [✓] 2026-01-31 23:55 - **Implement WiFi credentials cache in SecureStore**
- [✓] 2026-02-01 00:00 - **Create deployment_id lookup mechanism**
- [✓] 2026-02-01 00:08 - **Add API error handling for sensor attachment**
- [✓] 2026-02-01 00:15 - **Add sensor health monitoring**
- [✓] 2026-02-01 00:22 - **Add sensor setup analytics**
- [✓] 2026-02-01 00:28 - **Add pull-to-refresh with loading states**
- [✓] 2026-02-01 00:29 - **Enhanced sensor cards with status indicators**
- [✓] 2026-02-01 00:30 - **Add empty state with prominent Add Sensor button**
- [✓] 2026-02-01 00:40 - **Add bulk sensor operations**