WellNuo/wellnuoSheme/SysAnal.json
Sergei af148faa40 Add scheme files, beneficiaries module, dashboard improvements
Changes:
- Add wellnuoSheme/ folder with project documentation
- Rename patients -> beneficiaries (proper WellNuo terminology)
- Add BeneficiaryContext for state management
- Update API service with WellNuo endpoints
- Add dashboard screen for beneficiary overview
- Update navigation and layout

Scheme files include:
- API documentation with credentials
- Project description
- System analysis
- UX flow
- Legal documents (privacy, terms, support)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-12 13:38:38 -08:00

957 lines
28 KiB
JSON
Raw Permalink 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.

{
"_meta": {
"name": "SysAnal",
"updatedAt": "2025-12-12T21:15:34.928Z"
},
"elements": [
{
"id": "info-project",
"type": "card",
"title": "WellNuo Mobile App",
"subtitle": "Мониторинг пожилых людей",
"description": "**Стек:**\n- React Native 0.81.5 + Expo SDK 54\n- Expo Router 6.x\n- Backend: существующий API (Python)\n- AI: OpenAI GPT-3.5-turbo (только текст)\n\n**Репозиторий:**\nGitea: `robert/MobileApp_react_native`\nBranch: `development`\n\n**Мы делаем:** только frontend",
"tags": [
"system"
],
"borderColor": "gray",
"x": 140,
"y": 543.75
},
{
"id": "info-legend",
"type": "card",
"title": "ЛЕГЕНДА ТЕГОВ",
"subtitle": "Кто выполняет действие",
"description": "**frontend** - React Native приложение (наша работа)\n**backend** - Существующий API (уже готов)\n**external** - Внешние сервисы (OpenAI, Stripe)\n**env** - Переменные окружения/доступы\n\n**completed: true** = доступ получен/проверен\n**completed: false** = нужно получить",
"tags": [
"system"
],
"borderColor": "gray",
"x": 520,
"y": 716.25
},
{
"id": "info-data-flow",
"type": "card",
"title": "DATA FLOW PATTERN",
"subtitle": "Как данные ходят",
"description": "**Каждый экран с данными:**\n\n1. **Mount** → setLoading(true)\n2. **API Request** → frontend → backend\n3. **Condition** → успех/ошибка?\n4. **Success** → setData() → render\n5. **Error** → setError() → Retry\n\n**Стрелки:** → запрос | ← ответ",
"tags": [
"system"
],
"borderColor": "gray",
"x": 140,
"y": 780
},
{
"id": "env-section",
"type": "card",
"title": "ENV / CREDENTIALS",
"subtitle": "Все доступы проекта",
"description": "Секция с переменными окружения.\nПроверено: 12 декабря 2025\n\n✅ = есть | ❌ = нужно",
"tags": [
"env"
],
"borderColor": "cyan",
"x": 520,
"y": 307.5
},
{
"id": "env-gitea",
"type": "card",
"title": "GITEA_URL ✅",
"subtitle": "Репозиторий кода",
"description": "https://gitea.serv00.org\n\n**Repo:** robert/MobileApp_react_native\n**Branch:** development",
"tags": [
"env"
],
"borderColor": "cyan",
"completed": true,
"x": 900,
"y": 77.5
},
{
"id": "env-api-url",
"type": "card",
"title": "API_URL ✅",
"subtitle": "Backend API endpoint",
"description": "**URL:** `https://eluxnetworks.net/function/well-api/api`\n\n**Format:** x-www-form-urlencoded\n**Параметр:** function=названиеункции\n\n**Dashboard:** https://react.eluxnetworks.net/dashboard\n\n**Проверено:** работает ✅",
"tags": [
"env",
"backend"
],
"borderColor": "cyan",
"completed": true,
"x": 900,
"y": 192.5
},
{
"id": "env-api-credentials",
"type": "card",
"title": "API_CREDENTIALS ✅",
"subtitle": "Логин/пароль для API",
"description": "**Username:** anandk\n**Password:** anandk_8\n\n**Тестовый ответ:**\n- user_id: 43\n- max_role: 2\n- privileges: 21,38,29,41,42\n\n**Проверено:** 12.12.2025 ✅",
"tags": [
"env",
"backend"
],
"borderColor": "cyan",
"completed": true,
"x": 900,
"y": 307.5
},
{
"id": "env-expo-project",
"type": "card",
"title": "EXPO_PROJECT_ID ❌",
"subtitle": "EAS Project ID",
"description": "Для EAS Build и Push Notifications\n\nhttps://expo.dev\n\n(нужно создать проект)",
"tags": [
"env"
],
"borderColor": "cyan",
"completed": false,
"x": 900,
"y": 422.5
},
{
"id": "env-stripe-pub",
"type": "card",
"title": "STRIPE_PUBLISHABLE_KEY ❌",
"subtitle": "Stripe Public Key",
"description": "`pk_xxx`\n\nДля оплаты в приложении\n\nhttps://dashboard.stripe.com/apikeys",
"tags": [
"env",
"external"
],
"borderColor": "cyan",
"completed": false,
"x": 1280,
"y": 77.5
},
{
"id": "env-stripe-secret",
"type": "card",
"title": "STRIPE_SECRET_KEY ❌",
"subtitle": "Stripe Secret (backend)",
"description": "`sk_xxx`\n\nТолько на backend!",
"tags": [
"env",
"backend"
],
"borderColor": "cyan",
"completed": false,
"x": 1280,
"y": 192.5
},
{
"id": "env-sendgrid",
"type": "card",
"title": "SENDGRID_API_KEY ❌",
"subtitle": "Email сервис",
"description": "`SG.xxx`\n\nДля отправки:\n- Welcome email\n- Password reset",
"tags": [
"env",
"external"
],
"borderColor": "cyan",
"completed": false,
"x": 1280,
"y": 307.5
},
{
"id": "api-structure",
"type": "card",
"title": "API STRUCTURE",
"subtitle": "Структура существующего API",
"description": "**Base URL:**\n`https://eluxnetworks.net/function/well-api/api`\n\n**Format:** POST x-www-form-urlencoded\n\n**Функции (проверенные):**\n- `function=credentials` → логин\n- `function=voice_ask` → AI чат\n\n**Параметры credentials:**\n- user_name, ps, clientId, nonce\n\n**Параметры voice_ask:**\n- clientId, user_name, token, question, deployment_id",
"tags": [
"backend"
],
"borderColor": "green",
"x": 900,
"y": 537.5
},
{
"id": "flow-start",
"type": "card",
"title": "1. APP START",
"subtitle": "Запуск приложения",
"description": "**Файл:** `app/_layout.tsx`\n\nПользователь открывает приложение.\nПоказывается Splash Screen.",
"tags": [
"frontend"
],
"borderColor": "blue",
"x": 900,
"y": 652.5
},
{
"id": "flow-check-token",
"type": "condition",
"title": "2. Токен в SecureStore?",
"subtitle": "Проверка авторизации",
"description": "```javascript\nconst token = await SecureStore.getItemAsync('accessToken')\n```\n\nЕсли токен есть → проверяем валидность\nЕсли нет → Login Screen",
"tags": [
"frontend"
],
"borderColor": "yellow",
"x": 1280,
"y": 652.5
},
{
"id": "flow-login-screen",
"type": "card",
"title": "3. LOGIN SCREEN",
"subtitle": "Экран входа",
"description": "**Файл:** `app/(auth)/login.tsx`\n\n**State:**\n- username, password\n- loading, error\n\n**Поля:**\n- Username (не email!)\n- Password\n\n**Кнопки:**\n- [Sign In]\n- [Forgot Password?]\n- [Create Account]",
"tags": [
"frontend"
],
"borderColor": "blue",
"x": 1660,
"y": 710
},
{
"id": "flow-login-loading",
"type": "card",
"title": "3a. Loading State",
"subtitle": "Показать спиннер",
"description": "```javascript\nsetLoading(true)\nsetError(null)\n```\n\n- Disable кнопку\n- Показать спиннер",
"tags": [
"frontend"
],
"borderColor": "blue",
"x": 1660,
"y": 540
},
{
"id": "flow-login-api",
"type": "card",
"title": "4. POST function=credentials",
"subtitle": "Авторизация (существующий API)",
"description": "**URL:** https://eluxnetworks.net/function/well-api/api\n**Format:** x-www-form-urlencoded\n\n**Request:**\n```\nfunction=credentials\nuser_name=anandk\nps=password\nclientId=001\nnonce=random_number\n```\n\n**Response 200:**\n```json\n{\n \"access_token\": \"jwt...\",\n \"privileges\": \"21,38,29,41,42\",\n \"user_id\": 43,\n \"max_role\": 2,\n \"status\": \"200 OK\"\n}\n```",
"tags": [
"backend"
],
"borderColor": "green",
"x": 2026.443603515625,
"y": 542.4937133789062
},
{
"id": "flow-login-condition",
"type": "condition",
"title": "4a. Успех?",
"subtitle": "Проверка ответа",
"description": "**status === \"200 OK\"?**\n\n**Да** → Сохранить токен\n**Нет** → Показать ошибку",
"tags": [
"frontend"
],
"borderColor": "yellow",
"x": 2420,
"y": 542
},
{
"id": "flow-login-success",
"type": "card",
"title": "5. Сохранение токена",
"subtitle": "SecureStore",
"description": "```javascript\nawait SecureStore.setItemAsync('accessToken', response.access_token)\nawait SecureStore.setItemAsync('userId', response.user_id)\nawait SecureStore.setItemAsync('privileges', response.privileges)\n```\n\nПереход на главный экран",
"tags": [
"frontend"
],
"borderColor": "blue",
"x": 2800,
"y": 480
},
{
"id": "flow-login-error",
"type": "card",
"title": "5b. Error State",
"subtitle": "Показать ошибку",
"description": "```javascript\nsetLoading(false)\nsetError('Invalid credentials')\n```\n\n- Красный текст ошибки\n- Кнопка Retry активна",
"tags": [
"frontend"
],
"borderColor": "red",
"x": 2800,
"y": 620
},
{
"id": "flow-register-screen",
"type": "card",
"title": "3r. REGISTER SCREEN",
"subtitle": "Экран регистрации",
"description": "**Файл:** `app/(auth)/register.tsx`\n\n**Поля:**\n- Full Name\n- Email\n- Password\n- Confirm Password\n\n**Кнопки:**\n- [Create Account]\n- [Sign In]",
"tags": [
"frontend"
],
"borderColor": "blue",
"x": 1660,
"y": 880
},
{
"id": "flow-register-validate",
"type": "condition",
"title": "3r-1. Валидация?",
"subtitle": "Клиентская проверка",
"description": "- Name не пустой?\n- Email валидный?\n- Password >= 6?\n- Passwords совпадают?",
"tags": [
"frontend"
],
"borderColor": "yellow",
"x": 2040,
"y": 880
},
{
"id": "flow-register-api",
"type": "card",
"title": "3r-2. POST register",
"subtitle": "API регистрации",
"description": "**Request:**\n```json\n{\n \"name\": \"John\",\n \"email\": \"user@example.com\",\n \"password\": \"xxx\"\n}\n```\n\n**Response 201:** tokens\n**Error 409:** Email exists",
"tags": [
"backend"
],
"borderColor": "green",
"x": 2420,
"y": 880
},
{
"id": "flow-register-email",
"type": "card",
"title": "3r-3. Welcome Email",
"subtitle": "SendGrid",
"description": "Backend отправляет приветственное письмо\n\n(на сервере)",
"tags": [
"external"
],
"borderColor": "orange",
"x": 2800,
"y": 880
},
{
"id": "flow-forgot-screen",
"type": "card",
"title": "3f. FORGOT PASSWORD",
"subtitle": "Восстановление пароля",
"description": "**Файл:** `app/(auth)/forgot.tsx`\n\n**Поле:** Email\n\n**Кнопки:**\n- [Send Reset Link]\n- [Back to Login]",
"tags": [
"frontend"
],
"borderColor": "blue",
"x": 1660,
"y": 1050
},
{
"id": "flow-forgot-api",
"type": "card",
"title": "3f-1. POST forgot",
"subtitle": "API сброса",
"description": "**Request:**\n```json\n{ \"email\": \"user@example.com\" }\n```\n\n**Response 200:**\n```json\n{ \"message\": \"Reset link sent\" }\n```",
"tags": [
"backend"
],
"borderColor": "green",
"x": 2040,
"y": 1050
},
{
"id": "flow-patients-list",
"type": "card",
"title": "6. PATIENTS LIST",
"subtitle": "Главный экран - список пациентов",
"description": "**Файл:** `app/(tabs)/index.tsx`\n\n**State:**\n- patients: Patient[]\n- loading, error\n\n**UI:**\n- Список карточек\n- Pull to refresh\n- [+] Добавить\n\n**Tab Bar:** Home | Chat | Profile",
"tags": [
"frontend"
],
"borderColor": "blue",
"x": 3180,
"y": 480
},
{
"id": "flow-patients-loading",
"type": "card",
"title": "6a. Loading",
"subtitle": "useEffect mount",
"description": "```javascript\nuseEffect(() => {\n loadPatients()\n}, [])\n```\n\nsetLoading(true)",
"tags": [
"frontend"
],
"borderColor": "blue",
"x": 3560,
"y": 400
},
{
"id": "flow-patients-api",
"type": "card",
"title": "6b. GET patients",
"subtitle": "API запрос",
"description": "**Request:**\n```\nfunction=get_patients\ntoken=jwt\n```\n\n**Response:**\n```json\n{ \"patients\": [...] }\n```",
"tags": [
"backend"
],
"borderColor": "green",
"x": 3940,
"y": 400
},
{
"id": "flow-patients-condition",
"type": "condition",
"title": "6c. Успех?",
"subtitle": "Проверка",
"description": "**ok === true?**\n\n**Да** → render\n**Нет** → error",
"tags": [
"frontend"
],
"borderColor": "yellow",
"x": 4320,
"y": 400
},
{
"id": "flow-patients-render",
"type": "card",
"title": "6d. Render",
"subtitle": "Отрисовка",
"description": "```javascript\nsetLoading(false)\nsetPatients(data)\n```\n\nFlatList обновляется",
"tags": [
"frontend"
],
"borderColor": "blue",
"x": 4700,
"y": 340
},
{
"id": "flow-patients-error",
"type": "card",
"title": "6e. Error",
"subtitle": "Ошибка + Retry",
"description": "```javascript\nsetError('Failed')\n```\n\n[Retry] кнопка",
"tags": [
"frontend"
],
"borderColor": "red",
"x": 4700,
"y": 480
},
{
"id": "flow-patient-dashboard",
"type": "card",
"title": "7. PATIENT DASHBOARD",
"subtitle": "Дашборд пациента",
"description": "**Файл:** `app/patients/[id]/index.tsx`\n\n**Секции:**\n- Статус (online/offline)\n- Здоровье (пульс, шаги, сон)\n- Напоминания о лекарствах\n- [Chat with Julia] → AI Chat",
"tags": [
"frontend"
],
"borderColor": "blue",
"x": 3180,
"y": 620
},
{
"id": "flow-add-patient",
"type": "card",
"title": "6+. ADD PATIENT",
"subtitle": "Добавить пациента",
"description": "**Файл:** `app/patients/add.tsx`\n\n**Поля:**\n- Name\n- Photo\n- Relationship\n- Device ID",
"tags": [
"frontend"
],
"borderColor": "blue",
"x": 3180,
"y": 760
},
{
"id": "flow-chat-screen",
"type": "card",
"title": "8. AI CHAT SCREEN",
"subtitle": "Текстовый чат с Julia",
"description": "**Файл:** `app/(tabs)/chat.tsx`\n\n**State:**\n- messages: Message[]\n- input, sending\n\n**UI:**\n- История (bubbles)\n- Input + Send\n- Typing indicator",
"tags": [
"frontend"
],
"borderColor": "blue",
"x": 3560,
"y": 620
},
{
"id": "flow-chat-send",
"type": "card",
"title": "8a. Send",
"subtitle": "Отправка сообщения",
"description": "```javascript\nsetSending(true)\nsetMessages([...messages, {\n role: 'user',\n content: input\n}])\n```",
"tags": [
"frontend"
],
"borderColor": "blue",
"x": 3940,
"y": 560
},
{
"id": "flow-chat-send-api",
"type": "card",
"title": "9. POST function=voice_ask",
"subtitle": "Отправка сообщения (существующий API)",
"description": "**URL:** https://eluxnetworks.net/function/well-api/api\n**Format:** x-www-form-urlencoded\n\n**Request:**\n```\nfunction=voice_ask\nclientId=MA_001\nuser_name=anandk\ntoken=jwt_token\nquestion=How is mom doing?\ndeployment_id=21\n```\n\n**Response 200:**\n```json\n{\n \"ok\": true,\n \"response\": {\n \"Command\": \"REPORT\",\n \"body\": \"Hello! How can I assist you?\",\n \"language\": \"English\"\n },\n \"status\": \"200 OK\"\n}\n```",
"tags": [
"backend"
],
"borderColor": "green",
"x": 4320,
"y": 560
},
{
"id": "flow-chat-openai",
"type": "card",
"title": "10. OpenAI GPT-3.5-turbo",
"subtitle": "AI обработка (на бэкенде)",
"description": "Бэкенд использует:\n**Модель:** gpt-3.5-turbo\n\nЭто происходит на сервере.\nФронтенд просто отправляет question и получает ответ.\n\n**Мы НЕ вызываем OpenAI напрямую!**",
"tags": [
"external"
],
"borderColor": "orange",
"x": 4700,
"y": 620
},
{
"id": "flow-chat-response",
"type": "card",
"title": "10a. Render Response",
"subtitle": "Показать ответ",
"description": "```javascript\nsetSending(false)\nsetMessages([...messages, {\n role: 'assistant',\n content: response.body\n}])\n```",
"tags": [
"frontend"
],
"borderColor": "blue",
"x": 4700,
"y": 760
},
{
"id": "flow-profile-screen",
"type": "card",
"title": "11. PROFILE SCREEN",
"subtitle": "Профиль пользователя",
"description": "**Файл:** `app/(tabs)/profile.tsx`\n\n**Секции:**\n- Аватар, имя, email\n- [Edit Profile]\n- Notification Settings\n- [Subscription]\n- [Logout]",
"tags": [
"frontend"
],
"borderColor": "blue",
"x": 3560,
"y": 760
},
{
"id": "flow-profile-api",
"type": "card",
"title": "11a. GET profile",
"subtitle": "Загрузка профиля",
"description": "**Response:**\n```json\n{\n \"name\": \"John\",\n \"email\": \"...\",\n \"subscription\": {...}\n}\n```",
"tags": [
"backend"
],
"borderColor": "green",
"x": 3940,
"y": 760
},
{
"id": "flow-profile-update",
"type": "card",
"title": "11b. PATCH profile",
"subtitle": "Обновление",
"description": "**Request:**\n```json\n{ \"name\": \"New\" }\n```",
"tags": [
"backend"
],
"borderColor": "green",
"x": 4320,
"y": 760
},
{
"id": "flow-subscription-screen",
"type": "card",
"title": "12. SUBSCRIPTION",
"subtitle": "Управление подпиской",
"description": "**Файл:** `app/subscription/index.tsx`\n\n**Планы:**\n- Free: 1 пациент\n- Basic ($9.99): 3 пациента\n- Premium ($19.99): Unlimited",
"tags": [
"frontend"
],
"borderColor": "blue",
"x": 3560,
"y": 900
},
{
"id": "flow-stripe-checkout",
"type": "card",
"title": "12a. Stripe Checkout",
"subtitle": "Страница оплаты",
"description": "WebView или in-app browser\n\nПосле оплаты → redirect\n`wellnuo://payment-success`",
"tags": [
"external"
],
"borderColor": "orange",
"x": 3940,
"y": 900
},
{
"id": "flow-stripe-webhook",
"type": "card",
"title": "12b. Stripe Webhook",
"subtitle": "Backend обработка",
"description": "**Events:**\n- checkout.session.completed\n- invoice.paid\n\nОбновление БД",
"tags": [
"backend"
],
"borderColor": "green",
"x": 4320,
"y": 900
},
{
"id": "flow-logout",
"type": "card",
"title": "13. LOGOUT",
"subtitle": "Выход из системы",
"description": "```javascript\nawait SecureStore.deleteItemAsync('accessToken')\nawait SecureStore.deleteItemAsync('userId')\nrouter.replace('/(auth)/login')\n```",
"tags": [
"frontend"
],
"borderColor": "blue",
"x": 3180,
"y": 900
},
{
"id": "db-schema",
"type": "card",
"title": "DATABASE SCHEMA",
"subtitle": "PostgreSQL таблицы",
"description": "**users:** id, name, email, password_hash, avatar, subscription\n\n**patients:** id, name, avatar, device_id, status, health_data\n\n**user_patients:** user_id, patient_id, relationship\n\n**messages:** id, user_id, patient_id, role, content\n\n**alerts:** id, patient_id, type, message, read\n\n**password_resets:** id, user_id, token, expires_at",
"tags": [
"backend"
],
"borderColor": "teal",
"x": 140,
"y": 1000
},
{
"id": "design-colors",
"type": "card",
"title": "DESIGN: Colors",
"subtitle": "Цветовая палитра",
"description": "**Primary:**\n- `#4A90D9` - Primary Blue\n- `#2E5C8A` - Primary Dark\n\n**Status:**\n- `#5AC8A8` - Success\n- `#F5A623` - Warning\n- `#D0021B` - Error\n\n**Neutral:**\n- `#FFFFFF` - Background\n- `#F5F7FA` - Surface\n- `#333333` - Text Primary",
"tags": [
"system"
],
"borderColor": "pink",
"x": 520,
"y": 1000
},
{
"id": "design-typography",
"type": "card",
"title": "DESIGN: Typography",
"subtitle": "Шрифты",
"description": "**Font:** Inter\n\n**Sizes:**\nxs: 12, sm: 14, base: 16\nlg: 18, xl: 20, 2xl: 24\n\n**Weights:** 400, 500, 600, 700",
"tags": [
"system"
],
"borderColor": "pink",
"x": 900,
"y": 1000
},
{
"id": "todo-frontend",
"type": "card",
"title": "TODO: Frontend задачи",
"subtitle": "Что нужно сделать",
"description": "**1. Auth:**\n- [ ] Login screen\n- [ ] Register screen\n- [ ] Forgot password\n- [ ] SecureStore\n\n**2. Chat:**\n- [ ] Chat UI (bubbles)\n- [ ] voice_ask API\n- [ ] Typing indicator\n\n**3. Patients:**\n- [ ] List screen\n- [ ] Dashboard\n- [ ] Add patient\n\n**4. Profile:**\n- [ ] Profile screen\n- [ ] Subscription\n- [ ] Logout",
"tags": [
"frontend"
],
"borderColor": "blue",
"completed": false,
"x": 1280,
"y": 1000
}
],
"connections": [
{
"from": "info-project",
"to": "info-legend"
},
{
"from": "info-legend",
"to": "info-data-flow"
},
{
"from": "info-project",
"to": "env-section"
},
{
"from": "env-section",
"to": "env-gitea"
},
{
"from": "env-section",
"to": "env-api-url"
},
{
"from": "env-section",
"to": "env-api-credentials"
},
{
"from": "env-section",
"to": "env-expo-project"
},
{
"from": "env-section",
"to": "env-stripe-pub"
},
{
"from": "env-section",
"to": "env-stripe-secret"
},
{
"from": "env-section",
"to": "env-sendgrid"
},
{
"from": "env-section",
"to": "api-structure"
},
{
"from": "api-structure",
"to": "flow-start"
},
{
"from": "flow-start",
"to": "flow-check-token"
},
{
"from": "flow-check-token",
"to": "flow-login-screen",
"label": "Нет токена"
},
{
"from": "flow-check-token",
"to": "flow-patients-list",
"label": "Есть токен"
},
{
"from": "flow-login-screen",
"to": "flow-login-loading",
"label": "Sign In"
},
{
"from": "flow-login-loading",
"to": "flow-login-api"
},
{
"from": "flow-login-api",
"to": "flow-login-condition"
},
{
"from": "flow-login-condition",
"to": "flow-login-success",
"label": "200 OK"
},
{
"from": "flow-login-condition",
"to": "flow-login-error",
"label": "Error"
},
{
"from": "flow-login-success",
"to": "flow-patients-list"
},
{
"from": "flow-login-error",
"to": "flow-login-screen",
"label": "Retry"
},
{
"from": "flow-login-screen",
"to": "flow-register-screen",
"label": "Create Account"
},
{
"from": "flow-register-screen",
"to": "flow-register-validate",
"label": "Submit"
},
{
"from": "flow-register-validate",
"to": "flow-register-api",
"label": "Valid"
},
{
"from": "flow-register-api",
"to": "flow-register-email"
},
{
"from": "flow-register-email",
"to": "flow-login-success"
},
{
"from": "flow-login-screen",
"to": "flow-forgot-screen",
"label": "Forgot?"
},
{
"from": "flow-forgot-screen",
"to": "flow-forgot-api",
"label": "Submit"
},
{
"from": "flow-forgot-api",
"to": "flow-login-screen",
"label": "Email sent"
},
{
"from": "flow-patients-list",
"to": "flow-patients-loading",
"label": "Mount"
},
{
"from": "flow-patients-loading",
"to": "flow-patients-api"
},
{
"from": "flow-patients-api",
"to": "flow-patients-condition"
},
{
"from": "flow-patients-condition",
"to": "flow-patients-render",
"label": "Success"
},
{
"from": "flow-patients-condition",
"to": "flow-patients-error",
"label": "Error"
},
{
"from": "flow-patients-error",
"to": "flow-patients-loading",
"label": "Retry"
},
{
"from": "flow-patients-render",
"to": "flow-patients-list",
"label": "Render"
},
{
"from": "flow-patients-list",
"to": "flow-patient-dashboard",
"label": "Select patient"
},
{
"from": "flow-patients-list",
"to": "flow-add-patient",
"label": "+ Add"
},
{
"from": "flow-add-patient",
"to": "flow-patients-list",
"label": "Created"
},
{
"from": "flow-patient-dashboard",
"to": "flow-chat-screen",
"label": "Chat with Julia"
},
{
"from": "flow-chat-screen",
"to": "flow-chat-send",
"label": "Send"
},
{
"from": "flow-chat-send",
"to": "flow-chat-send-api"
},
{
"from": "flow-chat-send-api",
"to": "flow-chat-openai"
},
{
"from": "flow-chat-openai",
"to": "flow-chat-response"
},
{
"from": "flow-chat-response",
"to": "flow-chat-screen",
"label": "Render"
},
{
"from": "flow-patients-list",
"to": "flow-profile-screen",
"label": "Tab: Profile"
},
{
"from": "flow-profile-screen",
"to": "flow-profile-api",
"label": "Load"
},
{
"from": "flow-profile-screen",
"to": "flow-profile-update",
"label": "Edit"
},
{
"from": "flow-profile-screen",
"to": "flow-subscription-screen",
"label": "Subscription"
},
{
"from": "flow-profile-screen",
"to": "flow-logout",
"label": "Logout"
},
{
"from": "flow-subscription-screen",
"to": "flow-stripe-checkout",
"label": "Select Plan"
},
{
"from": "flow-stripe-checkout",
"to": "flow-stripe-webhook"
},
{
"from": "flow-stripe-webhook",
"to": "flow-profile-screen",
"label": "Updated"
},
{
"from": "flow-logout",
"to": "flow-login-screen"
},
{
"from": "db-schema",
"to": "design-colors"
},
{
"from": "design-colors",
"to": "design-typography"
},
{
"from": "design-typography",
"to": "todo-frontend"
}
],
"tagsDictionary": [
{
"name": "system",
"color": "gray"
},
{
"name": "env",
"color": "cyan"
},
{
"name": "frontend",
"color": "blue"
},
{
"name": "backend",
"color": "green"
},
{
"name": "external",
"color": "orange"
}
]
}