14 KiB
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
{
"username": "testuser",
"email": "test@example.com",
"password": "password123",
"full_name": "Test User",
"phone": "+1234567890"
}
Вход в систему
POST /api/v1/auth/login
{
"username": "testuser", // или "email": "test@example.com"
"password": "password123"
}
Ответ:
{
"access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"token_type": "bearer"
}
👤 User Service API
Профиль пользователя
GET /api/v1/user/profile
Ответ: Полная информация о пользователе
PUT /api/v1/user/profile - Обновление профиля
Дашборд пользователя
GET /api/v1/user/dashboard
Ответ:
{
"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} - Удалить контакт
Схема контакта:
{
"name": "Мама",
"phone_number": "+1234567890",
"relationship": "mother",
"notes": "Основной контакт",
"is_active": true
}
🆘 Emergency Service API (Полная спецификация)
Типы данных
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)
{
"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
{
"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
{
"latitude": 55.7558,
"longitude": 37.6176,
"report_type": "harassment",
"description": "Описание происшествия",
"severity": 4,
"is_anonymous": false
}
6. Отметки безопасности
POST /api/v1/safety-check
{
"message": "Я в безопасности",
"location_latitude": 55.7558,
"location_longitude": 37.6176
}
7. Статистика
GET /api/v1/stats
{
"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
{
"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 - Добавить запись
Схема записи:
{
"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
{
"user_id": 123,
"title": "Экстренное оповещение",
"message": "Новое оповещение рядом с вами",
"type": "emergency_alert",
"data": {"alert_id": 456}
}
Push токены
POST /api/v1/push-token
{
"token": "fcm_or_apns_token",
"platform": "ios" // или "android"
}
🔗 Интеграция для мобильного приложения
Базовый HTTP клиент
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
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());
}
}
Примеры использования
// Инициализация
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 уведомления
- Зарегистрируйте push токен через
/api/v1/push-token - Обрабатывайте входящие уведомления для экстренных ситуаций
- Показывайте локальные уведомления при получении emergency_alert
Геолокация
- Запрашивайте разрешения на точное местоположение
- Обновляйте координаты через
/api/v1/location/update - Кэшируйте последнее известное местоположение
Оффлайн режим
- Кэшируйте экстренные контакты локально
- Сохраняйте черновики оповещений для отправки при восстановлении связи
- Показывайте статус подключения к сервису
UI/UX
- Красная кнопка SOS должна быть всегда доступна
- Быстрый доступ к созданию оповещения (виджет, ярлык)
- Показывайте статус отправленных оповещений
- Уведомления о новых откликах на оповещения
🧪 Тестирование
Используйте прилагаемый скрипт test_emergency_api.sh для полного тестирования API:
./test_emergency_api.sh
Скрипт проверит:
- Регистрацию и авторизацию
- Создание и управление оповещениями
- Отклики на оповещения
- Отчеты и отметки безопасности
- Статистику и аналитику