# 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 ``` Скрипт проверит: - Регистрацию и авторизацию - Создание и управление оповещениями - Отклики на оповещения - Отчеты и отметки безопасности - Статистику и аналитику