{ "_meta": { "name": "Questions & API Analysis", }, "elements": [ { "id": "header", "type": "card", "title": "API Analysis Report", "borderColor": "purple", "tags": ["overview"], "description": "**Analysis Date:** December 15, 2025\n\n**Existing API:** 35+ endpoints (verified)\n**Missing for MVP:** 21 endpoints\n\n**Coverage:**\n- Core IoT: ✅ 100%\n- Auth: ⚠️ 20%\n- Profile: ❌ 0%\n- Billing: ❌ 0%\n- Push: ❌ 0%", "x": 140, "y": 300 }, { "id": "recommendation", "type": "card", "title": "✅ DECISION MADE", "borderColor": "green", "tags": ["decision", "resolved"], "description": "**Decision: Own Node.js + Supabase backend**\n\n**Status (Dec 18, 2025):**\n✅ Backend created: /backend/\n✅ Database migrated: Supabase\n✅ person_details = users table\n\n**Hybrid architecture:**\n- Our backend: auth, CRUD, push\n- eluxnetworks.net: IoT data, AI\n\n**Next steps:**\n1. Hash passwords (bcrypt)\n2. Create new tables (push_tokens, etc.)\n3. Implement forgot_password with Brevo\n4. Push notifications\n\nSee: 05_Database_Schema.json", "x": 520, "y": 120 }, { "id": "existing_api_summary", "type": "card", "title": "✅ Existing API (Working)", "borderColor": "green", "tags": ["existing"], "description": "**Auth:** credentials ✅\n**AI:** voice_ask ✅\n**Deployments:** CRUD + search ✅\n**Beneficiaries:** CRUD ✅\n**Caretakers:** CRUD ✅\n**Devices:** full management ✅\n**Alarms:** on/off, status ✅\n**Activity:** reports ✅\n**Dashboard:** list, single ✅\n**Floor/Maps:** layouts, locations ✅\n\n**Total: 35+ endpoints**\nAll verified working Dec 15, 2025", "x": 140, "y": 500 }, { "id": "missing_critical", "type": "card", "title": "🔴 CRITICAL - Blockers", "borderColor": "red", "tags": ["missing", "critical"], "description": "**Without these = NO App Store submission**\n\n1. **register** - new users can't sign up\n2. **forgot_password** - required by Apple\n3. **get_profile** - user data display\n4. **update_profile** - required by Apple/GDPR\n5. **delete_account** - REQUIRED by Apple since 2022\n6. **register_push_token** - core feature for alerts", "x": 520, "y": 300 }, { "id": "missing_important", "type": "card", "title": "🟡 IMPORTANT - MVP Features", "borderColor": "yellow", "tags": ["missing", "important"], "description": "**Needed for good user experience:**\n\n1. **reset_password** - complete password flow\n2. **refresh_token** - seamless auth\n3. **logout** - proper session end\n4. **change_password** - security settings\n5. **notification_settings** - manage alerts\n6. **invite_family_member** - add caregivers", "x": 520, "y": 480 }, { "id": "missing_optional", "type": "card", "title": "🟢 OPTIONAL - Can Postpone", "borderColor": "gray", "tags": ["missing", "optional"], "description": "**Can add after MVP launch:**\n\n1. Subscription plans/billing (if paid)\n2. Payment history\n3. Product catalog/orders\n4. Accept invitation flow\n5. Chat history persistence", "x": 520, "y": 660 }, { "id": "api_auth_register", "type": "card", "title": "register", "borderColor": "red", "tags": ["api", "auth", "critical"], "description": "**POST function=register**\n\n**Request:**\n```\nuser_name: string\nemail: string\npassword: string\nname: string\nphone?: string\n```\n\n**Response:**\n```json\n{\n \"user_id\": 123,\n \"access_token\": \"jwt...\",\n \"status\": \"200 OK\"\n}\n```\n\n⚠️ **Question:** Email verification?\n- Code to email?\n- Link confirmation?\n- No verification?", "x": 900, "y": 80 }, { "id": "api_auth_forgot", "type": "card", "title": "forgot_password", "borderColor": "red", "tags": ["api", "auth", "critical"], "description": "**POST function=forgot_password**\n\n**Request:**\n```\nemail: string\n```\n\n**Response:**\n```json\n{\n \"message\": \"Reset link sent\",\n \"status\": \"200 OK\"\n}\n```\n\nSends email with reset link/code", "x": 900, "y": 220 }, { "id": "api_auth_reset", "type": "card", "title": "reset_password", "borderColor": "yellow", "tags": ["api", "auth", "important"], "description": "**POST function=reset_password**\n\n**Request:**\n```\ntoken: string (from email)\nnew_password: string\n```\n\n**Response:**\n```json\n{\n \"success\": true,\n \"status\": \"200 OK\"\n}\n```", "x": 900, "y": 360 }, { "id": "api_auth_refresh", "type": "card", "title": "refresh_token", "borderColor": "yellow", "tags": ["api", "auth", "important"], "description": "**POST function=refresh_token**\n\n**Request:**\n```\nrefresh_token: string\n```\n\n**Response:**\n```json\n{\n \"access_token\": \"new_jwt...\",\n \"refresh_token\": \"new_refresh...\",\n \"status\": \"200 OK\"\n}\n```\n\nFor seamless re-auth when token expires", "x": 900, "y": 500 }, { "id": "api_auth_logout", "type": "card", "title": "logout", "borderColor": "yellow", "tags": ["api", "auth", "important"], "description": "**POST function=logout**\n\n**Request:**\n```\ntoken: string\n```\n\n**Response:**\n```json\n{\n \"success\": true,\n \"status\": \"200 OK\"\n}\n```\n\nInvalidates token on server side", "x": 900, "y": 640 }, { "id": "api_profile_get", "type": "card", "title": "get_profile", "borderColor": "red", "tags": ["api", "profile", "critical"], "description": "**POST function=get_profile**\n\n**Request:**\n```\ntoken: string\nuser_name: string\n```\n\n**Response:**\n```json\n{\n \"user_id\": 123,\n \"user_name\": \"john\",\n \"email\": \"john@example.com\",\n \"name\": \"John Doe\",\n \"phone\": \"+1234567890\",\n \"avatar_url\": \"https://...\",\n \"created_at\": \"2024-01-01\",\n \"status\": \"200 OK\"\n}\n```", "x": 1280, "y": 80 }, { "id": "api_profile_update", "type": "card", "title": "update_profile", "borderColor": "red", "tags": ["api", "profile", "critical"], "description": "**POST function=update_profile**\n\n**Request:**\n```\ntoken: string\nuser_name: string\nname?: string\nemail?: string\nphone?: string\navatar_url?: string\n```\n\n**Response:**\n```json\n{\n \"success\": true,\n \"status\": \"200 OK\"\n}\n```\n\n**Required by Apple App Store**", "x": 1280, "y": 220 }, { "id": "api_profile_password", "type": "card", "title": "change_password", "borderColor": "yellow", "tags": ["api", "profile", "important"], "description": "**POST function=change_password**\n\n**Request:**\n```\ntoken: string\nuser_name: string\nold_password: string\nnew_password: string\n```\n\n**Response:**\n```json\n{\n \"success\": true,\n \"status\": \"200 OK\"\n}\n```", "x": 1280, "y": 360 }, { "id": "api_profile_delete", "type": "card", "title": "delete_account", "borderColor": "red", "tags": ["api", "profile", "critical"], "description": "**POST function=delete_account**\n\n**Request:**\n```\ntoken: string\nuser_name: string\npassword: string (confirm)\n```\n\n**Response:**\n```json\n{\n \"success\": true,\n \"status\": \"200 OK\"\n}\n```\n\n⚠️ **REQUIRED BY APPLE**\nSince June 2022, all apps must allow account deletion", "x": 1280, "y": 500 }, { "id": "api_push_register", "type": "card", "title": "register_push_token", "borderColor": "red", "tags": ["api", "push", "critical"], "description": "**POST function=register_push_token**\n\n**Request:**\n```\ntoken: string (auth)\nuser_name: string\npush_token: string (FCM/APNs)\nplatform: \"ios\" | \"android\"\ndevice_id: string\n```\n\n**Response:**\n```json\n{\n \"success\": true,\n \"status\": \"200 OK\"\n}\n```\n\n**Critical for alarm notifications!**", "x": 1660, "y": 80 }, { "id": "api_push_settings_get", "type": "card", "title": "get_notification_settings", "borderColor": "yellow", "tags": ["api", "push", "important"], "description": "**POST function=get_notification_settings**\n\n**Request:**\n```\ntoken: string\nuser_name: string\n```\n\n**Response:**\n```json\n{\n \"alerts_enabled\": true,\n \"daily_report\": true,\n \"quiet_hours\": {\n \"enabled\": false,\n \"start\": \"22:00\",\n \"end\": \"07:00\"\n },\n \"status\": \"200 OK\"\n}\n```", "x": 1660, "y": 220 }, { "id": "api_push_settings_update", "type": "card", "title": "update_notification_settings", "borderColor": "yellow", "tags": ["api", "push", "important"], "description": "**POST function=update_notification_settings**\n\n**Request:**\n```\ntoken: string\nuser_name: string\nalerts_enabled?: boolean\ndaily_report?: boolean\nquiet_hours_enabled?: boolean\nquiet_hours_start?: string\nquiet_hours_end?: string\n```\n\n**Response:**\n```json\n{\n \"success\": true,\n \"status\": \"200 OK\"\n}\n```", "x": 1660, "y": 360 }, { "id": "api_invite", "type": "card", "title": "invite_family_member", "borderColor": "yellow", "tags": ["api", "family", "important"], "description": "**POST function=invite_family_member**\n\n**Request:**\n```\ntoken: string\nuser_name: string\ndeployment_id: number\ninvite_email: string\nrelationship: string\n```\n\n**Response:**\n```json\n{\n \"invite_id\": \"abc123\",\n \"message\": \"Invitation sent\",\n \"status\": \"200 OK\"\n}\n```\n\nAllows adding family caregivers to monitor same beneficiary", "x": 1660, "y": 500 }, { "id": "questions_header", "type": "card", "title": "Open Questions", "borderColor": "purple", "tags": ["questions"], "description": "Questions that need answers from Robert/EluxNetworks team", "x": 140, "y": 800 }, { "id": "q_webview_ui", "type": "card", "title": "Q1: WebView UI Cleanup", "borderColor": "yellow", "tags": ["questions"], "description": "Can you remove from browser version:\n\n1. Header «Dashboard Details»\n2. Navigation arrows (← →)\n3. Logout button\n\n**Reason:** Embedding in WebView, have own navigation.\n\n**Suggestion:** ?embedded=true parameter", "x": 520, "y": 800 }, { "id": "q_backend_access", "type": "card", "title": "Q2: Backend Access ✅ RESOLVED", "borderColor": "green", "tags": ["questions", "resolved"], "description": "**РЕШЕНО: Dec 18, 2025**\n\n**Решение:** Создаём собственный Node.js + Supabase backend\n\n**Архитектура (hybrid):**\n- Our backend: auth, users, push tokens, profiles\n- eluxnetworks.net: sensor data, AI (voice_ask), maps\n\n**Database:** Supabase PostgreSQL\nДанные мигрированы: 8 users, 45 deployments, 455 devices\n\n**Backend path:** /backend/\n**See:** 05_Database_Schema.json, 01_ENV_Credentials.json", "x": 520, "y": 980 }, { "id": "q_email_verification", "type": "card", "title": "Q3: Email Verification", "borderColor": "yellow", "tags": ["questions"], "description": "For user registration, how to verify email?\n\n**Options:**\n1. Send code to email (6 digits)\n2. Send confirmation link\n3. No verification (simplest)\n\n**Recommendation:** Option 1 (code) - best UX for mobile", "x": 900, "y": 800 }, { "id": "q_push_service", "type": "card", "title": "Q4: Push Notification Service", "borderColor": "yellow", "tags": ["questions"], "description": "Which service for push notifications?\n\n**Options:**\n1. Firebase Cloud Messaging (FCM)\n2. Expo Push Notifications\n3. OneSignal\n4. Amazon SNS\n\n**Recommendation:** Expo Push - easiest integration with our stack", "x": 900, "y": 980 }, { "id": "q_payments", "type": "card", "title": "Q5: Payment System", "borderColor": "yellow", "tags": ["questions"], "description": "Is the app paid?\n\n**If yes:**\n- Stripe integration needed\n- Apple In-App Purchases?\n- Subscription model?\n\n**If no (MVP):**\n- Skip billing API for now\n- Add later", "x": 1280, "y": 800 }, { "id": "q_wellness", "type": "card", "title": "Q6: Wellness Feature", "borderColor": "yellow", "tags": ["questions"], "description": "What is the purpose of Wellness?\n\n- Is it needed for MVP?\n- What data does it track?\n- How different from Dashboard?\n\n**Current status:** Unclear, need clarification", "x": 1280, "y": 980 } ], "connections": [ {"from": "header", "to": "recommendation"}, {"from": "header", "to": "existing_api_summary"}, {"from": "header", "to": "missing_critical"}, {"from": "missing_critical", "to": "missing_important"}, {"from": "missing_important", "to": "missing_optional"}, {"from": "missing_critical", "to": "api_auth_register"}, {"from": "missing_critical", "to": "api_auth_forgot"}, {"from": "missing_critical", "to": "api_profile_get"}, {"from": "missing_critical", "to": "api_profile_update"}, {"from": "missing_critical", "to": "api_profile_delete"}, {"from": "missing_critical", "to": "api_push_register"}, {"from": "missing_important", "to": "api_auth_reset"}, {"from": "missing_important", "to": "api_auth_refresh"}, {"from": "missing_important", "to": "api_auth_logout"}, {"from": "missing_important", "to": "api_profile_password"}, {"from": "missing_important", "to": "api_push_settings_get"}, {"from": "missing_important", "to": "api_push_settings_update"}, {"from": "missing_important", "to": "api_invite"}, {"from": "api_auth_register", "to": "api_auth_forgot"}, {"from": "api_auth_forgot", "to": "api_auth_reset"}, {"from": "api_auth_reset", "to": "api_auth_refresh"}, {"from": "api_auth_refresh", "to": "api_auth_logout"}, {"from": "api_profile_get", "to": "api_profile_update"}, {"from": "api_profile_update", "to": "api_profile_password"}, {"from": "api_profile_password", "to": "api_profile_delete"}, {"from": "api_push_register", "to": "api_push_settings_get"}, {"from": "api_push_settings_get", "to": "api_push_settings_update"}, {"from": "header", "to": "questions_header"}, {"from": "questions_header", "to": "q_webview_ui"}, {"from": "questions_header", "to": "q_backend_access"}, {"from": "questions_header", "to": "q_email_verification"}, {"from": "questions_header", "to": "q_push_service"}, {"from": "questions_header", "to": "q_payments"}, {"from": "questions_header", "to": "q_wellness"}, {"from": "recommendation", "to": "q_backend_access", "label": "Key question"} ], "tagsDictionary": [ {"name": "overview", "color": "purple"}, {"name": "decision", "color": "green"}, {"name": "existing", "color": "green"}, {"name": "missing", "color": "orange"}, {"name": "critical", "color": "red"}, {"name": "important", "color": "yellow"}, {"name": "optional", "color": "gray"}, {"name": "api", "color": "blue"}, {"name": "auth", "color": "blue"}, {"name": "profile", "color": "teal"}, {"name": "push", "color": "pink"}, {"name": "family", "color": "cyan"}, {"name": "questions", "color": "yellow"}, {"name": "resolved", "color": "lime"} ] }