All checks were successful
continuous-integration/drone/push Build is passing
213 lines
6.0 KiB
Python
213 lines
6.0 KiB
Python
from datetime import datetime
|
||
from enum import Enum
|
||
from typing import List, Optional
|
||
from uuid import UUID
|
||
|
||
from pydantic import BaseModel, Field
|
||
|
||
|
||
class AlertType(str, Enum):
|
||
GENERAL = "general"
|
||
MEDICAL = "medical"
|
||
VIOLENCE = "violence"
|
||
HARASSMENT = "harassment"
|
||
UNSAFE_AREA = "unsafe_area"
|
||
ACCIDENT = "accident"
|
||
FIRE = "fire"
|
||
NATURAL_DISASTER = "natural_disaster"
|
||
|
||
|
||
class AlertStatus(str, Enum):
|
||
ACTIVE = "active"
|
||
RESOLVED = "resolved"
|
||
CANCELLED = "cancelled"
|
||
INVESTIGATING = "investigating"
|
||
|
||
|
||
class ResponseType(str, Enum):
|
||
HELP_ON_WAY = "help_on_way"
|
||
CONTACTED_AUTHORITIES = "contacted_authorities"
|
||
SAFE_NOW = "safe_now"
|
||
FALSE_ALARM = "false_alarm"
|
||
INVESTIGATING = "investigating"
|
||
RESOLVED = "resolved"
|
||
|
||
|
||
class EmergencyAlertCreate(BaseModel):
|
||
latitude: float = Field(..., ge=-90, le=90, description="Latitude coordinate")
|
||
longitude: float = Field(..., ge=-180, le=180, description="Longitude coordinate")
|
||
alert_type: AlertType = AlertType.GENERAL
|
||
message: Optional[str] = Field(None, max_length=500, description="Emergency description")
|
||
address: Optional[str] = Field(None, max_length=500, description="Location address")
|
||
contact_emergency_services: bool = Field(default=True, description="Contact emergency services automatically")
|
||
notify_emergency_contacts: bool = Field(default=True, description="Notify user's emergency contacts")
|
||
|
||
|
||
class EmergencyAlertUpdate(BaseModel):
|
||
message: Optional[str] = None
|
||
is_resolved: Optional[bool] = None
|
||
|
||
|
||
class EmergencyAlertResponse(BaseModel):
|
||
id: int
|
||
uuid: UUID
|
||
user_id: int
|
||
latitude: float
|
||
longitude: float
|
||
address: Optional[str] = None
|
||
alert_type: AlertType
|
||
message: Optional[str] = None
|
||
is_resolved: bool = False
|
||
resolved_at: Optional[datetime] = None
|
||
resolved_notes: Optional[str] = None
|
||
notified_users_count: int = 0
|
||
responded_users_count: int = 0
|
||
created_at: datetime
|
||
updated_at: Optional[datetime] = None
|
||
|
||
# User information
|
||
user_name: Optional[str] = None
|
||
user_phone: Optional[str] = None
|
||
|
||
class Config:
|
||
from_attributes = True
|
||
|
||
|
||
class EmergencyResponseCreate(BaseModel):
|
||
response_type: ResponseType
|
||
message: Optional[str] = Field(None, max_length=500, description="Response message")
|
||
eta_minutes: Optional[int] = Field(None, ge=0, le=240, description="Estimated time of arrival in minutes")
|
||
|
||
|
||
class EmergencyResponseResponse(BaseModel):
|
||
id: int
|
||
alert_id: int
|
||
responder_id: int
|
||
response_type: ResponseType
|
||
message: Optional[str] = None
|
||
eta_minutes: Optional[int] = None
|
||
created_at: datetime
|
||
|
||
# Responder information
|
||
responder_name: Optional[str] = None
|
||
responder_phone: Optional[str] = None
|
||
|
||
class Config:
|
||
from_attributes = True
|
||
|
||
|
||
class UserInfo(BaseModel):
|
||
"""Базовая информация о пользователе для событий"""
|
||
id: int
|
||
username: str
|
||
full_name: Optional[str] = None
|
||
phone: Optional[str] = None
|
||
|
||
class Config:
|
||
from_attributes = True
|
||
|
||
|
||
class EmergencyEventDetails(BaseModel):
|
||
"""Полная детальная информация о событии экстренной помощи"""
|
||
# Основная информация о событии
|
||
id: int
|
||
uuid: UUID
|
||
user_id: int
|
||
latitude: float
|
||
longitude: float
|
||
address: Optional[str] = None
|
||
alert_type: AlertType
|
||
message: Optional[str] = None
|
||
status: AlertStatus
|
||
created_at: datetime
|
||
updated_at: Optional[datetime] = None
|
||
resolved_at: Optional[datetime] = None
|
||
|
||
# Информация о пользователе, который создал событие
|
||
user: UserInfo
|
||
|
||
# Все ответы на это событие
|
||
responses: List[EmergencyResponseResponse] = []
|
||
|
||
# Статистика уведомлений
|
||
notifications_sent: int = 0
|
||
websocket_notifications_sent: int = 0
|
||
push_notifications_sent: int = 0
|
||
|
||
# Дополнительная информация
|
||
contact_emergency_services: bool = True
|
||
notify_emergency_contacts: bool = True
|
||
|
||
class Config:
|
||
from_attributes = True
|
||
|
||
|
||
# Report schemas
|
||
class EmergencyReportCreate(BaseModel):
|
||
latitude: float = Field(..., ge=-90, le=90)
|
||
longitude: float = Field(..., ge=-180, le=180)
|
||
report_type: str = Field(..., description="Type of emergency report")
|
||
description: str = Field(..., min_length=10, max_length=1000)
|
||
address: Optional[str] = Field(None, max_length=500)
|
||
is_anonymous: bool = Field(default=False)
|
||
severity: int = Field(default=3, ge=1, le=5, description="Severity level 1-5")
|
||
|
||
|
||
class EmergencyReportResponse(BaseModel):
|
||
id: int
|
||
uuid: UUID
|
||
user_id: Optional[int] = None
|
||
latitude: float
|
||
longitude: float
|
||
address: Optional[str] = None
|
||
report_type: str
|
||
description: str
|
||
is_anonymous: bool
|
||
severity: int
|
||
status: str = "pending"
|
||
created_at: datetime
|
||
|
||
class Config:
|
||
from_attributes = True
|
||
|
||
|
||
# Statistics schemas
|
||
class EmergencyStatistics(BaseModel):
|
||
total_alerts: int = 0
|
||
active_alerts: int = 0
|
||
resolved_alerts: int = 0
|
||
total_responders: int = 0
|
||
avg_response_time_minutes: float = 0
|
||
|
||
|
||
# Location-based schemas
|
||
class NearbyAlertResponse(BaseModel):
|
||
id: int
|
||
alert_type: str
|
||
latitude: float
|
||
longitude: float
|
||
address: Optional[str] = None
|
||
distance_km: float
|
||
created_at: datetime
|
||
responded_users_count: int = 0
|
||
|
||
|
||
# Safety check schemas
|
||
class SafetyCheckCreate(BaseModel):
|
||
message: Optional[str] = Field(None, max_length=200)
|
||
location_latitude: Optional[float] = Field(None, ge=-90, le=90)
|
||
location_longitude: Optional[float] = Field(None, ge=-180, le=180)
|
||
|
||
|
||
class SafetyCheckResponse(BaseModel):
|
||
id: int
|
||
uuid: UUID
|
||
user_id: int
|
||
message: Optional[str] = None
|
||
location_latitude: Optional[float] = None
|
||
location_longitude: Optional[float] = None
|
||
created_at: datetime
|
||
|
||
class Config:
|
||
from_attributes = True
|