WellNuo/CLAUDE.md
Sergei b14360f4b6 Fix web build: React 19 JSX runtime + AuthContext hooks order
- babel.config.js: changed jsxRuntime from 'classic' to 'automatic' (React 19 requirement)
- AuthContext.tsx: reordered useEffect/useCallback to fix "Cannot access 'checkAuth' before initialization" error on web
- CLAUDE.md: added Quick Start, Git Workflow, Credentials sections

Web version now builds and runs correctly with npm run web
2026-01-12 11:56:24 -08:00

360 lines
13 KiB
Markdown
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.

# WellNuo - Project Architecture
## Quick Start
```bash
cd /Users/sergei/Desktop/WellNuo
git pull origin development # всегда сначала pull!
npm run web # Web-First подход
# Откроется http://localhost:8081
```
---
## Git Workflow (ОБЯЗАТЕЛЬНО!)
**Branch:** `development`
### Перед началом работы:
```bash
git pull origin development
```
### После изменений:
```bash
git add <файлы>
git commit -m "описание"
git push origin development
```
### Правило одной сессии:
**Только ОДИН Claude Code работает с этим проектом одновременно!**
---
## Credentials
### PostgreSQL
```
Host: eluxnetworks.net
Port: 5432
Database: wellnuo_app
User: sergei
Password: W31153Rg31
```
### JWT
```
JWT_SECRET: wellnuo_jwt_secret_key_2024
```
### Stripe (Test)
```
Publishable: pk_test_51P3kdqP0gvUw6M9C7ixPQHqbPcvga4G5kAYx1h6QXQAt1psbrC2rrmOojW0fTeQzaxD1Q9RKS3zZ23MCvjjZpWLi00eCFWRHMk
Secret: sk_test_51P3kdqP0gvUw6M9CFhALbFxOzOUvw3LcWH7UvfGF4NtjZLOgUlzBqKAQJrHjs1loQTPRDUxfOQ5315mjUXICFU8z00PgKEVWGo
```
### Brevo Email (OTP)
```
API Key: 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
```
---
## Текущий статус (12.01.2026)
### Работает:
- [x] Web версия (`npm run web`)
- [x] Login экран
- [x] Backend API
### TODO (Web-First):
- [ ] SecureStore → localStorage (HIGH!)
- [ ] ImagePicker → File Input
- [ ] WebView → iframe
- [ ] Stripe.js для web
### Исправленные баги:
1. `babel.config.js` — jsxRuntime: 'automatic'
2. `AuthContext.tsx` — порядок hooks
---
## Ссылки
| Что | URL |
|-----|-----|
| Production | https://wellnuo.smartlaunchhub.com/app |
| API | https://wellnuo.smartlaunchhub.com/api |
| Сервер | 91.98.205.156 |
| Системный анализ | https://scheme.smartlaunchhub.com/canvas?id=cmkatv8dp0001llnsbk6eviwr |
| Задачи в схеме | https://scheme.smartlaunchhub.com/canvas?schema=cmk8xf11g0005llbvsbt0rd5z |
---
## 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
```
## Правила разработки (Development Approach)
**Методология и подход к качеству кода и тестированию.**
### ГЛАВНОЕ ПРАВИЛО: НЕ ДОБАВЛЯЙ НИЧЕГО БЕЗ СОГЛАСОВАНИЯ
**ЗАПРЕЩЕНО без явного согласования с юзером:**
- ❌ Добавлять новые UI элементы (бейджи, кнопки, тексты)
- ❌ Менять поведение которое юзер не просил менять
- ❌ "Улучшать" что-то по своей инициативе
- ❌ Интерпретировать данные API и решать как их показывать
**Если видишь что-то непонятное (например `equipmentStatus: "demo"`):**
1. СПРОСИ юзера: "Что это значит? Как это должно отображаться?"
2. НЕ ПРИДУМЫВАЙ сам UI решения
3. НЕ ДОБАВЛЯЙ бейджи/тексты которые юзер не просил
**Твоя задача — делать ТОЛЬКО то что просят, не больше.**
---
### Правило: ЧИТАЙ КОД ПЕРЕД ИЗМЕНЕНИЯМИ
1. **Всегда читай существующий код компонента перед изменением**
- Понять текущую логику, state machine, conditional rendering
- Не добавлять логику которая уже есть
- Не ломать существующее поведение
2. **Проследи весь user flow, не только один экран**
- Если фиксишь список — проверь как это влияет на detail page
- Если фиксишь backend — проверь как UI отображает новые данные
- Backend fix без проверки UI — это НЕ завершённый fix
### Правило edge cases: ПРОВЕРЯЙ ВСЕ СОСТОЯНИЯ
Перед тем как сказать "готово", проверь UI для ВСЕХ возможных состояний:
- Happy path (всё работает)
- Пустое состояние (нет данных)
- Ошибка (API недоступен)
- Специальные режимы (demo mode, trial, expired и т.д.)
### Не проси юзера тестить пока сам не проверил
1. Сначала проверь API ответ (curl)
2. Потом проверь что UI правильно отображает этот ответ
3. Потом сделай скриншот и убедись
4. Только потом говори юзеру "готово, проверь"
### Частые ошибки которых НЕЛЬЗЯ допускать
- ❌ Фиксить backend и НЕ проверять frontend
- ❌ Проверить только один сценарий и сказать "готово"
-Не читать существующий код и добавлять дублирующую логику
- ❌ Игнорировать edge cases (demo mode, expired subscription, etc.)
- ❌ Делать изменения "вслепую" без понимания текущей логики