WellNuo/wellnuoSheme/SysAnal.json
Sergei 0c9eb0c088 Add Supabase migration and update schemes
- Migrated PostgreSQL data to Supabase (531 rows total)
- Added Supabase Database card to ENV scheme
- Added migration SQL files and CSV exports
- Tables: deployments(45), devices(455), person_details(8), deployment_details(23)

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

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

957 lines
27 KiB
JSON

{
"_meta": {
"name": "SysAnal",
"updatedAt": "2025-12-13T00:45:17.412Z"
},
"elements": [
{
"id": "info-project",
"type": "card",
"title": "WellNuo Mobile App",
"subtitle": "Elderly Care Monitoring",
"description": "**Stack:**\n- React Native 0.81.5 + Expo SDK 54\n- Expo Router 6.x\n- Backend: existing API (Python)\n- AI: OpenAI GPT-3.5-turbo (text only)\n\n**Repository:**\nGitea: `robert/MobileApp_react_native`\nBranch: `development`\n\n**We build:** frontend only",
"tags": [
"system"
],
"borderColor": "gray",
"x": 140,
"y": 543.75
},
{
"id": "info-legend",
"type": "card",
"title": "TAG LEGEND",
"subtitle": "Who performs the action",
"description": "**frontend** - React Native app (our work)\n**backend** - Existing API (already done)\n**external** - External services (OpenAI, Stripe)\n**env** - Environment variables/credentials\n\n**completed: true** = access obtained/verified\n**completed: false** = need to obtain",
"tags": [
"system"
],
"borderColor": "gray",
"x": 520,
"y": 716.25
},
{
"id": "info-data-flow",
"type": "card",
"title": "DATA FLOW PATTERN",
"subtitle": "How data flows",
"description": "**Every data screen:**\n\n1. **Mount** → setLoading(true)\n2. **API Request** → frontend → backend\n3. **Condition** → success/error?\n4. **Success** → setData() → render\n5. **Error** → setError() → Retry\n\n**Arrows:** → request | ← response",
"tags": [
"system"
],
"borderColor": "gray",
"x": 140,
"y": 780
},
{
"id": "env-section",
"type": "card",
"title": "ENV / CREDENTIALS",
"subtitle": "All project credentials",
"description": "Environment variables section.\nVerified: December 12, 2025\n\n✅ = available | ❌ = needed",
"tags": [
"env"
],
"borderColor": "cyan",
"x": 520,
"y": 307.5
},
{
"id": "env-gitea",
"type": "card",
"title": "GITEA_URL ✅",
"subtitle": "Code repository",
"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**Parameter:** function=function_name\n\n**Dashboard:** https://react.eluxnetworks.net/dashboard\n\n**Verified:** working ✅",
"tags": [
"env",
"backend"
],
"borderColor": "cyan",
"completed": true,
"x": 900,
"y": 192.5
},
{
"id": "env-api-credentials",
"type": "card",
"title": "API_CREDENTIALS ✅",
"subtitle": "Login/password for API",
"description": "**Username:** anandk\n**Password:** anandk_8\n\n**Test response:**\n- user_id: 43\n- max_role: 2\n- privileges: 21,38,29,41,42\n\n**Verified:** 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": "For EAS Build and Push Notifications\n\nhttps://expo.dev\n\n**Project ID:** 4f415b4b-41c8-4b98-989c-32f6b3f97481\n**Owner:** serter2069ya\n\nCreated: Dec 17, 2025",
"tags": [
"env"
],
"borderColor": "cyan",
"completed": true,
"x": 900,
"y": 422.5
},
{
"id": "env-stripe-pub",
"type": "card",
"title": "STRIPE_PUBLISHABLE_KEY ❌",
"subtitle": "Stripe Public Key",
"description": "`pk_xxx`\n\nFor in-app payments\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\nBackend only!",
"tags": [
"env",
"backend"
],
"borderColor": "cyan",
"completed": false,
"x": 1280,
"y": 192.5
},
{
"id": "env-sendgrid",
"type": "card",
"title": "SENDGRID_API_KEY ❌",
"subtitle": "Email service",
"description": "`SG.xxx`\n\nFor sending:\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": "Existing API structure",
"description": "**Base URL:**\n`https://eluxnetworks.net/function/well-api/api`\n\n**Format:** POST x-www-form-urlencoded\n\n**Functions (verified):**\n- `function=credentials` → login\n- `function=voice_ask` → AI chat\n\n**Parameters credentials:**\n- user_name, ps, clientId, nonce\n\n**Parameters 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": "App launch",
"description": "**File:** `app/_layout.tsx`\n\nUser opens the app.\nSplash Screen is shown.",
"tags": [
"frontend"
],
"borderColor": "blue",
"x": 900,
"y": 652.5
},
{
"id": "flow-check-token",
"type": "condition",
"title": "2. Token in SecureStore?",
"subtitle": "Authorization check",
"description": "```javascript\nconst token = await SecureStore.getItemAsync('accessToken')\n```\n\nIf token exists → verify validity\nIf not → Login Screen",
"tags": [
"frontend"
],
"borderColor": "yellow",
"x": 1280,
"y": 652.5
},
{
"id": "flow-login-screen",
"type": "card",
"title": "3. LOGIN SCREEN",
"subtitle": "Login screen",
"description": "**File:** `app/(auth)/login.tsx`\n\n**State:**\n- username, password\n- loading, error\n\n**Fields:**\n- Username (not email!)\n- Password\n\n**Buttons:**\n- [Sign In]\n- [Forgot Password?]\n- [Create Account]",
"tags": [
"frontend"
],
"borderColor": "blue",
"x": 1948.8316650390625,
"y": 717.6703491210938
},
{
"id": "flow-login-loading",
"type": "card",
"title": "3a. Loading State",
"subtitle": "Show spinner",
"description": "```javascript\nsetLoading(true)\nsetError(null)\n```\n\n- Disable button\n- Show spinner",
"tags": [
"frontend"
],
"borderColor": "blue",
"x": 1660,
"y": 540
},
{
"id": "flow-login-api",
"type": "card",
"title": "4. POST function=credentials",
"subtitle": "Authorization (existing 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": 1981.828125,
"y": 401.3630065917969
},
{
"id": "flow-login-condition",
"type": "condition",
"title": "4a. Success?",
"subtitle": "Response check",
"description": "**status === \"200 OK\"?**\n\n**Yes** → Save token\n**No** → Show error",
"tags": [
"frontend"
],
"borderColor": "yellow",
"x": 2388.911865234375,
"y": 394.84893798828125
},
{
"id": "flow-login-success",
"type": "card",
"title": "5. Save token",
"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\nNavigate to main screen",
"tags": [
"frontend"
],
"borderColor": "blue",
"x": 2800,
"y": 480
},
{
"id": "flow-login-error",
"type": "card",
"title": "5b. Error State",
"subtitle": "Show error",
"description": "```javascript\nsetLoading(false)\nsetError('Invalid credentials')\n```\n\n- Red error text\n- Retry button active",
"tags": [
"frontend"
],
"borderColor": "red",
"x": 2578.297607421875,
"y": 681.2437744140625
},
{
"id": "flow-register-screen",
"type": "card",
"title": "3r. REGISTER SCREEN",
"subtitle": "Registration screen",
"description": "**File:** `app/(auth)/register.tsx`\n\n**Fields:**\n- Full Name\n- Email\n- Password\n- Confirm Password\n\n**Buttons:**\n- [Create Account]\n- [Sign In]",
"tags": [
"frontend"
],
"borderColor": "blue",
"x": 1660,
"y": 880
},
{
"id": "flow-register-validate",
"type": "condition",
"title": "3r-1. Validation?",
"subtitle": "Client-side check",
"description": "- Name not empty?\n- Email valid?\n- Password >= 6?\n- Passwords match?",
"tags": [
"frontend"
],
"borderColor": "yellow",
"x": 2040,
"y": 880
},
{
"id": "flow-register-api",
"type": "card",
"title": "3r-2. POST register",
"subtitle": "Registration 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 sends welcome email\n\n(on server)",
"tags": [
"external"
],
"borderColor": "orange",
"x": 2800,
"y": 880
},
{
"id": "flow-forgot-screen",
"type": "card",
"title": "3f. FORGOT PASSWORD",
"subtitle": "Password recovery",
"description": "**File:** `app/(auth)/forgot.tsx`\n\n**Field:** Email\n\n**Buttons:**\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": "Reset 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": "Main screen - patients list",
"description": "**File:** `app/(tabs)/index.tsx`\n\n**State:**\n- patients: Patient[]\n- loading, error\n\n**UI:**\n- Card list\n- Pull to refresh\n- [+] Add\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 request",
"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. Success?",
"subtitle": "Check",
"description": "**ok === true?**\n\n**Yes** → render\n**No** → error",
"tags": [
"frontend"
],
"borderColor": "yellow",
"x": 4320,
"y": 400
},
{
"id": "flow-patients-render",
"type": "card",
"title": "6d. Render",
"subtitle": "Render",
"description": "```javascript\nsetLoading(false)\nsetPatients(data)\n```\n\nFlatList updates",
"tags": [
"frontend"
],
"borderColor": "blue",
"x": 4700,
"y": 340
},
{
"id": "flow-patients-error",
"type": "card",
"title": "6e. Error",
"subtitle": "Error + Retry",
"description": "```javascript\nsetError('Failed')\n```\n\n[Retry] button",
"tags": [
"frontend"
],
"borderColor": "red",
"x": 4700,
"y": 480
},
{
"id": "flow-patient-dashboard",
"type": "card",
"title": "7. PATIENT DASHBOARD",
"subtitle": "Patient dashboard",
"description": "**File:** `app/patients/[id]/index.tsx`\n\n**Sections:**\n- Status (online/offline)\n- Health (pulse, steps, sleep)\n- Medication reminders\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": "Add patient",
"description": "**File:** `app/patients/add.tsx`\n\n**Fields:**\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": "Text chat with Julia",
"description": "**File:** `app/(tabs)/chat.tsx`\n\n**State:**\n- messages: Message[]\n- input, sending\n\n**UI:**\n- History (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": "Send message",
"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": "Send message (existing 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 processing (on backend)",
"description": "Backend uses:\n**Model:** gpt-3.5-turbo\n\nThis happens on server.\nFrontend just sends question and gets response.\n\n**We do NOT call OpenAI directly!**",
"tags": [
"external"
],
"borderColor": "orange",
"x": 4700,
"y": 620
},
{
"id": "flow-chat-response",
"type": "card",
"title": "10a. Render Response",
"subtitle": "Show response",
"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": "User profile",
"description": "**File:** `app/(tabs)/profile.tsx`\n\n**Sections:**\n- Avatar, name, 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": "Load profile",
"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": "Update",
"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": "Subscription management",
"description": "**File:** `app/subscription/index.tsx`\n\n**Plans:**\n- Free: 1 patient\n- Basic ($9.99): 3 patients\n- Premium ($19.99): Unlimited",
"tags": [
"frontend"
],
"borderColor": "blue",
"x": 3560,
"y": 900
},
{
"id": "flow-stripe-checkout",
"type": "card",
"title": "12a. Stripe Checkout",
"subtitle": "Payment page",
"description": "WebView or in-app browser\n\nAfter payment → 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 processing",
"description": "**Events:**\n- checkout.session.completed\n- invoice.paid\n\nDB update",
"tags": [
"backend"
],
"borderColor": "green",
"x": 4320,
"y": 900
},
{
"id": "flow-logout",
"type": "card",
"title": "13. LOGOUT",
"subtitle": "Sign out",
"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 tables",
"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": "Color palette",
"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": "Fonts",
"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 tasks",
"subtitle": "What needs to be done",
"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": "No token"
},
{
"from": "flow-check-token",
"to": "flow-patients-list",
"label": "Has token"
},
{
"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"
}
]
}