Import Vector lab project
This commit is contained in:
+158
@@ -0,0 +1,158 @@
|
||||
# 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
|
||||
Reference in New Issue
Block a user