Files
vector/README.md
T

431 lines
38 KiB
Markdown
Raw 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.
# ВЕКТОР МЧС — Система определения приоритетных направлений поиска
**Программное средство поддержки принятия решений при поисково-спасательных работах (ПСР) на открытой местности МЧС Республики Беларусь.**
ВЕКТОР рассчитывает приоритетные направления поиска пропавшего человека по матмодели: на основании данных о потерявшемся (возраст, диагнозы, физподготовка, транспорт), обстоятельствах потери (время, причина, направление), среде (рельеф, погода, сезон) и точке последней пропажи (ТНП) система строит концентрическую зону вероятного нахождения и подсвечивает приоритетные направления обследования с учётом рельефа из OSM-данных.
> **Версия документа:** соответствует состоянию репозитория на 25 сентября 2026 г.
> **Репозиторий:** [`Sadmin/vector`](http://192.168.0.106:3000/Sadmin/vector)
> **Развёртывание:** см. [SETUP_GUIDE.md](SETUP_GUIDE.md) — пошаговый гайд по развёртыванию на серверах МЧС.
---
## Оглавление
1. [Назначение и контекст](#1-назначение-и-контекст)
2. [Ключевая политика: полностью закрытый контур](#2-ключевая-политика-полностью-закрытый-контур)
3. [Архитектура](#3-архитектура)
4. [Стек технологий](#4-стек-технологий)
5. [Структура репозитория](#5-структура-репозитория)
6. [База данных](#6-база-данных)
7. [Математическая модель расчёта](#7-математическая-модель-расчёта)
8. [OSM-геослой (PostGIS)](#7-osm-геослой-postgis)
9. [Бэкенд (FastAPI) — структура и API](#8-бэкенд-fastapi--структура-и-api)
10. [Фронтенд (React)](#9-фронтенд-react)
11. [Аутентификация, роли и подразделения (RBAC)](#10-аутентификация-роли-и-подразделения-rbac)
12. [Мультипоиск и операции](#11-мультипоиск-и-операции)
13. [Интеграция с КОНТУР (отправка зон)](#12-интеграция-с-контуром-отправка-зон)
14. [Аудит](#13-аудит)
15. [Тестирование](#14-тестирование)
16. [Справочники](#14-справочники)
17. [Что готово и что в планах](#15-что-готово-и-что-в-планах)
18. [Контакты и сопровождение](#16-контакты-и-сопровождение)
---
## 1. Назначение и контекст
### Что делает ВЕКТОР
ВЕКТОР — рабочий инструмент РЦУ (расчётно-центрального управления) МЧС Республики Беларусь при организации поиска пропавших людей:
- **Карточка поиска** — структурированный ввод данных: субъект (возраст, пол, диагнозы — РАС, эпилепсия, СДВГ, ЗПР, психотип), обстоятельства (причина потери, время, направление движения, надёжность свидетельства), среда (сезон, погода, температура, рельеф), ресурсы (группы, кинолог, транспорт)
- **Матрасчёт** — детерминированный расчёт: максимальный радиус по методике ПСР (КМЧ × коэффициенты), приоритетные направления (сектора 45° с весами), прогноз поведения по психотипу, срочность и критические действия
- **Карта зон** — Leaflet: концентрические круги возможной зоны (0.5R / 0.75R / R) + подсветка приоритетных направлений; слои воды/болот полигонами и ж/д линий из локальной OSM
- **Рекомендации** — тактические рекомендации по профилям случая (проверить водоёмы, обследовать вдоль дорог и т.д.)
- **Мультипоиск** — несколько одновременных поисков, каждое ОУМЧС/Г(Р)ОЧС работает со своими операциями
- **Интеграция с КОНТУР** — отправка зон в полевую систему координации (ATAK + Meshtastic)
- **Архив завершённых поисков** — факт vs прогноз (дистанция, направление, место находки) для калибровки зонального скоринга
- **Администрирование** — пользователи по иерархии МЧС, журнал аудита, статистика
### Методическая основа
Расчёт радиуса основан на статистических таблицах ПСР (поиск и спасение, экстремум-методика): базовая скорость смещения по среднему лесу (НормС) умножается на коэффициенты возраста, диагноза, рельефа, погоды, времени суток, транспорта. Скоринг зон — взвешенная сумма факторов рельефа (лес, вода, дороги, НП) по секторам вокруг ТНП.
### Домен
МЧС осуществляет поиски **только в природных экосистемах** — не в городах. Город учтён в коэффициентах рельефа, но приоритетные зоны строятся для природной среды.
---
## 2. Ключевая политика: полностью закрытый контур
**Все данные о поисках (включая ПДн детей) не покидают контур организации.**
- **ИИ/LLM удалён из проекта полностью** (решение руководства): анализ детерминированный, `backend/services/claude_service.py` и любые облачные API исключены. В `docker-compose` и `.env` НЕТ никаких API-ключей внешних сервисов
- **Расчёт локальный**: вся математика в `services/*.py` (Python), выполняется на сервере за миллисекунды
- **Карты — из локальной OSM**: дамп Geofabrik (беларусь-latest.osm.pbf, ~333 МБ) импортирован в PostGIS внутри организации; бэкенд не ходит в Overpass/интернет (fallback на Overpass остаётся только на случай пустых OSM-таблиц)
- **Фронтенд** тянет OSM-тайлы и иконки Leaflet с CDN — для полностью offline-контура требуется локальный tile-сервер (в планах)
Тест-страж: `backend/tests/test_rules_analysis.py::TestNoLLM` — падает, если в код возвращается внешний ИИ.
---
## 3. Архитектура
```
┌───────────────────────────────────────────────────┐
│ Браузер пользователя │
│ (Chrome / Firefox / Edge — любая ОС) │
└──────────────────────┬────────────────────────────┘
│ HTTP
┌──────────────────────▼────────────────────────────┐
│ vector-frontend (React 18, CRA, порт 3000) │
│ Форма карточки · карта Leaflet · дашборд · админка│
└──────────────────────┬────────────────────────────┘
│ REST JSON :8000
┌──────────────────────▼────────────────────────────┐
│ vector-backend (FastAPI, порт 8000) │
│ ┌──────────────────────────────────────────────┐ │
│ │ Роутеры: auth, cases, analyze, operations, │ │
│ │ admin, admin_users, closed_cases, contour, │ │
│ │ water, geocode, stats, health │ │
│ └──────────────────────────────────────────────┘ │
│ ┌──────────────────────────────────────────────┐ │
│ │ Services (математика, без БД/HTTP): │ │
│ │ search_engine (модель), distance_service │ │
│ │ (радиус), scoring_service (сектора), │ │
│ │ rules_analysis (правила), psychotype, │ │
│ │ geo_service → osm_local (PostGIS) │ │
│ └──────────────────────────────────────────────┘ │
└──────────────────────┬────────────────────────────┘
│ SQLAlchemy / psycopg2
┌──────────────────────▼────────────────────────────┐
│ vector-postgres (PostgreSQL 16 + PostGIS 3.6) │
│ БД vector_mchs: кейсы, операции, юниты, аудит, │
│ OSM (planet_osm_*: 1 млн дорог, 192 тыс. лесов) │
└───────────────────────────────────────────────────┘
│ (опционально, outbound)
┌──────────────────────▼────────────────────────────┐
│ КОНТУР (CT130, полевая координация ATAK) │
│ POST /api/v1/vector/zones — приоритетные зоны │
└───────────────────────────────────────────────────┘
```
### Принципы архитектуры
- **Чистая математика**: `services/*.py` не знают ни о БД, ни об HTTP — только входные словари на выходе модели. Тонкие роутеры-обёртки в `backend/routers/`
- **Контракт /analyze**: `zone.forest_pct` — доля 0..1 (не проценты!), дистанции — км (в PostGIS SRID 3857 раздувание мерка: real = mercator × cos(lat))
- **Анализ воспроизводим**: тот же вход — тот же выход; прогон модели сохраняется в `analysis_log` кейса и сравнивается с фактом в архиве
---
## 4. Стек технологий
| Слой | Технология | Версия | Назначение |
|------|-----------|--------|-----------|
| Бэкенд | FastAPI | 0.115 | REST API |
| ORM | SQLAlchemy 2.0 + psycopg2 | | БД + миграции Alembic 1.14 |
| БД | PostgreSQL 16 + PostGIS 3.6 | | Данные + гео (PostGIS) |
| OSM | osm2pgsql 2.1 | | Импорт дамп OSM → planet_osm_* |
| Auth | python-jose + passlib | | JWT + bcrypt, server-side сессии |
| Фронт | React 18 (CRA) + react-leaflet | | SPA |
| Карта | Leaflet 1.9 + OSM-тайлы | | Отображение зон |
| Контейнеры | Docker Compose | | 4 сервиса |
Полный список зависимостей — `backend/requirements.txt` и `frontend/package.json`.
---
## 5. Структура репозитория
```
vector/
├── backend/ # FastAPI-приложение
│ ├── main.py # Сборка приложения (12 роутеров)
│ ├── models.py # 22 таблицы (SQLAlchemy, +password_history)
│ ├── schemas.py # Pydantic-схемы
│ ├── database.py # Репозиторий кейсов + статистика
│ ├── audit.py # Журнал аудита + гео-скоуп
│ ├── password_policy.py # B23: исполняемая политика паролей
│ ├── purge_logs.py # B23: ретенция журналов (DELETE, cron)
│ ├── rbac.py # Роли/права/политика безопасности
│ ├── alembic/ # Миграции (006…010)
│ ├── seed_users.py # Сид первых пользователей
│ ├── seed_units.py # Сид подразделений (РЦУ РЧС → ОУМЧС → Г(Р)ОЧС, 142 юнита)
│ ├── routers/ # 12 модулей API (см. раздел 8)
│ ├── services/ # Адаптеры расчёта
│ └── tests/ # 263 теста (pytest)
├── services/ # Математика (чистые функции)
│ ├── search_engine.py # SearchInput/SearchModel — ядро расчёта
│ ├── distance_service.py # Максимальный радиус (КМЧ × коэффициенты)
│ ├── scoring_service.py # Взвешенный скоринг секторов
│ ├── rules_analysis.py # Правила: срочность, действия, поведение
│ ├── psychotype_service.py # Психотипирование (опрос)
│ ├── geo_service.py # Геоданные секторов (лес/вода/дороги/НП)
│ ├── osm_local.py # Локальный PostGIS-провайдер OSM
│ └── recommendation_service.py
├── frontend/ # React SPA
│ └── src/
│ ├── App.js # Роутинг (/dashboard, /desktop, /users, /admin)
│ ├── constants.js # Единые справочники (место находки, кто нашёл, румбы)
│ ├── api/client.js # apiFetch/apiJson — Bearer + 401-перехват
│ ├── components/ # CaseForm (5 шагов), SearchMap, ProtectedRoute
│ └── pages/ # Dashboard, DesktopSARPage, analysis/, AdminDashboard,
│ # UsersAdmin, ClosedCases, Login
├── scripts/ # Развёртывание и живые проверки
│ ├── b16-import.sh # Импорт OSM-дампа в PostGIS
│ ├── e2e-*.sh # e2e-сценарии
│ ├── eN-live-check.sh # Живые проверки этапов E1–E4
│ └── prod-stamp-backfill.sql
├── docker-compose.yml # 4 сервиса: postgres, adminer, backend, frontend
├── .env.example # Шаблон окружения (без внешних ключей)
├── SETUP_GUIDE.md # Развёртывание на серверах МЧС
├── vector_tasks.md # Живой план работ (B1…B21+)
└── README.md # Этот документ
```
---
## 6. База данных
**PostgreSQL 16 + PostGIS 3.6**, БД `vector_mchs`. Схема управления — Alembic (`backend/alembic/versions/`), актуальная ревизия **010_b23_policy**.
### Основные таблицы
| Таблица | Назначение |
|---------|-----------|
| `cases` | Карточки поисков: субъект, обстоятельства, среда, ТНП, исход |
| `analysis_log` | JSONB-лог прогонов анализа (аудит расчётов) |
| `search_models` | Слой 4: сохранённые матмодели по кейсам (GeoJSON-зоны) |
| `search_teams`, `field_observations`, `areas_checked`, `found_events` | Оперативные слои (состав групп, наблюдения, проверенные квадраты, находки) |
| `reference_priors` | Слой 1: справочные приоритеты |
| `users`, `mchs_units` | Пользователи; иерархия РЦУ РЧС → 6 ОУМЧС → 135 Г(Р)ОЧС |
| `password_history` | История паролей (bcrypt-хэши; проверка переиспользования, B23) |
| `roles`, `permissions`, `role_permissions`, `user_roles` | RBAC: 4 роли, 9 прав, матрица связей |
| `sessions`, `auth_events` | Server-side сессии (sha256-токены), журнал входов |
| `security_settings` | Политика безопасности (10 параметров, **исполняется кодом с B23**) |
| `search_operations` | Поисковые операции (статусная машина, привязка к кейсу и КОНТУРу) |
| `audit_events`, `audit_changes` | Неизменяемый журнал аудита, field-level изменения (ретенция 90 дней) |
| `planet_osm_*` | Импорт OSM Беларуси (osm2pgsql, SRID 4326/3857): дороги, леса, вода, НП |
### Политика безопасности (`security_settings`, меняется в админке)
| Параметр | Значение | Исполнение (B23) |
|----------|----------|------------------|
| Минимальная длина пароля | 8 | ✅ при смене/сбросе пароля |
| Сложность пароля | требуются буквы+цифры | ✅ при смене/сбросе пароля |
| Срок действия пароля | 90 дней | ✅ `enforce_expiry` на каждом запросе → `must_change_password` |
| История паролей | 5 (нельзя переиспользовать) | ✅ таблица `password_history` (5 последних старых хэшей + текущий) |
| Блокировка после неудачных входов | 5 (на 15 минут) | ✅ (с B21) |
| Тайм-аут сессии | 24 ч | ✅ проверка `expires_at` при каждом запросе |
| Тайм-аут неактивности | 60 мин | ⚠️ `last_seen_at` пишется, но не проверяется |
| Макс. параллельных сессий | 3 (старые отзываются) | ✅ (с B21) |
| Ретенция журнала аудита | 90 дней | ✅ реальный DELETE: cron `python -m backend.purge_logs` (03:10) или POST `/admin/users/maintenance/purge-logs` |
Семантика истории: `password_history_count = N` хранит N последних *старых* хэшей;
вместе с текущим паролем защищено N+1 последних значений.
---
## 7. Математическая модель расчёта
Ядро — `services/search_engine.py`: `SearchInput` → `SearchModel` (чистая функция, без БД/HTTP).
### Состав расчёта
1. **Максимальный радиус** (`distance_service.py`): НормС (скорость смещения по среднему лесу, км/ч) × коэффициенты возраста / диагноза / рельефа / погоды / времени суток / транспорта, с учётом усталости. Контрольные точки: подросток 14 л, 3 ч, лес = 5.1 км; велосипедист 8 л, 2 ч = 10.8 км
2. **Коэффициенты рельефа** (`terrain_map`): лес/поле/луг/город/неизвестно = 1.0; густой лес = 0.5; болото = 0.4; горы/овраги = 0.6; дорога/тропа = 0.8
3. **Сектора направлений** (`scoring_service.py`): 8 секторов по 45° вокруг ТНП; каждый сектор оценивается по составу рельефа из локальной OSM (лес — доля 0..1, вода/НП — расстояние в км), приоритетные подсвечиваются на карте
4. **Психотип** (`psychotype_service.py`): опрос из формы → доминантный / гармоничный / тревожный / интроверт → модификаторы поведения и рекомендаций
5. **Правила** (`rules_analysis.py`): срочность (critical/high/elevated/normal), критические действия, прогноз поведения по профилям (не_умеет_плавать ×3.0 к водоёмам и т.п.), тактические рекомендации («проверить водоёмы», не «перекрыть»)
6. **Профили, не покрытые моделью** (ДЦП, слабое зрение/слух) — честно помечаются `unmodeled_profiles`, не искажают расчёт
**Коэффициенты меняются только по явному решению руководства** — молча таблицы не трогать.
---
## 7. OSM-геослой (PostGIS)
- Импорт: дамп [Geofabrik](https://download.geofabrik.de/europe/belarus-latest.osm.pbf) (~333 МБ) → `scripts/b16-import.sh` (osm2pgsql --slim, ~4,5 мин, RAM 2 ГБ)
- Содержимое: 1 010 507 дорог, 192 374 леса, 81 772 воды, 2 731 НП
- Провайдер `services/osm_local.py` читает `planet_osm_*`; `geo_service.py` переключается на Overpass только если таблицы пусты
- Полный `/analyze` на локальных данных: ~10 мс (см. `scripts/e2e-b16-timing.sh`)
- Обновление дампа — по решению (раз в квартал / заморозить)
---
## 8. Бэкенд (FastAPI) — структура и API
`backend/main.py` собирает 12 роутеров. Авторизация — Bearer JWT (form-urlencoded логин, OAuth2PasswordRequestForm).
| Префикс | Модуль | Назначение |
|---------|--------|-----------|
| `/api/v1/health` | health.py | Liveness |
| `/api/v1/auth` | auth.py | Логин/логаут/me/смена пароля, блокировки |
| `/api/v1/cases` | cases.py | CRUD карточек поисков |
| `/api/v1/analyze` | analyze.py | Матрасчёт зон (по payload или case_id) |
| `/api/v1/operations` | operations.py | Операции мультипоиска (CRUD, статусная машина, /summary), завершение поиска |
| `/api/v1/operations/{id}/send-to-contour` | contour.py | Отправка зон в КОНТУР; GET areas-checked (прокси) |
| `/api/v1/admin` | admin.py | Список/редактирование кейсов, дашборд-метрики |
| `/api/v1/admin/users` | admin_users.py | Пользователи (создание/роли/юниты/блокировка/сброс пароля) + журнал аудита |
| `/api/v1/closed-cases` | closed_cases.py | Архив завершённых поисков (ручной ввод + прогон модели) |
| `/api/v1/water/{case_id}` | water.py | Вода/болота (полигоны), ж/д (линии) вокруг ТНП |
| `/api/v1/geocode` | geocode.py | Прокси Nominatim (формат «пункт, район, адрес») |
| `/api/v1/stats` | stats.py | Тепловая карта, агрегаты |
Swagger: `http://<сервер>:8000/docs`.
**Синхронизация закрытия**: кейс закрывается через ЛЮБОЙ из путей (`PATCH /admin/cases` или `POST /operations/{id}/complete`) — активная операция кейса автоматически завершается (`completed` + `closed_at`).
---
## 9. Фронтенд (React)
SPA на react-scripts (CRA). Роутинг:
| Путь | Страница |
|------|----------|
| `/dashboard` | Главная: «Активные поиски» (счётчики, карточки операций, «+ Новый поиск», «Пользователи») |
| `/desktop` | Рабочее пространство: форма карточки (5 шагов) + карта + результат анализа |
| `/analysis/:case_id` | Результат анализа: карта зон, КОНТУР-панель, «Завершить поиск» |
| `/users` | Админка пользователей + вкладка «Аудит» |
| `/admin` | Администрирование: Кейсы / Операции / Завершённые поиски |
Компоненты:
- **CaseForm** — 5 шагов: субъект → обстоятельства → среда → координаты (ТНП + геокодирование) → ресурсы; после сохранения автоматически создаётся поисковая операция
- **SearchMap** — концентрические круги (0.5R/0.75R/R) + подсветка приоритетных направлений 45°-секторами (палитра ЦОУ: #ff4d00 / #ff9f1a / #ffd166)
- **Dashboard / UsersAdmin / AdminDashboard** — VCL-density, тёмная тема (#0d1117 / #161b22 / #30363d / #e6edf3)
Единые справочники исхода — `frontend/src/constants.js` (тип места находки, кто нашёл, 8 румбов) — используются во всех точках ввода исхода.
---
## 10. Аутентификация, роли и подразделения (RBAC)
### Иерархия подразделений
РЦУ РЧС (республиканский) → 6 областных ОУМЧС → 135 Г(Р)ОЧС/ПАСО. Справочник — идемпотентный сид `backend/seed_units.py` (источник: справочник подразделений РВС).
### Роли
| Роль | Права | Скоуп видимости |
|------|-------|----------------|
| **admin** (РЦУ РЧС) | Все 9 прав | Все операции и пользователи республики |
| **coordinator** (ОУМЧС) | view/create/update/export/manage_users/view_audit | Своё ОУМЧС + подчинённые Г(Р)ОЧС |
| **operator** (Г(Р)ОЧС) | view/create/update | Свои поиски |
| **observer** | view | Только просмотр |
- Управление пользователями (`manage_users`): РЦУ РЧС — все; ОУМЧС — только своё поддерево (кросс-областные операции отбиваются 403 на бэкенде)
- Созданный пользователь обязан сменить пароль при первом входе (`must_change_password`)
- Сессии server-side: JWT несёт идентификатор, в БД — sha256-хэш; сброс пароля отзывает все сессии
---
## 11. Мультипоиск и операции
`search_operations` — надстройка над кейсами для одновременной работы с несколькими поисками:
- Одна операция на карточку (case_id unique)
- **Статусная машина**: planned → active ⇄ paused → completed → archived (недопустимые переходы → 400)
- Авто-создание операции при сохранении карточки; дашборд показывает активные
- `POST /operations/{id}/complete` — завершение поиска: исход (найден живым/погибшим, дистанция, направление, кто нашёл) → кейс в архив + детерминированный прогон матмодели → сравнение «прогноз vs факт» (accuracy_note)
- `GET /operations/summary` — счётчики для дашборда (активные / всего / завершено за 24 ч)
---
## 12. Интеграция с КОНТУР (отправка зон)
КОНТУР — система полевой координации (ATAK + Meshtastic). ВЕКТОР отдаёт приоритетные зоны (outbound):
1. В операции задаётся `contour_operation_id` (UUID операции в КОНТУРе)
2. `POST /api/v1/operations/{id}/send-to-contour` строит `SearchZones[]` (GeoJSON-полигоны секторов ±22.5°, `zone_id = vec:<НАПР>:<дист>m`, probability по приоритету) и отправляет на `{CONTOUR_API_URL}/api/v1/vector/zones?operation_id=…` с `Bearer CONTOUR_TOKEN`
3. Каждый шаг аудируется (`contour_send_ok` / `contour_send_failed`); ошибка КОНТУРа → 502
4. `GET /api/v1/operations/{id}/areas-checked` — прокси проверенных полевых квадратов (inbound, B17)
Переменные окружения: `CONTOUR_API_URL` (по умолчанию `http://192.168.0.130:8000`), `CONTOUR_TOKEN`.
---
## 13. Аудит
Неизменяемый журнал (append-only):
- `audit_events`: кто, что, когда, IP, user-agent, тип события (login/lockout/user_*/operation_*/contour_send_*/case_closed)
- `audit_changes`: field-level `старое → новое` по каждому изменённому полю
- Ретенция 90 дней (фильтруется при чтении из `security_settings`)
- Доступ: право `view_audit` — вкладка «Аудит» в админке `/users` с фильтром по типу и пагинацией
---
## 13а. Прикладное логирование (B22)
Единая настройка — `backend/logging_setup.py`, инициализируется один раз при старте
(`backend.main::lifespan → setup_logging()`). Все модульные логгеры проекта живут
в пространстве имён `vector.*` и пишут в:
- **stdout** контейнера — уровень INFO (меняется env `VectorLOGLEVEL=debug`);
- **файл** `/tmp/vector/vector.log` внутри контейнера — ротация 5×2 МБ (отключается `VectorLOGFILE=0`, каталог `VectorLOGDIR`).
Формат строки: `время LEVEL vector.<модуль>: сообщение`. Пороги для файла — INFO и выше.
### Наблюдаемые события
| Логгер | Событие | Что означает |
|--------|---------|--------------|
| `vector.app` | `Vector API стартует` / `остановлен` | Жизненный цикл процесса |
| `vector.analyze` | `анализ case=… радиус=… срочность=… зон=… время=…мс` | Каждый матрасчёт с длительностью |
| `vector.auth` | `login_ok` / `login_failed` / `lockout` | Входы и блокировки (user, счётчик, IP) |
| `vector.audit` | `audit <тип> user=… obj=… ip=…` | Каждая запись в audit_events |
| `vector.contour` | `contour_send_ok` / `contour_send_failed` / `contour_rejected` | Отправка зон в КОНТУР |
| `vector.operations` | `operation_complete op=… исход=…` | Завершение поиска (найден живым/погибшим) |
| `vector.admin` | `admin closed case …` | Синхронизация закрытия кейса с операциями |
| `vector.geocode` | `geocode q=… результатов=…` / `geocode timeout` | Прокси Nominatim |
| `vector.geo` / `vector.geo.osm` | Overpass недоступен, OSM PostGIS недоступен | Состояние геослоя (fallback, breaker) |
| `vector.rules` | `Geo/scoring service error` | Отказ расчёта зон → fallback-зоны |
| `vector.water` | `geo layer cache write failed` | Ошибки кэша геослоя |
### Правила
- ПДн и секреты в логи не пишутся: никаких паролей, JWT, содержимого карточек (только id и агрегаты).
- Аудит-события дублируются в БД (`audit_events`) — лог это операционный след, БД — юридический.
- Уровень по умолчанию INFO; WARNING/ERROR — для неисправностей. Не логировать на INFO каждый HTTP-запрос (это делает uvicorn access-log).
---
## 15. Что готово и что в планах
### Реализовано
- Форма карточки поиска (5 шагов), справочники, автоподсчёт «прошло времени»
- Детерминированный матрасчёт: радиус, сектора, поведение, срочность, рекомендации — без ИИ
- Локальный OSM-геослой в PostGIS (Беларусь), /analyze ~10 мс, без внешних вызовов
- Карта: концентрические круги + подсветка направлений (дизайн согласованный)
- РБАК: иерархия РЦУ РЧС → ОУМЧС → Г(Р)ОЧС (142 юнита), 4 роли / 9 прав, блокировки, сессии
- Мультипоиск: операции, статусная машина, дашборд «Активные поиски»
- Завершение поиска с внесением исхода, архив завершённых с «прогноз vs факт»
- Аудит 90 дней с field-level деталями
- Прикладное логирование `vector.*`: события анализа, входов, КОНТУРа, аудита (README §13а)
- Интеграция с КОНТУР: отправка зон (контракт B20)
- Журнал аудита пользователей: входы, изменения, отправки
- 263 автотеста (pytest), 5 skipped
- B23: исполняемая политика паролей (срок/сложность/история), ретенция журналов реальным DELETE + cron
### В планах
- **E5 (B17)** — приём полевых данных от КОНТУРа: треки групп, проверенные квадраты (areas-checked) на карте операции
- **Живая интеграция с КОНТУР** (CT130) — настройка токена и реальная отправка зон
- **Локальный tile-сервер** — для полностью offline-фронта (сейчас тайлы OSM с CDN в браузере)
- **Калибровка settlement_score** — вкладка населённых пунктов в скоринге секторов (открытый методический вопрос)
- **Калибровка зонального скоринга** по накопленному архиву «прогноз vs факт»
---
## 16. Контакты и сопровождение
- Развёртывание и эксплуатация: см. [SETUP_GUIDE.md](SETUP_GUIDE.md)
- План работ и статус этапов: `vector_tasks.md`
- API-документация: Swagger `http://<сервер>:8000/docs`
- Репозиторий: [`Sadmin/vector`](http://192.168.0.106:3000/Sadmin/vector)
Смежные системы МЧС: **РВС** («Регистрация входящих сообщений», [`Sadmin/rvs-web`](http://192.168.0.106:3000/Sadmin/rvs-web)), **КОНТУР** (полевая координация).