Files
chat/docs/MOBILE_API_SPECS.md
Andrew K. Choi 7c22664daf
All checks were successful
continuous-integration/drone/push Build is passing
sdf
2025-09-26 12:22:14 +09:00

495 lines
14 KiB
Markdown
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.

# API Спецификации для мобильного приложения Women's Safety App
## Обзор системы
Микросервисная архитектура с 6 сервисами:
- **API Gateway** (порт 8000) - точка входа
- **User Service** (порт 8001) - управление пользователями
- **Emergency Service** (порт 8002) - экстренные ситуации
- **Location Service** (порт 8003) - геолокация
- **Calendar Service** (порт 8004) - календарь здоровья
- **Notification Service** (порт 8005) - уведомления
**Базовый URL:** `http://192.168.0.103:8000` (API Gateway)
**Прямые сервисы:** `http://192.168.0.103:800X` (где X - номер сервиса)
---
## 🔐 Система авторизации
### Регистрация пользователя
**POST** `/api/v1/auth/register`
```json
{
"username": "testuser",
"email": "test@example.com",
"password": "password123",
"full_name": "Test User",
"phone": "+1234567890"
}
```
### Вход в систему
**POST** `/api/v1/auth/login`
```json
{
"username": "testuser", // или "email": "test@example.com"
"password": "password123"
}
```
**Ответ:**
```json
{
"access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"token_type": "bearer"
}
```
---
## 👤 User Service API
### Профиль пользователя
**GET** `/api/v1/user/profile`
**Ответ:** Полная информация о пользователе
**PUT** `/api/v1/user/profile` - Обновление профиля
### Дашборд пользователя
**GET** `/api/v1/user/dashboard`
**Ответ:**
```json
{
"user_info": {...},
"recent_alerts": [...],
"emergency_contacts": [...],
"safety_stats": {...}
}
```
### Экстренные контакты
**GET** `/api/v1/user/emergency-contacts` - Список контактов
**POST** `/api/v1/user/emergency-contacts` - Добавить контакт
**PUT** `/api/v1/user/emergency-contacts/{id}` - Обновить контакт
**DELETE** `/api/v1/user/emergency-contacts/{id}` - Удалить контакт
**Схема контакта:**
```json
{
"name": "Мама",
"phone_number": "+1234567890",
"relationship": "mother",
"notes": "Основной контакт",
"is_active": true
}
```
---
## 🆘 Emergency Service API (Полная спецификация)
### Типы данных
```typescript
enum AlertType {
GENERAL = "general",
MEDICAL = "medical",
VIOLENCE = "violence",
HARASSMENT = "harassment",
UNSAFE_AREA = "unsafe_area",
ACCIDENT = "accident",
FIRE = "fire",
NATURAL_DISASTER = "natural_disaster"
}
enum AlertStatus {
ACTIVE = "active",
RESOLVED = "resolved",
CANCELLED = "cancelled",
INVESTIGATING = "investigating"
}
enum ResponseType {
HELP_ON_WAY = "help_on_way",
CONTACTED_AUTHORITIES = "contacted_authorities",
SAFE_NOW = "safe_now",
FALSE_ALARM = "false_alarm"
}
```
### Основные endpoints
#### 1. Создание экстренного оповещения
**POST** `/api/v1/alert` (через Emergency Service напрямую: порт 8002)
```json
{
"latitude": 55.7558,
"longitude": 37.6176,
"alert_type": "general",
"message": "Нужна помощь",
"address": "Красная площадь, Москва",
"contact_emergency_services": true,
"notify_emergency_contacts": true
}
```
#### 2. Получение оповещений
- **GET** `/api/v1/alerts/my` - Мои оповещения
- **GET** `/api/v1/alerts/active` - Активные оповещения
- **GET** `/api/v1/alerts/nearby?latitude=55.7558&longitude=37.6176&radius_km=10` - Ближайшие
#### 3. Отклик на оповещение
**POST** `/api/v1/alert/{alert_id}/respond`
```json
{
"response_type": "help_on_way",
"message": "Еду к вам!",
"eta_minutes": 15,
"location_sharing": true
}
```
#### 4. Управление оповещением
- **PUT** `/api/v1/alert/{alert_id}` - Обновить оповещение
- **PUT** `/api/v1/alert/{alert_id}/resolve` - Пометить как решенное
- **GET** `/api/v1/alert/{alert_id}/responses` - Получить отклики
#### 5. Отчеты о происшествиях
**POST** `/api/v1/report`
```json
{
"latitude": 55.7558,
"longitude": 37.6176,
"report_type": "harassment",
"description": "Описание происшествия",
"severity": 4,
"is_anonymous": false
}
```
#### 6. Отметки безопасности
**POST** `/api/v1/safety-check`
```json
{
"message": "Я в безопасности",
"location_latitude": 55.7558,
"location_longitude": 37.6176
}
```
#### 7. Статистика
**GET** `/api/v1/stats`
```json
{
"total_alerts": 150,
"active_alerts": 12,
"resolved_alerts": 138,
"total_responders": 89,
"avg_response_time_minutes": 8.5
}
```
---
## 📍 Location Service API
### Обновление местоположения
**POST** `/api/v1/location/update`
```json
{
"latitude": 55.7558,
"longitude": 37.6176,
"accuracy": 10.0,
"altitude": 150.0
}
```
### Поиск пользователей рядом
**GET** `/api/v1/nearby-users?latitude=55.7558&longitude=37.6176&radius_km=1.0`
### Геокодирование
**GET** `/api/v1/geocode/reverse?latitude=55.7558&longitude=37.6176`
**GET** `/api/v1/geocode/forward?address=Красная площадь, Москва`
---
## 📅 Calendar Service API
### Календарь здоровья
**GET** `/api/v1/calendar/entries` - Записи календаря
**POST** `/api/v1/calendar/entries` - Добавить запись
**Схема записи:**
```json
{
"date": "2024-01-15",
"entry_type": "period_start", // period_start, period_end, mood, symptoms
"notes": "Заметки",
"mood_score": 4, // 1-5
"symptoms": ["headache", "fatigue"]
}
```
### Аналитика
**GET** `/api/v1/calendar/analytics` - Аналитика цикла
---
## 🔔 Notification Service API
### Отправка уведомления
**POST** `/api/v1/send-notification`
```json
{
"user_id": 123,
"title": "Экстренное оповещение",
"message": "Новое оповещение рядом с вами",
"type": "emergency_alert",
"data": {"alert_id": 456}
}
```
### Push токены
**POST** `/api/v1/push-token`
```json
{
"token": "fcm_or_apns_token",
"platform": "ios" // или "android"
}
```
---
## 🔗 Интеграция для мобильного приложения
### Базовый HTTP клиент
```javascript
class WomenSafetyAPI {
constructor(baseUrl = 'http://192.168.0.103:8000') {
this.baseUrl = baseUrl;
this.token = null;
}
setToken(token) {
this.token = token;
}
async request(method, endpoint, data = null) {
const config = {
method,
headers: {
'Content-Type': 'application/json',
}
};
if (this.token) {
config.headers.Authorization = `Bearer ${this.token}`;
}
if (data && (method === 'POST' || method === 'PUT')) {
config.body = JSON.stringify(data);
}
const url = `${this.baseUrl}${endpoint}`;
const response = await fetch(url, config);
if (!response.ok) {
const error = await response.json();
throw new Error(error.detail || 'API Error');
}
return await response.json();
}
}
```
### Основные методы API
```javascript
class EmergencyAPI extends WomenSafetyAPI {
// Авторизация
async login(username, password) {
const response = await this.request('POST', '/api/v1/auth/login', {
username,
password
});
this.setToken(response.access_token);
return response;
}
async register(userData) {
return await this.request('POST', '/api/v1/auth/register', userData);
}
// Экстренные ситуации (через порт 8002)
async createAlert(alertData) {
const emergencyUrl = this.baseUrl.replace('8000', '8002');
return await fetch(`${emergencyUrl}/api/v1/alert`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${this.token}`
},
body: JSON.stringify(alertData)
}).then(r => r.json());
}
async getNearbyAlerts(latitude, longitude, radiusKm = 10) {
const emergencyUrl = this.baseUrl.replace('8000', '8002');
const params = new URLSearchParams({
latitude: latitude.toString(),
longitude: longitude.toString(),
radius_km: radiusKm.toString()
});
return await fetch(`${emergencyUrl}/api/v1/alerts/nearby?${params}`, {
headers: { 'Authorization': `Bearer ${this.token}` }
}).then(r => r.json());
}
async respondToAlert(alertId, responseData) {
const emergencyUrl = this.baseUrl.replace('8000', '8002');
return await fetch(`${emergencyUrl}/api/v1/alert/${alertId}/respond`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${this.token}`
},
body: JSON.stringify(responseData)
}).then(r => r.json());
}
// Профиль пользователя
async getProfile() {
return await this.request('GET', '/api/v1/user/profile');
}
async getDashboard() {
return await this.request('GET', '/api/v1/user/dashboard');
}
// Экстренные контакты
async getEmergencyContacts() {
return await this.request('GET', '/api/v1/user/emergency-contacts');
}
async addEmergencyContact(contactData) {
return await this.request('POST', '/api/v1/user/emergency-contacts', contactData);
}
// Местоположение
async updateLocation(locationData) {
return await this.request('POST', '/api/v1/location/update', locationData);
}
// Отметка безопасности
async createSafetyCheck(safetyData) {
const emergencyUrl = this.baseUrl.replace('8000', '8002');
return await fetch(`${emergencyUrl}/api/v1/safety-check`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${this.token}`
},
body: JSON.stringify(safetyData)
}).then(r => r.json());
}
}
```
### Примеры использования
```javascript
// Инициализация
const api = new EmergencyAPI('http://192.168.0.103:8000');
// Авторизация
await api.login('testuser', 'password123');
// Создание экстренного оповещения
const alert = await api.createAlert({
latitude: 55.7558,
longitude: 37.6176,
alert_type: 'general',
message: 'Нужна помощь!',
address: 'Красная площадь, Москва'
});
// Поиск ближайших оповещений
const nearbyAlerts = await api.getNearbyAlerts(55.7558, 37.6176, 5);
// Отклик на оповещение
const response = await api.respondToAlert(alert.id, {
response_type: 'help_on_way',
message: 'Еду к вам!',
eta_minutes: 10
});
// Получение профиля
const profile = await api.getProfile();
// Отметка безопасности
const safetyCheck = await api.createSafetyCheck({
message: 'Добрался домой безопасно',
location_latitude: 55.7600,
location_longitude: 37.6100
});
```
---
## 🛡️ Безопасность и аутентификация
### JWT токены
- Время жизни: настраивается в конфигурации
- Формат: `Bearer {token}`
- Включают: user_id, email, exp (время истечения)
### Заголовки запросов
```
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
Content-Type: application/json
```
### Коды ошибок
- `401 Unauthorized` - Неверные учетные данные
- `403 Forbidden` - Недостаточно прав
- `422 Unprocessable Entity` - Ошибки валидации
- `500 Internal Server Error` - Внутренняя ошибка
---
## 📱 Рекомендации для мобильной разработки
### Push уведомления
1. Зарегистрируйте push токен через `/api/v1/push-token`
2. Обрабатывайте входящие уведомления для экстренных ситуаций
3. Показывайте локальные уведомления при получении emergency_alert
### Геолокация
1. Запрашивайте разрешения на точное местоположение
2. Обновляйте координаты через `/api/v1/location/update`
3. Кэшируйте последнее известное местоположение
### Оффлайн режим
1. Кэшируйте экстренные контакты локально
2. Сохраняйте черновики оповещений для отправки при восстановлении связи
3. Показывайте статус подключения к сервису
### UI/UX
1. Красная кнопка SOS должна быть всегда доступна
2. Быстрый доступ к созданию оповещения (виджет, ярлык)
3. Показывайте статус отправленных оповещений
4. Уведомления о новых откликах на оповещения
---
## 🧪 Тестирование
Используйте прилагаемый скрипт `test_emergency_api.sh` для полного тестирования API:
```bash
./test_emergency_api.sh
```
Скрипт проверит:
- Регистрацию и авторизацию
- Создание и управление оповещениями
- Отклики на оповещения
- Отчеты и отметки безопасности
- Статистику и аналитику