Files
chat/docs/MOBILE_QUICK_START.md
Andrey K. Choi 3050e084fa
All checks were successful
continuous-integration/drone/push Build is passing
main functions commit
2025-10-19 19:50:00 +09:00

198 lines
6.5 KiB
Markdown
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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.

# 🚀 БЫСТРЫЙ СТАРТ: Интеграция Emergency Service в мобильное приложение
## 📋 КРАТКИЙ ЧЕКЛИСТ (30 минут)
### 1⃣ УДАЛИТЕ ВРЕМЕННЫЕ ТОКЕНЫ (5 мин)
```kotlin
// ❌ УДАЛИТЬ:
val tempToken = "temp_token_for_${email}"
// ✅ ЗАМЕНИТЬ:
val jwtToken = authManager.getValidJwtToken()
```
### 2⃣ ДОБАВЬТЕ JWT АУТЕНТИФИКАЦИЮ (10 мин)
```kotlin
// Добавить в build.gradle
implementation 'com.squareup.retrofit2:retrofit:2.9.0'
implementation 'com.squareup.okhttp3:okhttp:4.11.0'
implementation 'org.jetbrains.kotlinx:kotlinx-serialization-json:1.5.1'
// Простая авторизация
suspend fun login(email: String, password: String): String? {
val response = apiService.login(LoginRequest(email, password))
return if (response.isSuccessful) {
response.body()?.access_token
} else null
}
```
### 3⃣ НАСТРОЙТЕ WEBSOCKET (10 мин)
```kotlin
val token = getJwtToken()
val wsUrl = "ws://YOUR_SERVER:8002/api/v1/emergency/ws/current_user_id?token=$token"
val client = OkHttpClient()
val request = Request.Builder().url(wsUrl).build()
val webSocket = client.newWebSocket(request, object : WebSocketListener() {
override fun onMessage(webSocket: WebSocket, text: String) {
// Обработка сообщений от сервера
handleEmergencyMessage(text)
}
})
```
### 4⃣ ДОБАВЬТЕ API CALLS (5 мин)
```kotlin
// Создание экстренного вызова
suspend fun createAlert(latitude: Double, longitude: Double, description: String) {
val alert = CreateAlertRequest("medical", latitude, longitude, null, description)
val response = emergencyApi.createAlert(alert, "Bearer $jwtToken")
// Обработка ответа
}
// Получение списка вызовов
suspend fun getMyAlerts() {
val response = emergencyApi.getMyAlerts("Bearer $jwtToken")
// Обработка списка
}
```
---
## 🛠️ ОСНОВНЫЕ ENDPOINTS
### Аутентификация:
```
POST http://YOUR_SERVER:8000/api/v1/auth/login
Body: {"email": "user@example.com", "password": "password"}
Response: {"access_token": "JWT_TOKEN", "user": {...}}
```
### Emergency API (все с Bearer JWT токеном):
```
POST http://YOUR_SERVER:8002/api/v1/alert - Создать вызов
GET http://YOUR_SERVER:8002/api/v1/alerts/my - Мои вызовы
GET http://YOUR_SERVER:8002/api/v1/alerts/active - Активные вызовы
GET http://YOUR_SERVER:8002/api/v1/alerts/nearby?lat=55.7&lon=37.6&radius=5 - Ближайшие
POST http://YOUR_SERVER:8002/api/v1/alert/{id}/respond - Ответить на вызов
POST http://YOUR_SERVER:8002/api/v1/safety-check - Проверка безопасности
```
### WebSocket:
```
ws://YOUR_SERVER:8002/api/v1/emergency/ws/current_user_id?token=JWT_TOKEN
```
---
## 📱 МИНИМАЛЬНЫЙ КОД
### AuthManager.kt
```kotlin
class AuthManager {
private var jwtToken: String? = null
suspend fun login(email: String, password: String): Boolean {
val response = retrofit.create(AuthApi::class.java)
.login(LoginRequest(email, password))
return if (response.isSuccessful) {
jwtToken = response.body()?.access_token
true
} else false
}
fun getJwtToken(): String? = jwtToken
}
```
### EmergencyManager.kt
```kotlin
class EmergencyManager(private val authManager: AuthManager) {
private var webSocket: WebSocket? = null
fun connectWebSocket() {
val token = authManager.getJwtToken() ?: return
val wsUrl = "ws://YOUR_SERVER:8002/api/v1/emergency/ws/current_user_id?token=$token"
val request = Request.Builder().url(wsUrl).build()
webSocket = OkHttpClient().newWebSocket(request, object : WebSocketListener() {
override fun onMessage(webSocket: WebSocket, text: String) {
handleMessage(text)
}
})
}
suspend fun createAlert(lat: Double, lon: Double, description: String) {
val token = authManager.getJwtToken() ?: return
val alert = CreateAlertRequest("medical", lat, lon, null, description)
val response = emergencyApi.createAlert(alert, "Bearer $token")
// Handle response
}
private fun handleMessage(message: String) {
val data = Json.decodeFromString<WebSocketMessage>(message)
when (data.type) {
"emergency_alert" -> showEmergencyNotification(data)
"connection_established" -> onConnected()
}
}
}
```
---
## 🧪 ТЕСТИРОВАНИЕ
### Проверьте подключение:
```bash
# На сервере запустите тесты
./venv/bin/python test_final_security.py
```
### Тестовые данные:
- **Server**: `http://192.168.219.108:8000` (замените на ваш IP)
- **Email**: `shadow85@list.ru`
- **Password**: `R0sebud1985`
### Быстрый тест в коде:
```kotlin
// В onCreate или init
lifecycleScope.launch {
val success = authManager.login("shadow85@list.ru", "R0sebud1985")
if (success) {
emergencyManager.connectWebSocket()
Toast.makeText(this@MainActivity, "Connected!", Toast.LENGTH_SHORT).show()
}
}
```
---
## ⚠️ ВАЖНЫЕ МОМЕНТЫ
1. **Замените IP адрес** `YOUR_SERVER` на реальный IP сервера
2. **Удалите ВСЕ** `temp_token_` из кода
3. **Добавьте разрешения** в AndroidManifest.xml:
```xml
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
```
4. **Обработайте ошибки** сети и токенов
5. **Сохраняйте токен** в зашифрованном виде
---
## 📞 ПРОБЛЕМЫ?
1. **WebSocket не подключается** → Проверьте JWT токен и URL
2. **API возвращает 403** → Проверьте заголовок Authorization
3. **API возвращает 500** → Проверьте формат данных в запросе
4. **Нет уведомлений** → Проверьте WebSocket подключение
**Полная документация:** `MOBILE_APP_INTEGRATION_GUIDE.md`
**Готовые тесты сервера:** `test_final_security.py` - показывает, что все работает! ✅