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

617 lines
22 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.

# Полные схемы данных для мобильного приложения Women's Safety App
## 📋 Содержание
1. [Схемы авторизации](#схемы-авторизации)
2. [Схемы пользователей](#схемы-пользователей)
3. [Схемы экстренных ситуаций](#схемы-экстренных-ситуаций)
4. [Схемы местоположения](#схемы-местоположения)
5. [Схемы уведомлений](#схемы-уведомлений)
6. [Схемы календаря](#схемы-календаря)
7. [TypeScript интерфейсы](#typescript-интерфейсы)
---
## 🔐 Схемы авторизации
### UserRegister
```json
{
"username": "string", // Имя пользователя (уникальное)
"email": "string", // Email (уникальный)
"password": "string", // Пароль (мин 8 символов)
"full_name": "string?", // Полное имя
"phone": "string?", // Номер телефона
"date_of_birth": "date?", // Дата рождения (YYYY-MM-DD)
"bio": "string?" // Биография (макс 500 символов)
}
```
### UserLogin
```json
{
"username": "string?", // Имя пользователя ИЛИ
"email": "string?", // Email (один из двух обязателен)
"password": "string" // Пароль
}
```
### TokenResponse
```json
{
"access_token": "string", // JWT токен
"token_type": "bearer" // Тип токена
}
```
---
## 👤 Схемы пользователей
### UserProfile (полная информация)
```json
{
"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
```json
{
"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
```json
{
"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 (полная схема)
```json
{
"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 (отклик на оповещение)
```json
{
"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 (отчет о происшествии)
```json
{
"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 (отметка безопасности)
```json
{
"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
```json
{
"total_alerts": 150, // int, общее количество оповещений
"active_alerts": 12, // int, активные оповещения
"resolved_alerts": 138, // int, решенные оповещения
"total_responders": 89, // int, всего откликнувшихся
"avg_response_time_minutes": 8.5 // float, среднее время отклика
}
```
### NearbyAlert (ближайшие оповещения)
```json
{
"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
```json
{
"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
```json
{
"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
```json
{
"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
```json
{
"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
```json
{
"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
```json
{
"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
```json
{
"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
```json
{
"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 интерфейсы
```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
### Рекомендации по обработке ошибок
```typescript
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.