- Add NavigationController for centralized routing logic - Add useNavigationFlow hook for easy usage in components - Update subscription flow with Stripe integration - Simplify activate.tsx - Update beneficiaries and profile screens - Update CLAUDE.md with navigation documentation
212 lines
7.3 KiB
Markdown
212 lines
7.3 KiB
Markdown
# WellNuo - Project Architecture
|
|
|
|
## API-First Architecture
|
|
|
|
**IMPORTANT: This project uses an API-first approach. NO local storage for business data!**
|
|
|
|
### Key Principles
|
|
|
|
1. **All beneficiary data comes from the remote API only**
|
|
- No AsyncStorage for beneficiaries
|
|
- No local caching of beneficiary lists
|
|
- Every CRUD operation goes through the WellNuo API
|
|
|
|
2. **Single Source of Truth: WellNuo Backend**
|
|
- All beneficiary data is stored in PostgreSQL (hosted on eluxnetworks.net)
|
|
- Changes are immediately persisted to the server
|
|
- App always fetches fresh data on screen focus
|
|
|
|
### API Endpoints
|
|
|
|
#### WellNuo API (Primary)
|
|
Base URL: `https://wellnuo.smartlaunchhub.com/api`
|
|
|
|
| Method | Endpoint | Description |
|
|
|--------|----------|-------------|
|
|
| GET | `/me/beneficiaries` | List all beneficiaries for current user |
|
|
| GET | `/me/beneficiaries/:id` | Get single beneficiary details |
|
|
| POST | `/me/beneficiaries` | Create new beneficiary |
|
|
| PATCH | `/me/beneficiaries/:id` | Update beneficiary |
|
|
| DELETE | `/me/beneficiaries/:id` | Remove beneficiary access |
|
|
| POST | `/me/beneficiaries/:id/activate` | Activate device for beneficiary |
|
|
| GET | `/auth/me` | Get current user profile with beneficiaries |
|
|
| PATCH | `/auth/profile` | Update user profile (firstName, lastName, phone) |
|
|
|
|
Authentication: Bearer token (JWT from `/auth/verify-otp`)
|
|
|
|
#### Legacy API (WebView Dashboard)
|
|
Base URL: `https://eluxnetworks.net/function/well-api/api`
|
|
|
|
Used only for:
|
|
- Developer Mode / WebView dashboard
|
|
- Real sensor data visualization (from NDK devices)
|
|
|
|
### Data Flow
|
|
|
|
```
|
|
┌─────────────┐ ┌──────────────────┐ ┌──────────────────┐
|
|
│ React App │ ──▶ │ WellNuo Backend │ ──▶ │ PostgreSQL │
|
|
│ (Expo) │ ◀── │ (Express.js) │ ◀── │ (eluxnetworks.net)│
|
|
└─────────────┘ └──────────────────┘ └──────────────────┘
|
|
```
|
|
|
|
### Database Schema
|
|
|
|
- `users` - User accounts (email, password hash)
|
|
- `person_details` - Beneficiary profiles (firstName, lastName, avatar, etc.)
|
|
- `user_access` - Links accessor_id → beneficiary_id with role (owner/viewer)
|
|
- `subscriptions` - Subscription status for beneficiaries
|
|
- `devices` - IoT devices linked to beneficiaries
|
|
|
|
### What NOT to do
|
|
|
|
- ❌ Don't use `localBeneficiaries` from BeneficiaryContext for actual data
|
|
- ❌ Don't save beneficiary data to AsyncStorage
|
|
- ❌ Don't cache API responses locally for offline use
|
|
- ❌ Don't assume data is available without API call
|
|
- ❌ Don't save user profile data (name, phone) to SecureStore
|
|
- ❌ Don't use `userName` from SecureStore - it's legacy!
|
|
|
|
### What TO do
|
|
|
|
- ✅ Always fetch fresh data via `api.getAllBeneficiaries()` or `api.getWellNuoBeneficiary(id)`
|
|
- ✅ Get user profile via `api.getMe()`, update via `api.updateProfile()` (calls `/auth/profile`)
|
|
- ✅ Use `useFocusEffect` to reload data when screen gains focus
|
|
- ✅ Handle loading and error states for all API calls
|
|
- ✅ Show appropriate feedback on successful operations
|
|
- ✅ Only store in SecureStore: `accessToken`, `userId`, `userEmail` (technical auth data)
|
|
|
|
## Navigation Controller (Centralized Routing)
|
|
|
|
All navigation decisions are centralized in `services/NavigationController.ts`.
|
|
|
|
**IMPORTANT: NavigationController is NOT automatic middleware!**
|
|
- It does NOT intercept or control all navigation automatically
|
|
- It's a utility that must be EXPLICITLY called at specific points in the app
|
|
- You must manually call `nav.navigateAfterLogin()`, `nav.navigateAfterAddBeneficiary()`, etc.
|
|
- Regular navigation (e.g., `router.push('/profile')`) works independently
|
|
|
|
### When to use NavigationController:
|
|
- ✅ After OTP verification (login flow)
|
|
- ✅ After creating a new beneficiary
|
|
- ✅ After completing purchase/demo selection
|
|
- ✅ When you need to determine the "correct next screen" based on user state
|
|
|
|
### When NOT needed:
|
|
- ❌ Simple screen-to-screen navigation (just use `router.push()`)
|
|
- ❌ Tab navigation (handled by Expo Router)
|
|
- ❌ Back navigation (handled automatically)
|
|
|
|
### Key Files
|
|
- `services/NavigationController.ts` - All routing logic and conditions
|
|
- `hooks/useNavigationFlow.ts` - React hook for easy usage in components
|
|
|
|
### Navigation Flow After Login
|
|
|
|
```
|
|
User enters OTP code
|
|
↓
|
|
Has firstName in profile?
|
|
│
|
|
NO → /(auth)/enter-name
|
|
│
|
|
YES → Has beneficiaries?
|
|
│
|
|
NO → /(auth)/add-loved-one
|
|
│
|
|
YES → Check equipment status of first beneficiary
|
|
├── none → /(auth)/purchase
|
|
├── ordered/shipped → /(tabs)/beneficiaries/:id/equipment
|
|
├── delivered → /(auth)/activate
|
|
└── active/demo → /(tabs)/dashboard
|
|
```
|
|
|
|
### Navigation After Adding Beneficiary
|
|
|
|
```
|
|
Beneficiary created in DB
|
|
↓
|
|
User already has WellNuo devices?
|
|
│
|
|
NO → /(auth)/purchase (buy equipment)
|
|
│
|
|
YES → /(auth)/activate (connect existing device)
|
|
```
|
|
|
|
### Navigation After Purchase
|
|
|
|
```
|
|
Payment completed / Demo selected
|
|
↓
|
|
Demo mode?
|
|
│
|
|
YES → /(auth)/activate (immediate activation)
|
|
│
|
|
NO → /(tabs)/beneficiaries/:id/equipment (track delivery)
|
|
```
|
|
|
|
### Usage Example
|
|
|
|
```typescript
|
|
import { useNavigationFlow } from '@/hooks/useNavigationFlow';
|
|
|
|
function MyScreen() {
|
|
const nav = useNavigationFlow();
|
|
|
|
// After login - automatically determines correct screen
|
|
nav.navigateAfterLogin(profile, beneficiaries);
|
|
|
|
// After adding beneficiary
|
|
nav.navigateAfterAddBeneficiary(42, hasExistingDevices);
|
|
|
|
// After purchase
|
|
nav.navigateAfterPurchase(42, { demo: true });
|
|
|
|
// Quick shortcuts
|
|
nav.goToDashboard();
|
|
nav.goToPurchase(beneficiaryId);
|
|
nav.goToActivate(beneficiaryId);
|
|
}
|
|
```
|
|
|
|
### Available Routes (ROUTES constant)
|
|
|
|
```typescript
|
|
ROUTES.AUTH.LOGIN // /(auth)/login
|
|
ROUTES.AUTH.VERIFY_OTP // /(auth)/verify-otp
|
|
ROUTES.AUTH.ENTER_NAME // /(auth)/enter-name
|
|
ROUTES.AUTH.ADD_LOVED_ONE // /(auth)/add-loved-one
|
|
ROUTES.AUTH.PURCHASE // /(auth)/purchase
|
|
ROUTES.AUTH.ACTIVATE // /(auth)/activate
|
|
|
|
ROUTES.TABS.DASHBOARD // /(tabs)/dashboard
|
|
ROUTES.TABS.BENEFICIARIES // /(tabs)/beneficiaries
|
|
ROUTES.TABS.CHAT // /(tabs)/chat
|
|
ROUTES.TABS.VOICE // /(tabs)/voice
|
|
ROUTES.TABS.PROFILE // /(tabs)/profile
|
|
|
|
ROUTES.BENEFICIARY.DETAIL(id) // /(tabs)/beneficiaries/:id
|
|
ROUTES.BENEFICIARY.SUBSCRIPTION(id) // /(tabs)/beneficiaries/:id/subscription
|
|
ROUTES.BENEFICIARY.EQUIPMENT(id) // /(tabs)/beneficiaries/:id/equipment
|
|
ROUTES.BENEFICIARY.SHARE(id) // /(tabs)/beneficiaries/:id/share
|
|
```
|
|
|
|
## Development
|
|
|
|
### Server Location
|
|
- Production: `root@91.98.205.156:/var/www/wellnuo-api/`
|
|
- PM2 process: `wellnuo-api`
|
|
|
|
### Key Files
|
|
- `services/api.ts` - All API methods
|
|
- `services/NavigationController.ts` - Centralized routing logic
|
|
- `hooks/useNavigationFlow.ts` - Navigation hook for components
|
|
- `contexts/BeneficiaryContext.tsx` - Beneficiary state management (current selection only)
|
|
- `app/(tabs)/beneficiaries/` - Beneficiary screens
|
|
|
|
### Running Locally
|
|
```bash
|
|
# Start Expo on port 8081 with iPhone 16 Pro Max
|
|
IOS_SIMULATOR_UDID=6BB240A2-0F2F-41E4-B568-9FFAF9B7FBA2 npx expo start --port 8081 --ios
|
|
```
|