66 lines
2.1 KiB
Python
66 lines
2.1 KiB
Python
from pydantic import BaseModel, Field
|
||
from typing import Optional, Any, Dict, List, Generic, TypeVar
|
||
from datetime import datetime
|
||
from app.schemas.common import BaseSchema, PaginatedResponse
|
||
|
||
T = TypeVar('T')
|
||
|
||
class HealthResponse(BaseSchema):
|
||
"""Health check ответ"""
|
||
status: str = "healthy"
|
||
timestamp: datetime = Field(default_factory=datetime.utcnow)
|
||
version: str = "1.0.0"
|
||
database: str
|
||
|
||
class ValidationErrorDetail(BaseSchema):
|
||
"""Детали ошибки валидации"""
|
||
field: str
|
||
message: str
|
||
value: Optional[Any] = None
|
||
|
||
class ValidationErrorResponse(BaseSchema):
|
||
"""Ответ с ошибками валидации"""
|
||
error: str = "Validation Error"
|
||
details: List[ValidationErrorDetail] = Field(default_factory=list)
|
||
status_code: int = 422
|
||
|
||
class ExportResponse(BaseSchema):
|
||
"""Ответ на экспорт данных"""
|
||
download_url: str
|
||
file_name: str
|
||
file_size: int
|
||
expires_at: datetime
|
||
format: str # csv, xlsx, json
|
||
|
||
class AnalyticsFieldStats(BaseSchema):
|
||
"""Статистика по полю формы"""
|
||
field_name: str
|
||
field_label: str
|
||
field_type: str
|
||
total_responses: int
|
||
filled_count: int
|
||
empty_count: int
|
||
fill_rate: float # процент заполнения
|
||
unique_values: int
|
||
distribution: Dict[str, int] # значение -> количество
|
||
|
||
class AnalyticsDailyStats(BaseSchema):
|
||
"""Ежедневная статистика"""
|
||
date: str
|
||
count: int
|
||
avg_completion_time: Optional[float] = None
|
||
|
||
class FormAnalyticsResponse(BaseSchema):
|
||
"""Аналитика по форме"""
|
||
form_id: int
|
||
form_name: str
|
||
total_submissions: int
|
||
unique_submitters: int
|
||
avg_completion_time: Optional[float]
|
||
completion_rate: float # процент завершенных
|
||
fields_stats: List[AnalyticsFieldStats]
|
||
daily_stats: List[AnalyticsDailyStats]
|
||
peak_hours: Dict[int, int] # час -> количество
|
||
trend: str # increasing, decreasing, stable
|
||
last_submission_at: Optional[datetime]
|
||
first_submission_at: Optional[datetime] |