- Add 2-second timeout to profile fetch in getStoredUser() to ensure
app startup < 3 seconds even with slow network. Falls back to cached
user data on timeout.
- Implement early scan termination in BLEManager when devices found.
Scan now exits after 3 seconds once minimum devices are detected,
instead of always waiting full 10 seconds.
- Add PerformanceService for tracking app startup time, API response
times, and BLE operation durations with threshold checking.
- Integrate performance tracking in app/_layout.tsx to measure and
log startup duration in dev mode.
- Add comprehensive test suite for performance service and BLE
scan optimizations.
Performance targets:
- App startup: < 3 seconds
- BLE operations: < 10 seconds
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Implement Next.js middleware for route protection
- Create Zustand auth store for web (similar to mobile)
- Add comprehensive tests for middleware and auth store
- Protect authenticated routes (/dashboard, /profile)
- Redirect unauthenticated users to /login
- Redirect authenticated users from auth routes to /dashboard
- Handle session expiration with 401 callback
- Set access token cookie for middleware
- All tests passing (105 tests total)
Implemented a full sensor health monitoring system for WP sensors that
tracks connectivity, WiFi signal strength, communication quality, and
overall device health.
Features:
- Health status calculation (excellent/good/fair/poor/critical)
- WiFi signal quality monitoring (RSSI-based)
- Communication statistics tracking (success rate, response times)
- BLE connection metrics (RSSI, attempt/failure counts)
- Time-based status (online/warning/offline based on last seen)
- Health data caching and retrieval
Components:
- Added SensorHealthMetrics types with detailed health indicators
- Implemented getSensorHealth() and getAllSensorHealth() in BLEManager
- Created SensorHealthCard UI component for health visualization
- Added API endpoints for health history and reporting
- Automatic communication stats tracking on every BLE command
Testing:
- 12 new tests for health monitoring functionality
- All 89 BLE tests passing
- No linting errors
This enables proactive monitoring of sensor health to identify
connectivity issues, poor WiFi signal, or failing devices before they
impact user experience.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Improved error handling in the attachDeviceToBeneficiary method with:
- Structured ApiResponse return type with detailed error codes
- User-friendly error messages for different failure scenarios:
- DEPLOYMENT_NOT_FOUND: Beneficiary has no deployment configured
- UNAUTHORIZED: Missing or expired authentication credentials
- NOT_FOUND: Sensor or deployment not found (404)
- SERVER_ERROR: Legacy API server error (500)
- SERVICE_UNAVAILABLE: Service temporarily unavailable (503+)
- LEGACY_API_ERROR: Error from Legacy API response body
- NETWORK_ERROR: Network connectivity issues
- EXCEPTION: Unexpected errors
- Enhanced error messages in setup-wifi.tsx to display API error details
- Fixed navigator.onLine check to work in test environment
- Added comprehensive test suite with 11 test cases covering all error scenarios
All tests passing (11/11).
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- 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.
- Add ONLINE_THRESHOLD_MS constant for magic number (30 min threshold)
- Add AbortController to cancel requests when screen loses focus
- Register BLE cleanup callback for logout in BLEContext
- Add 'Unknown User' fallback for displayName in all locations
- Add null safety guard in handleBeneficiaryPress
- Add bustImageCache() at API layer to ensure avatars always have cache-busting timestamps
- Remove redundant bustImageCache() calls from UI components (already handled at API level)
- Add key prop to Image components using avatar URL to force re-render on avatar change
- Add expo-image-manipulator mock to jest.setup.js
This ensures that when users upload new avatars, React Native's Image component
displays the updated image immediately instead of showing cached old versions.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Removed all console.log, console.error, console.warn, console.info, and console.debug statements from the main source code to clean up production output.
Changes:
- Removed 400+ console statements from TypeScript/TSX files
- Cleaned BLE services (BLEManager.ts, MockBLEManager.ts)
- Cleaned API services, contexts, hooks, and components
- Cleaned WiFi setup and sensor management screens
- Preserved console statements in test files (*.test.ts, __tests__/)
- TypeScript compilation verified successfully
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Clear master encryption key when user logs out
- Ensures WiFi passwords cannot be decrypted after logout
- Improves security by removing cryptographic material
- Complements existing WiFi password clearing on logout
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Implemented proper BLE cleanup mechanism on user logout:
**Root Cause:**
- BLE cleanup callback was being set but reference could become stale
- No explicit cleanup call in profile logout handler
- Callback stability issues due to re-renders
**Changes:**
1. app/_layout.tsx:
- Use useRef pattern to maintain stable callback reference
- Set callback once with ref that always points to current cleanupBLE
- Cleanup callback on unmount to prevent memory leaks
2. app/(tabs)/profile/index.tsx:
- Add explicit cleanupBLE() call in logout handler
- Import useBLE hook to access cleanup function
- Ensure cleanup happens before logout completes
3. services/api.ts:
- Update setOnLogoutBLECleanupCallback signature to accept null
- Allows proper cleanup of callback on unmount
4. jest.setup.js:
- Add AsyncStorage mock to prevent test failures
5. Tests:
- Add comprehensive BLE cleanup tests
- Test callback pattern and stability
- Test logout flow with BLE cleanup
- Test error handling during cleanup
**Result:**
BLE connections now properly disconnect when user logs out,
preventing stale connections and potential resource leaks.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Create wifiPasswordStore service for encrypted password storage
- Replace AsyncStorage with SecureStore for WiFi credentials
- Add automatic migration from AsyncStorage to SecureStore
- Integrate WiFi password cleanup into logout process
- Add comprehensive test suite for password storage operations
- Update setup-wifi screen to use secure storage
Security improvements:
- WiFi passwords now stored encrypted via expo-secure-store
- Passwords automatically cleared on user logout
- Seamless migration for existing users
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Implement comprehensive BLE cleanup functionality that properly
disconnects all devices and releases resources when user logs out.
Changes:
- Add cleanup() method to BLEManager and MockBLEManager
- Update IBLEManager interface to include cleanup
- Add cleanupBLE() to BLEContext to disconnect all devices
- Implement callback mechanism in api.ts for BLE cleanup on logout
- Wire up BLE cleanup in app layout to trigger on logout
- Add unit tests for BLE cleanup functionality
This ensures no BLE connections remain active after logout,
preventing resource leaks and potential connection issues.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Changes:
- Updated backend/src/services/mqtt.js to use LEGACY_API_USERNAME and LEGACY_API_PASSWORD from .env
- Updated services/api.ts with new robster credentials
- Added Legacy API and MQTT credentials to backend/.env.example
- MQTT service now falls back to LEGACY_API_* env vars if MQTT_* not set
This ensures all services use consistent, up-to-date credentials from environment configuration.
- Add build number/timestamp display on login screen
- Improve error message when beneficiary has no deployment (user-friendly text instead of crash)
- Fix verify-otp screen layout for Android (smaller spacing, icon sizes)
- Add KeyboardAvoidingView to setup-wifi screen
- Save WiFi passwords per SSID (auto-fill on reconnect)
- Suppress BLE "operation cancelled" noise in logs
- Add build-info generation script (npm run build-info)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
BLE Fix:
- Check if sensor is already connected to target WiFi before sending credentials
- Handle W|fail when sensor uses saved credentials instead of new password
- Return success if sensor is connected to target network even after W|fail
Build Version Indicator:
- Add visible version badge on Dashboard screen (v2.1.0 • 2026-01-27 17:05)
- Green text on dark background in bottom-right corner
- Helps verify which build is running on device
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Add NotificationHistoryItem, NotificationHistoryResponse types
- Add notification type enums (NotificationType, NotificationChannel, NotificationStatus)
- Implement getNotificationHistory() in api.ts with filtering support
- Supports limit, offset, type, status query params
- Returns paginated history with total count
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Add legacyCode to ROOM_LOCATIONS constants (102-200)
- Add getLocationLegacyCode() to convert ID -> code when saving
- Add getLocationIdFromCode() to convert code -> ID when loading
- updateDeviceMetadata now sends numeric codes to Legacy API
- getDevicesForBeneficiary now converts codes back to string IDs
Legacy API expects numeric location codes (e.g., 102 for Bedroom),
but frontend uses string IDs (e.g., 'bedroom'). This fix ensures
proper bidirectional conversion.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Added room locations array with id, label, and icon for each room type:
- Bedroom, Living Room, Kitchen, Bathroom, Hallway
- Entrance, Garage, Basement, Office, Other
Also exported RoomLocationId type for type-safe location selection.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Add originalName to Beneficiary type in types/index.ts
- Update getAllBeneficiaries to map displayName, originalName, customName from API
- Update getWellNuoBeneficiary to include originalName in response mapping
- Use server-provided displayName instead of computing client-side
Now GET /me/beneficiaries/:id returns:
- displayName: customName || name (for UI display)
- originalName: original name from beneficiaries table
- customName: user's custom name for this beneficiary
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Add displayName field to Beneficiary type (computed: customName || name)
- Populate displayName in getAllBeneficiaries and getWellNuoBeneficiary API calls
- Update detail page header to use beneficiary.displayName
- Update MockDashboard to use displayName
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Allow users to set custom display names for their beneficiaries
(e.g., "Mom", "Dad" instead of the real name). The custom_name
is stored per-user in user_access, so different caregivers can
have different names for the same beneficiary.
Changes:
- Migration 009: Add custom_name column to user_access
- API: Return customName in GET /me/beneficiaries endpoints
- API: New PATCH /me/beneficiaries/:id/custom-name endpoint
- Types: Add customName to Beneficiary interface
- api.ts: Add updateBeneficiaryCustomName method
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Add baseUrl and legacyApiUrl as class properties in ApiService
- Add getLegacyCredentials() method for device operations
- Add Authorization header to getDevicesForBeneficiary()
- Add Authorization header to attachDeviceToBeneficiary()
These changes fix the sensors list functionality allowing users
to view sensors for any beneficiary.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Implements API method to link WP sensors to a beneficiary's deployment
via the Legacy API set_deployment endpoint. Uses proper authentication
through getLegacyWebViewCredentials() and follows existing API patterns.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Add method to update device location and description via Legacy API
device_form endpoint. Uses getLegacyWebViewCredentials for auth.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Implemented three-tier sensor status (online/warning/offline) with visual indicators and BLE scanning for nearby devices.
Features:
- WPSensor type with status field (online/warning/offline)
- Automatic status calculation based on lastSeen time:
• Online: < 5 minutes (fresh data)
• Warning: 5 min - 1 hour (potential issue)
• Offline: > 1 hour (definitely problem)
- Dual sensor display: Connected (API) + Available Nearby (BLE)
- BLE scanning button for discovering nearby WP sensors
- Action Sheet for offline sensors with Reconnect/Remove options
- Updated summary card: Total/Online/Warning/Offline counts
- Visual status indicators: colored dots and labels
- Graceful error handling for API unavailability
Files changed:
- types/index.ts: Added WPSensor interface with status and source fields
- services/api.ts: Updated getDevicesForBeneficiary with status calculation
- equipment.tsx: Complete UI overhaul with BLE scanning and two-tier sensor list
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Monitoring badge: equipment active + subscription active
- Get kit badge: user hasn't ordered equipment yet
- Equipment status badges: ordered, shipped, delivered
- No subscription warning when equipment works but no sub
- Stripe subscription caching in backend (hourly sync)
- BeneficiaryMenu with edit/share/archive/delete actions
- Added role field to Beneficiary type
- Display role (Custodian/Guardian/Caretaker) in small gray text under name
- Role comes from user_access table via API
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Redirects should only happen on the main beneficiary page (index.tsx).
Other pages (subscription, equipment, share) just show their content
without redirecting - user navigated there intentionally via menu.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- BeneficiaryMenu: dropdownItem now has width: 100%
- Increased minWidth to 180 and added overflow: hidden
- Users can now tap anywhere on the menu row, not just the text
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Add legacy dashboard API methods (eluxnetworks.net)
- Implement JWT token validation before using cached credentials
- Clear invalid tokens (non-JWT strings like "0") and force re-login
- Use correct credentials (anandk/anandk_8)
- Add 30-minute token refresh interval when WebView is active
- Fix avatar upload using expo-file-system instead of FileReader
- Handle address field as both string and object
- Created reusable BeneficiaryMenu component with Modal backdrop
- Menu closes on outside tap (proper Modal + Pressable implementation)
- Removed debug panel from subscription and beneficiary detail pages
- Fixed subscription creation and equipment status handling
- Backend improvements for Stripe integration
Database:
- Simplified beneficiary schema: single `name` field instead of first_name/last_name
- Single `address` field instead of 5 separate address columns
- Added migration 008_update_notification_settings.sql
Backend:
- Updated all beneficiaries routes for new schema
- Fixed admin routes for simplified fields
- Updated notification settings routes
- Improved stripe and webhook handlers
Frontend:
- Updated all forms to use single name/address fields
- Added new equipment-status and purchase screens
- Added BeneficiaryDetailController service
- Added subscription service
- Improved navigation and auth flow
- Various UI improvements
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- GET /me/profile → GET /auth/me
- PATCH /me/profile → PATCH /auth/profile
These endpoints now correctly match the backend implementation
in backend/src/routes/auth.js
- Convert login from username/password to email input
- Add OTP verification screen with auto-login for dev email
- Add dev email bypass (serter2069@gmail.com) using legacy anandk credentials
- Add saveEmail/getStoredEmail methods to API service
- Add email field to User type
- Clean up logout to also clear stored email
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Replace all 'patient' terminology with 'beneficiary'
- Add Voice AI screen (voice.tsx) with voice_ask API integration
- Optimize getAllBeneficiaries() to use single deployments_list API call
- Rename PatientDashboardData to BeneficiaryDashboardData
- Update UI components: BeneficiaryCard, beneficiary picker modal
- Update all error messages and comments
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>