# Stats Service API - Статистические рекомендации и агрегаты ## Endpoints ### GET /api/v1/stats/summary Получить агрегированную статистику для дашборда. **Response:** ```json { "total_cases": 8, "active_cases": 7, "closed_cases": 1, "by_gender": {"М": 8}, "by_age_group": { "8-11": 6, "12-14": 2 }, "by_psychotype": {}, "by_diagnosis": {"здоров": 3}, "by_season": { "зима": 3, "весна": 1, "лето": 1 }, "avg_distance_km": 2.3, "avg_search_duration_hours": 4.5, "survival_rate": 100.0 } ``` ### POST /api/v1/stats/recommendation Получить статистические рекомендации на основе похожих случаев. **Фильтры (в порядке приоритета):** 1. Возраст ±2 года + сезон + terrain 2. Возраст ±2 года + сезон (если < 5 случаев) 3. Возраст ±2 года (если < 5 случаев) 4. Все случаи (если < 5 случаев) **Request:** ```json { "age": 10, "season": "лето", "terrain_primary": "лес" } ``` **Response:** ```json { "median_distance_km": 2.3, "top_directions": [ { "direction": "СВ", "count": 1, "percentage": 100.0 } ], "top_location_types": ["forest"], "survival_rate": 100.0, "sample_size": 1, "filters_used": { "age_range": "8 to 12", "season": "лето", "terrain": "лес" } } ``` ### GET /api/v1/stats/heatmap Получить данные для тепловой карты находок. **Query Parameters:** - `age_min` (optional): Минимальный возраст - `age_max` (optional): Максимальный возраст - `season` (optional): Сезон - `outcome` (optional): Исход (alive/deceased) **Response:** ```json { "points": [ { "lat": 53.9, "lon": 27.56, "intensity": 1.0, "case_id": "uuid", "distance_km": 2.3, "outcome": "alive" } ], "total": 1 } ``` ## Функции stats_service.py ### get_statistical_recommendation() SQL выборка похожих случаев с фильтрами: - Возраст ±2 года - Сезон - Terrain (тип местности) - Минимум 5 случаев для выборки Возвращает: - `median_distance_km` - медианное расстояние находки - `top_directions` - топ-3 направления с процентами - `top_location_types` - топ-5 типов локаций - `survival_rate` - процент выживаемости - `sample_size` - размер выборки - `filters_used` - использованные фильтры ### get_dashboard_stats() Агрегаты для дашборда: - Общее количество случаев (всего, активных, закрытых) - Распределение по полу, возрасту, психотипу, диагнозам, сезонам - Средняя дистанция находки - Средняя длительность поиска - Процент выживаемости ### get_heatmap_data() Данные для тепловой карты с фильтрами: - Возраст (min/max) - Сезон - Исход (alive/deceased) ## Тестирование ```bash # 1. Получить агрегаты дашборда curl http://localhost:8000/api/v1/stats/summary # 2. Получить статистические рекомендации curl -X POST http://localhost:8000/api/v1/stats/recommendation \ -H "Content-Type: application/json" \ -d '{"age": 10, "season": "лето", "terrain_primary": "лес"}' # 3. Получить данные для тепловой карты curl "http://localhost:8000/api/v1/stats/heatmap?age_min=8&age_max=12" ``` ## Протестировано (2026-05-05) ✅ GET /api/v1/stats/summary - работает ✅ POST /api/v1/stats/recommendation - работает ✅ GET /api/v1/stats/heatmap - работает ## Технические детали - **Синхронная SQLAlchemy** (не async) - **PostgreSQL ARRAY** - используется `any()` вместо `contains()` - **Fallback механизм** - если выборка < 5 случаев, расширяются фильтры - **Pydantic модели** - валидация входных/выходных данных ## Дата создания 2026-05-05