{ "_meta": { "name": "WellNuo - UX Flow (Step by Step)", "updatedAt": "2025-12-12T21:07:42.362Z" }, "elements": [ { "id": "start", "type": "card", "title": "1. App Launch", "borderColor": "purple", "tags": [ "user" ], "description": "Пользователь открывает приложение\n\nДействие: Tap на иконку WellNuo\nРезультат: Запуск приложения", "x": 140, "y": 396.25 }, { "id": "check_token", "type": "card", "title": "2. Check Stored Token", "borderColor": "green", "tags": [ "frontend" ], "description": "Frontend проверяет наличие токена\n\nИсточник: SecureStore\nКлюч: 'access_token'\n\nЕсли есть → проверить валидность\nЕсли нет → показать Login", "x": 520, "y": 396.25 }, { "id": "token_exists", "type": "condition", "title": "Token exists?", "borderColor": "yellow", "tags": [ "decision" ], "description": "Есть ли сохраненный токен?", "x": 890, "y": 396.25 }, { "id": "show_login", "type": "card", "title": "3. Login Screen", "borderColor": "green", "tags": [ "frontend" ], "description": "Экран авторизации\n\nПоля:\n- Username (TextInput)\n- Password (TextInput, secure)\n- Login Button\n\nСостояние: loading, error, idle", "x": 6160, "y": 573.75 }, { "id": "user_enters_creds", "type": "card", "title": "4. Enter Credentials", "borderColor": "purple", "tags": [ "user" ], "description": "Пользователь вводит данные\n\nUsername: string (required)\nPassword: string (required)\n\nДействие: Нажимает Login", "x": 6540, "y": 607.5 }, { "id": "validate_input", "type": "card", "title": "5. Validate Input", "borderColor": "green", "tags": [ "frontend" ], "description": "Клиентская валидация\n\nПроверки:\n- Username не пустой\n- Password не пустой\n- Длина >= 3 символов\n\nОшибка → показать inline error", "x": 6920, "y": 607.5 }, { "id": "input_valid", "type": "condition", "title": "Input valid?", "borderColor": "yellow", "tags": [ "decision" ], "description": "Прошла ли клиентская валидация?", "x": 7290, "y": 607.5 }, { "id": "send_auth_request", "type": "card", "title": "6. Send Auth Request", "borderColor": "green", "tags": [ "frontend" ], "description": "POST запрос на авторизацию\n\nURL: https://eluxnetworks.net/function/well-api/api\nContent-Type: x-www-form-urlencoded\n\nBody:\n- function=credentials\n- user_name={username}\n- ps={password}\n- clientId={deviceId}\n- nonce={timestamp}", "x": 7660, "y": 607.5 }, { "id": "backend_auth", "type": "card", "title": "7. Validate Credentials", "borderColor": "blue", "tags": [ "backend" ], "description": "Backend проверяет credentials\n\nПроцесс:\n1. Проверка user_name в DB\n2. Сравнение password hash\n3. Генерация access_token\n4. Возврат user_id, privileges\n\nУспех: { ok: true, access_token, user_id }\nОшибка: { ok: false, error: 'message' }", "x": 8040, "y": 607.5 }, { "id": "auth_success", "type": "condition", "title": "Auth success?", "borderColor": "yellow", "tags": [ "decision" ], "description": "ok === true?", "x": 8410, "y": 607.5 }, { "id": "store_token", "type": "card", "title": "8. Store Token", "borderColor": "green", "tags": [ "frontend" ], "description": "Сохранение данных авторизации\n\nSecureStore:\n- access_token\n- user_id\n- user_name\n\nAsyncStorage:\n- privileges\n- login_timestamp", "x": 8780, "y": 145 }, { "id": "show_auth_error", "type": "card", "title": "Auth Error", "borderColor": "red", "tags": [ "error", "frontend" ], "description": "Показать ошибку авторизации\n\nТипы ошибок:\n- Invalid credentials\n- Account locked\n- Network error\n- Server error\n\nДействие: Alert или inline message", "x": 8780, "y": 607.5 }, { "id": "main_chat", "type": "card", "title": "9. Chat Screen", "borderColor": "green", "tags": [ "frontend" ], "description": "Главный экран чата\n\nКомпоненты:\n- Header (user info, logout)\n- MessageList (FlatList)\n- InputField + Send Button\n\nСостояние:\n- messages: []\n- inputText: ''\n- isLoading: false", "x": 1260, "y": 155 }, { "id": "user_types", "type": "card", "title": "10. Type Message", "borderColor": "purple", "tags": [ "user" ], "description": "Пользователь пишет сообщение\n\nДействие: Ввод текста в TextInput\nЗатем: Нажимает Send или Enter", "x": 1640, "y": 325 }, { "id": "validate_message", "type": "card", "title": "11. Validate Message", "borderColor": "green", "tags": [ "frontend" ], "description": "Проверка сообщения\n\n- Не пустое\n- Длина <= 4000 символов\n- Не только пробелы\n\nДобавить в messages[] как 'user'", "x": 2020, "y": 325 }, { "id": "message_valid", "type": "condition", "title": "Message valid?", "borderColor": "yellow", "tags": [ "decision" ], "description": "Прошла ли валидация сообщения?", "x": 2390, "y": 268.75 }, { "id": "send_chat_request", "type": "card", "title": "12. Send Chat Request", "borderColor": "green", "tags": [ "frontend" ], "description": "POST запрос на AI chat\n\nURL: https://eluxnetworks.net/function/well-api/api\nContent-Type: x-www-form-urlencoded\n\nBody:\n- function=voice_ask\n- clientId={deviceId}\n- user_name={username}\n- token={access_token}\n- question={message}\n- deployment_id={model_id}\n\nState: isLoading = true", "x": 2760, "y": 268.75 }, { "id": "backend_chat", "type": "card", "title": "13. Process Chat Request", "borderColor": "blue", "tags": [ "backend" ], "description": "Backend обрабатывает запрос\n\n1. Валидация token\n2. Rate limiting check\n3. Подготовка prompt\n4. Вызов AI провайдера\n5. Логирование\n6. Возврат ответа", "x": 3140, "y": 245 }, { "id": "call_openrouter", "type": "card", "title": "14. AI Provider Request", "borderColor": "orange", "tags": [ "external" ], "description": "Запрос к OpenRouter\n\nURL: https://openrouter.ai/api/v1/chat/completions\nModel: gpt-3.5-turbo\n\nПараметры:\n- messages: [{role, content}]\n- max_tokens: 1000\n- temperature: 0.7", "x": 3520, "y": 245 }, { "id": "ai_response", "type": "card", "title": "15. AI Response", "borderColor": "orange", "tags": [ "external" ], "description": "OpenRouter возвращает ответ\n\n{\n choices: [{\n message: {\n content: 'AI response text'\n }\n }]\n}", "x": 3900, "y": 245 }, { "id": "backend_response", "type": "card", "title": "16. Backend Response", "borderColor": "blue", "tags": [ "backend" ], "description": "Backend формирует ответ\n\nУспех:\n{\n ok: true,\n response: {\n body: 'AI response text'\n }\n}\n\nОшибка:\n{ ok: false, error: 'message' }", "x": 4280, "y": 245 }, { "id": "chat_success", "type": "condition", "title": "Response OK?", "borderColor": "yellow", "tags": [ "decision" ], "description": "ok === true?", "x": 4650, "y": 245 }, { "id": "display_response", "type": "card", "title": "17. Display Response", "borderColor": "green", "tags": [ "frontend" ], "description": "Отображение ответа AI\n\nДобавить в messages[]:\n{\n role: 'assistant',\n content: response.body,\n timestamp: Date.now()\n}\n\nisLoading = false\nScroll to bottom", "x": 5020, "y": 77.5 }, { "id": "show_chat_error", "type": "card", "title": "Chat Error", "borderColor": "red", "tags": [ "error", "frontend" ], "description": "Показать ошибку чата\n\nТипы:\n- Token expired → re-login\n- Rate limit → wait message\n- AI error → retry option\n- Network → offline mode?\n\nisLoading = false", "x": 5020, "y": 543.75 }, { "id": "token_expired", "type": "condition", "title": "Token expired?", "borderColor": "yellow", "tags": [ "decision" ], "description": "Ошибка 401 или token_expired?", "x": 5400, "y": 543.75 }, { "id": "clear_auth", "type": "card", "title": "Clear Auth Data", "borderColor": "green", "tags": [ "frontend" ], "description": "Очистка данных авторизации\n\nSecureStore.deleteItemAsync('access_token')\nSecureStore.deleteItemAsync('user_id')\n\nПеренаправление на Login Screen", "x": 5780, "y": 567.5 }, { "id": "retry_option", "type": "card", "title": "Retry Option", "borderColor": "green", "tags": [ "frontend" ], "description": "Предложить повторить\n\nUI: Кнопка 'Retry' под ошибкой\nДействие: Повторный send_chat_request\n\nМакс. 3 попытки", "x": 5780, "y": 291.25 }, { "id": "logout", "type": "card", "title": "Logout", "borderColor": "purple", "tags": [ "user" ], "description": "Пользователь выходит\n\nДействие: Нажимает Logout в Header\n\nОчистка:\n- SecureStore tokens\n- AsyncStorage data\n- Reset navigation to Login", "x": 5400, "y": 416.25 }, { "id": "end_session", "type": "card", "title": "Session End", "borderColor": "gray", "tags": [ "frontend" ], "description": "Завершение сессии\n\nВозврат на Login Screen\nГотов к новой авторизации", "x": 5780, "y": 440 } ], "connections": [ { "from": "start", "to": "check_token" }, { "from": "check_token", "to": "token_exists" }, { "from": "token_exists", "to": "main_chat", "label": "yes" }, { "from": "token_exists", "to": "show_login", "label": "no" }, { "from": "show_login", "to": "user_enters_creds" }, { "from": "user_enters_creds", "to": "validate_input" }, { "from": "validate_input", "to": "input_valid" }, { "from": "input_valid", "to": "send_auth_request", "label": "yes" }, { "from": "input_valid", "to": "show_login", "label": "no (show error)" }, { "from": "send_auth_request", "to": "backend_auth" }, { "from": "backend_auth", "to": "auth_success" }, { "from": "auth_success", "to": "store_token", "label": "yes" }, { "from": "auth_success", "to": "show_auth_error", "label": "no" }, { "from": "store_token", "to": "main_chat" }, { "from": "show_auth_error", "to": "show_login" }, { "from": "main_chat", "to": "user_types" }, { "from": "user_types", "to": "validate_message" }, { "from": "validate_message", "to": "message_valid" }, { "from": "message_valid", "to": "send_chat_request", "label": "yes" }, { "from": "message_valid", "to": "main_chat", "label": "no" }, { "from": "send_chat_request", "to": "backend_chat" }, { "from": "backend_chat", "to": "call_openrouter" }, { "from": "call_openrouter", "to": "ai_response" }, { "from": "ai_response", "to": "backend_response" }, { "from": "backend_response", "to": "chat_success" }, { "from": "chat_success", "to": "display_response", "label": "yes" }, { "from": "chat_success", "to": "show_chat_error", "label": "no" }, { "from": "display_response", "to": "main_chat", "label": "loop" }, { "from": "show_chat_error", "to": "token_expired" }, { "from": "token_expired", "to": "clear_auth", "label": "yes" }, { "from": "token_expired", "to": "retry_option", "label": "no" }, { "from": "clear_auth", "to": "show_login" }, { "from": "retry_option", "to": "send_chat_request", "label": "retry" }, { "from": "retry_option", "to": "main_chat", "label": "cancel" }, { "from": "main_chat", "to": "logout", "label": "logout action" }, { "from": "logout", "to": "end_session" }, { "from": "end_session", "to": "show_login" } ], "tagsDictionary": [ { "id": "tag-user", "name": "user", "color": "purple" }, { "id": "tag-frontend", "name": "frontend", "color": "green" }, { "id": "tag-backend", "name": "backend", "color": "blue" }, { "id": "tag-external", "name": "external", "color": "orange" }, { "id": "tag-decision", "name": "decision", "color": "yellow" }, { "id": "tag-error", "name": "error", "color": "red" } ] }