- Dashboard.jsx: счётчики (активных / всего / завершено за 24ч из
/operations/summary), фильтры по статусу, сетка карточек операций
(title, статус-бейдж, подразделение, время обновления), клик →
рабочее пространство (анализ по карточке операции).
- Роут /dashboard, «/» → дашборд (было /desktop).
- CaseForm: после создания карточки автоматически создаётся поисковая
операция (title «Поиск: имя, N лет») — операция не блокирует анализ.
- VCL-density, палитра ЦОУ (#ff4d00 акценты, статусы цветом).
- Step3Circumstances: удалено дублирующее «Последнее известное место»
(last_known_place); остаётся только tnp_address на шаге координат.
- Step4Environment: кнопка «Найти координаты» теперь РАБОЧАЯ — вызывает
новый GET /api/v1/geocode (прокси Nominatim, countrycodes=by, короткий
запрос «пункт, адрес» по граблям geocoding), заполняет lat/lon,
показывает найденный display_name или ошибку. Без debounce-автоплейса
(Pitfall 2) — только явный клик.
- Step3Circumstances: «Прошло времени» считается автоматически из
lost_time (пересчёт каждые 30 с, округление до 0.1 ч); поле остаётся
редактируемым для корректировки.
- БАГФИКС: форма шлёт lost_time, модель хранит loss_time — алиас в
_normalize_case_data. Раньше время пропажи молча терялось
(Pydantic игнорирует неизвестные поля) — elapsed_hours приходилось
вводить руками.
- last_known_place убран из валидации шага 4.
- backend/routers/geocode.py: Nominatim-прокси с auth (operator/field/admin).
192 passed, JSX валиден.
- api/client.js: apiFetch подставляет Bearer-токен, выставляет
Content-Type: application/json для не-FormData тел, ловит 401 -> событие
- context/AuthContext: валидация токена через /auth/me, loading-гейт,
logout(), подписка на 401
- components/ProtectedRoute: guard с ролями и заглушкой на время проверки
- pages/Login: форма входа (OAuth2 form-urlencoded), редирект на from
- App.js: AuthProvider, /login, ProtectedRoute на /sar /desktop
/analysis /admin (admin -> roles=[admin]) /mobile
- AdminDashboard/CaseForm/AnalysisResult: переход на apiFetch
- AdminDashboard: кнопка "Выйти" в шапке (useAuth().logout)
Co-Authored-By: Claude <noreply@anthropic.com>
B7: stop AdminDashboard refetching the case list on selection change
selectedCaseId was both read and written inside the list-loading effect and
listed in its deps, causing a second fetch on first render and after every
filter reset. Auto-select now uses a functional state update, so the effect
no longer depends on selectedCaseId; editForm stays in sync via the existing
selectedCase effect.