Files
chat/docs/DATA_SCHEMAS.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

22 KiB
Raw Permalink Blame History

Полные схемы данных для мобильного приложения Women's Safety App

📋 Содержание

  1. Схемы авторизации
  2. Схемы пользователей
  3. Схемы экстренных ситуаций
  4. Схемы местоположения
  5. Схемы уведомлений
  6. Схемы календаря
  7. TypeScript интерфейсы

🔐 Схемы авторизации

UserRegister

{
  "username": "string",              // Имя пользователя (уникальное)
  "email": "string",                 // Email (уникальный)
  "password": "string",              // Пароль (мин 8 символов)
  "full_name": "string?",            // Полное имя
  "phone": "string?",                // Номер телефона
  "date_of_birth": "date?",          // Дата рождения (YYYY-MM-DD)
  "bio": "string?"                   // Биография (макс 500 символов)
}

UserLogin

{
  "username": "string?",             // Имя пользователя ИЛИ
  "email": "string?",                // Email (один из двух обязателен)
  "password": "string"               // Пароль
}

TokenResponse

{
  "access_token": "string",          // JWT токен
  "token_type": "bearer"             // Тип токена
}

👤 Схемы пользователей

UserProfile (полная информация)

{
  "id": 123,                         // int, ID пользователя
  "uuid": "8ed4fb51-8a90-4b22...",   // string, UUID пользователя
  "username": "testuser",            // string, имя пользователя
  "email": "test@example.com",       // string, email
  "phone": "+1234567890",            // string?, телефон
  "first_name": "John",              // string?, имя
  "last_name": "Doe",                // string?, фамилия
  "date_of_birth": "1990-01-01",     // date?, дата рождения
  "bio": "Краткая биография",        // string?, биография
  "avatar_url": "https://...",       // string?, URL аватара
  "location_sharing_enabled": true,   // bool, разрешение на геолокацию
  "emergency_notifications_enabled": true, // bool, экстренные уведомления
  "push_notifications_enabled": true, // bool, push уведомления
  "email_verified": false,           // bool, email подтвержден
  "phone_verified": true,            // bool, телефон подтвержден
  "is_active": true,                 // bool, активен ли аккаунт
  "created_at": "2024-01-01T10:00:00Z", // datetime, дата регистрации
  "updated_at": "2024-01-15T10:00:00Z"  // datetime, последнее обновление
}

UserDashboard

{
  "user_info": {                     // Краткая информация о пользователе
    "id": 123,
    "username": "testuser",
    "email": "test@example.com",
    "first_name": "John",
    "last_name": "Doe"
  },
  "recent_alerts": [                 // Последние оповещения (макс 5)
    {
      "id": 456,
      "alert_type": "general",
      "message": "Нужна помощь",
      "created_at": "2024-01-15T09:30:00Z",
      "is_resolved": false,
      "responded_users_count": 2
    }
  ],
  "emergency_contacts": [            // Экстренные контакты
    {
      "id": 789,
      "name": "Мама",
      "phone_number": "+1234567890",
      "relationship": "mother"
    }
  ],
  "safety_stats": {                  // Статистика безопасности
    "total_alerts_created": 5,
    "total_responses_given": 12,
    "safety_checks_count": 45,
    "last_safety_check": "2024-01-15T08:00:00Z"
  }
}

EmergencyContact

{
  "id": 789,                         // int, ID контакта
  "uuid": "8ed4fb51-8a90-4b22...",   // string, UUID контакта
  "user_id": 123,                    // int, ID владельца
  "name": "Мама",                    // string, имя контакта
  "phone_number": "+1234567890",     // string, телефон
  "relationship": "mother",          // string?, отношение (mother, father, spouse, friend, etc.)
  "notes": "Основной контакт",       // string?, заметки
  "is_active": true,                 // bool, активен ли контакт
  "created_at": "2024-01-01T10:00:00Z", // datetime, дата создания
  "updated_at": "2024-01-15T10:00:00Z"  // datetime, последнее обновление
}

🆘 Схемы экстренных ситуаций

EmergencyAlert (полная схема)

{
  "id": 123,                         // int, ID оповещения
  "uuid": "8ed4fb51-8a90-4b22...",   // string, UUID оповещения
  "user_id": 26,                     // int, ID создателя
  "latitude": 55.7558,               // float, широта (-90 до 90)
  "longitude": 37.6176,              // float, долгота (-180 до 180)
  "address": "Красная площадь, Москва", // string?, адрес
  "alert_type": "general",           // AlertType, тип оповещения
  "status": "active",                // AlertStatus, текущий статус
  "message": "Нужна помощь",         // string?, описание ситуации
  "is_resolved": false,              // bool, решено ли
  "resolved_at": null,               // datetime?, время решения
  "resolved_by": null,               // int?, кем решено
  "resolved_notes": null,            // string?, заметки о решении
  "contact_emergency_services": true, // bool, связаться со службами
  "notify_emergency_contacts": true, // bool, уведомить контакты
  "notified_users_count": 5,         // int, количество уведомленных
  "responded_users_count": 2,        // int, количество откликнувшихся
  "created_at": "2024-01-15T10:30:00Z", // datetime, время создания
  "updated_at": "2024-01-15T10:35:00Z"  // datetime, последнее обновление
}

EmergencyResponse (отклик на оповещение)

{
  "id": 456,                         // int, ID отклика
  "uuid": "8ed4fb51-8a90-4b22...",   // string, UUID отклика
  "alert_id": 123,                   // int, ID оповещения
  "user_id": 27,                     // int, ID откликнувшегося
  "response_type": "help_on_way",    // ResponseType, тип отклика
  "message": "Еду к вам!",           // string?, сообщение
  "eta_minutes": 15,                 // int?, время прибытия в минутах
  "location_sharing": true,          // bool, делиться местоположением
  "created_at": "2024-01-15T10:32:00Z" // datetime, время создания
}

EmergencyReport (отчет о происшествии)

{
  "id": 789,                         // int, ID отчета
  "uuid": "8ed4fb51-8a90-4b22...",   // string, UUID отчета
  "user_id": 26,                     // int?, ID автора (null для анонимных)
  "latitude": 55.7558,               // float, широта
  "longitude": 37.6176,              // float, долгота
  "address": "Тверская улица",       // string?, адрес
  "report_type": "harassment",       // string, тип происшествия
  "description": "Подробное описание...", // string, описание (10-1000 символов)
  "is_anonymous": false,             // bool, анонимный отчет
  "severity": 4,                     // int, серьезность (1-5)
  "status": "pending",               // string, статус (pending/investigating/resolved)
  "created_at": "2024-01-15T10:45:00Z"  // datetime, время создания
}

SafetyCheck (отметка безопасности)

{
  "id": 101,                         // int, ID отметки
  "uuid": "8ed4fb51-8a90-4b22...",   // string, UUID отметки
  "user_id": 26,                     // int, ID пользователя
  "message": "Добрался домой безопасно", // string?, сообщение
  "location_latitude": 55.7600,      // float?, широта
  "location_longitude": 37.6100,     // float?, долгота
  "created_at": "2024-01-15T22:00:00Z"  // datetime, время создания
}

EmergencyStatistics

{
  "total_alerts": 150,               // int, общее количество оповещений
  "active_alerts": 12,               // int, активные оповещения
  "resolved_alerts": 138,            // int, решенные оповещения
  "total_responders": 89,            // int, всего откликнувшихся
  "avg_response_time_minutes": 8.5   // float, среднее время отклика
}

NearbyAlert (ближайшие оповещения)

{
  "id": 123,                         // int, ID оповещения
  "alert_type": "medical",           // string, тип оповещения
  "latitude": 55.7558,               // float, широта
  "longitude": 37.6176,              // float, долгота
  "address": "Больница №1",          // string?, адрес
  "distance_km": 2.5,                // float, расстояние в километрах
  "created_at": "2024-01-15T09:15:00Z", // datetime, время создания
  "responded_users_count": 3         // int, количество откликов
}

📍 Схемы местоположения

LocationUpdate

{
  "latitude": 55.7558,               // float, широта (-90 до 90)
  "longitude": 37.6176,              // float, долгота (-180 до 180)
  "accuracy": 10.0,                  // float?, точность в метрах
  "altitude": 150.0,                 // float?, высота в метрах
  "speed": 0.0,                      // float?, скорость м/с
  "heading": 90.0,                   // float?, направление (0-360 градусов)
  "timestamp": "2024-01-15T10:30:00Z" // datetime?, время получения координат
}

NearbyUser

{
  "user_id": 27,                     // int, ID пользователя
  "distance_meters": 500.0,          // float, расстояние в метрах
  "latitude": 55.7568,               // float, широта (может быть приблизительной)
  "longitude": 37.6186,              // float, долгота (может быть приблизительной)
  "last_seen": "2024-01-15T10:25:00Z", // datetime, последнее обновление местоположения
  "is_available": true               // bool, готов ли помочь
}

GeocodeResult

{
  "address": "Красная площадь, 1, Москва, Россия", // string, полный адрес
  "street": "Красная площадь",       // string?, улица
  "house_number": "1",               // string?, номер дома
  "city": "Москва",                  // string?, город
  "state": "Москва",                 // string?, регион/область
  "country": "Россия",               // string?, страна
  "postal_code": "109012",           // string?, почтовый индекс
  "latitude": 55.7558,               // float, широта
  "longitude": 37.6176               // float, долгота
}

🔔 Схемы уведомлений

NotificationCreate

{
  "user_id": 123,                    // int, ID получателя
  "title": "Экстренное оповещение",  // string, заголовок
  "message": "Новое оповещение рядом с вами", // string, текст сообщения
  "type": "emergency_alert",         // string, тип уведомления
  "data": {                          // object?, дополнительные данные
    "alert_id": 456,
    "latitude": 55.7558,
    "longitude": 37.6176
  },
  "priority": "high",                // string?, приоритет (low/normal/high/urgent)
  "schedule_at": null                // datetime?, время отправки (null = сейчас)
}

PushTokenRegistration

{
  "token": "fcm_or_apns_token_here", // string, токен устройства
  "platform": "ios",                // string, платформа (ios/android)
  "app_version": "1.0.0",            // string?, версия приложения
  "device_info": {                   // object?, информация об устройстве
    "model": "iPhone 14",
    "os_version": "17.0"
  }
}

NotificationHistory

{
  "id": 789,                         // int, ID уведомления
  "user_id": 123,                    // int, ID получателя
  "title": "Экстренное оповещение",  // string, заголовок
  "message": "Текст уведомления",    // string, сообщение
  "type": "emergency_alert",         // string, тип
  "status": "delivered",             // string, статус (sent/delivered/read/failed)
  "sent_at": "2024-01-15T10:30:00Z", // datetime, время отправки
  "delivered_at": "2024-01-15T10:30:05Z", // datetime?, время доставки
  "read_at": null                    // datetime?, время прочтения
}

📅 Схемы календаря

CalendarEntry

{
  "id": 456,                         // int, ID записи
  "user_id": 123,                    // int, ID пользователя
  "date": "2024-01-15",              // date, дата записи (YYYY-MM-DD)
  "entry_type": "period_start",      // string, тип записи
  "notes": "Болезненные ощущения",   // string?, заметки
  "mood_score": 3,                   // int?, настроение (1-5)
  "energy_level": 4,                 // int?, уровень энергии (1-5)
  "symptoms": [                      // array?, симптомы
    "headache",
    "fatigue",
    "cramps"
  ],
  "flow_intensity": "medium",        // string?, интенсивность (light/medium/heavy)
  "temperature": 36.6,               // float?, температура тела
  "weight": 65.5,                    // float?, вес
  "created_at": "2024-01-15T08:00:00Z", // datetime, время создания
  "updated_at": "2024-01-15T08:05:00Z"  // datetime, последнее обновление
}

CalendarAnalytics

{
  "cycle_length": 28,                // int?, средняя длина цикла
  "period_length": 5,                // int?, средняя длина месячных
  "next_period_prediction": "2024-02-10", // date?, прогноз следующих месячных
  "fertility_window": {              // object?, окно фертильности
    "start": "2024-01-20",
    "end": "2024-01-25"
  },
  "mood_trends": {                   // object?, тренды настроения
    "average_score": 3.5,
    "lowest_day": 2,
    "highest_day": 12
  },
  "symptoms_frequency": {            // object?, частота симптомов
    "headache": 0.3,
    "cramps": 0.8,
    "fatigue": 0.6
  }
}

📱 TypeScript интерфейсы

// Перечисления
export enum AlertType {
  GENERAL = 'general',
  MEDICAL = 'medical',
  VIOLENCE = 'violence',
  HARASSMENT = 'harassment',
  UNSAFE_AREA = 'unsafe_area',
  ACCIDENT = 'accident',
  FIRE = 'fire',
  NATURAL_DISASTER = 'natural_disaster'
}

export enum AlertStatus {
  ACTIVE = 'active',
  RESOLVED = 'resolved',
  CANCELLED = 'cancelled',
  INVESTIGATING = 'investigating'
}

export enum ResponseType {
  HELP_ON_WAY = 'help_on_way',
  CONTACTED_AUTHORITIES = 'contacted_authorities',
  SAFE_NOW = 'safe_now',
  FALSE_ALARM = 'false_alarm',
  INVESTIGATING = 'investigating',
  RESOLVED = 'resolved'
}

// Интерфейсы авторизации
export interface UserRegister {
  username: string;
  email: string;
  password: string;
  full_name?: string;
  phone?: string;
  date_of_birth?: string;
  bio?: string;
}

export interface UserLogin {
  username?: string;
  email?: string;
  password: string;
}

export interface TokenResponse {
  access_token: string;
  token_type: string;
}

// Интерфейсы пользователя
export interface UserProfile {
  id: number;
  uuid: string;
  username: string;
  email: string;
  phone?: string;
  first_name?: string;
  last_name?: string;
  date_of_birth?: string;
  bio?: string;
  avatar_url?: string;
  location_sharing_enabled: boolean;
  emergency_notifications_enabled: boolean;
  push_notifications_enabled: boolean;
  email_verified: boolean;
  phone_verified: boolean;
  is_active: boolean;
  created_at: string;
  updated_at?: string;
}

export interface EmergencyContact {
  id: number;
  uuid: string;
  user_id: number;
  name: string;
  phone_number: string;
  relationship?: string;
  notes?: string;
  is_active: boolean;
  created_at: string;
  updated_at?: string;
}

// Интерфейсы экстренных ситуаций
export interface EmergencyAlertCreate {
  latitude: number;
  longitude: number;
  alert_type: AlertType;
  message?: string;
  address?: string;
  contact_emergency_services?: boolean;
  notify_emergency_contacts?: boolean;
}

export interface EmergencyAlert {
  id: number;
  uuid: string;
  user_id: number;
  latitude: number;
  longitude: number;
  address?: string;
  alert_type: AlertType;
  status: AlertStatus;
  message?: string;
  is_resolved: boolean;
  resolved_at?: string;
  resolved_by?: number;
  resolved_notes?: string;
  contact_emergency_services: boolean;
  notify_emergency_contacts: boolean;
  notified_users_count: number;
  responded_users_count: number;
  created_at: string;
  updated_at?: string;
}

export interface EmergencyResponseCreate {
  response_type: ResponseType;
  message?: string;
  eta_minutes?: number;
  location_sharing?: boolean;
}

export interface EmergencyResponse {
  id: number;
  uuid: string;
  alert_id: number;
  user_id: number;
  response_type: ResponseType;
  message?: string;
  eta_minutes?: number;
  location_sharing: boolean;
  created_at: string;
}

export interface EmergencyStatistics {
  total_alerts: number;
  active_alerts: number;
  resolved_alerts: number;
  total_responders: number;
  avg_response_time_minutes: number;
}

export interface NearbyAlert {
  id: number;
  alert_type: string;
  latitude: number;
  longitude: number;
  address?: string;
  distance_km: number;
  created_at: string;
  responded_users_count: number;
}

// Интерфейсы местоположения
export interface LocationUpdate {
  latitude: number;
  longitude: number;
  accuracy?: number;
  altitude?: number;
  speed?: number;
  heading?: number;
  timestamp?: string;
}

export interface NearbyUser {
  user_id: number;
  distance_meters: number;
  latitude: number;
  longitude: number;
  last_seen: string;
  is_available: boolean;
}

// Интерфейсы уведомлений
export interface PushTokenRegistration {
  token: string;
  platform: 'ios' | 'android';
  app_version?: string;
  device_info?: {
    model?: string;
    os_version?: string;
  };
}

// API клиент
export interface APIClient {
  setToken(token: string): void;
  login(username: string, password: string): Promise<TokenResponse>;
  register(userData: UserRegister): Promise<UserProfile>;
  getProfile(): Promise<UserProfile>;
  createAlert(alertData: EmergencyAlertCreate): Promise<EmergencyAlert>;
  getNearbyAlerts(lat: number, lng: number, radius?: number): Promise<NearbyAlert[]>;
  respondToAlert(alertId: number, response: EmergencyResponseCreate): Promise<EmergencyResponse>;
  updateLocation(location: LocationUpdate): Promise<void>;
  createSafetyCheck(data: { message?: string; location_latitude?: number; location_longitude?: number }): Promise<any>;
}

📋 Валидация данных

Ограничения полей

  • Координаты: latitude (-90 до 90), longitude (-180 до 180)
  • Пароль: минимум 8 символов, максимум 70 (для совместимости с bcrypt)
  • Email: валидный формат email
  • Телефон: рекомендуется международный формат (+1234567890)
  • Сообщения: максимум 500 символов для alert message, 200 для safety check
  • Описания: 10-1000 символов для emergency reports

Обязательные поля

  • При регистрации: username, email, password
  • При создании оповещения: latitude, longitude, alert_type
  • При отклике: response_type
  • При обновлении местоположения: latitude, longitude

Рекомендации по обработке ошибок

interface APIError {
  detail: string;
  status_code: number;
  field_errors?: {
    [field: string]: string[];
  };
}

// Обработка ошибок валидации
try {
  await api.createAlert(alertData);
} catch (error) {
  if (error.status_code === 422) {
    // Показать ошибки валидации для каждого поля
    Object.entries(error.field_errors || {}).forEach(([field, errors]) => {
      console.error(`${field}: ${errors.join(', ')}`);
    });
  }
}

Эти схемы данных обеспечивают полную интеграцию мобильного приложения с Women's Safety App API.