Commit Graph

25 Commits

Author SHA1 Message Date
root bef603415f B19: переписать как отдельный проект «Контур» (не фаза Вектора)
По концепции пользователя: Вектор = «где искать», Контур = «как выполнять
поиск в поле» — два независимых проекта. Контур = ATAK + Meshtastic + GPS.
Замкнутый цикл: Вектор→зоны→Контур→поле→наблюдения→Вектор→перерасчёт.
Вектор-сторона взаимодействия = B17 (приём данных) + B18 (перерасчёт/выдача)
+ отдельная задача «Контракт обмена» (развязка: движок не знает ATAK/Mesh).

Co-Authored-By: Claude <noreply@anthropic.com>
2026-08-20 16:51:49 +00:00
root 25d852035a B13–B19: дорожная карта реструктуризации Вектора в систему подсистем
B13 — каркас-видение: 7 подсистем (Core/GIS/Search Area/Field Data/
Real-time/Backend/UI) + 4 ключевых принципа (развязка движка, 4 слоя данных,
итеративная модель, очередь задач) + технический контур PostGIS.
B14 — чистый SearchEngine (поведение-сохраняющий, B1-safe).
B15 — 4 слоя данных: схема + Alembic-миграция + версионирование моделей.
B16 — GIS: PostGIS + локальный OSM (замена живого Overpass).
B17 — Field Data: модель + ингестия операционных данных.
B18 — итеративный пересчёт модели + очередь задач (event-driven).
B19 — «Контур» (ATAK + Meshtastic, реал-тайм) — плейсхолдер, отдельный проект.
Сводка и рекомендуемый порядок обновлены.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-08-20 16:46:14 +00:00
root 3e2692f8a5 B5: перенести расчёт анализа в бэкенд (единый источник правды)
AnalysisResult.jsx теперь тонкий клиент над POST /api/v1/analyze — локальные
формулы (calculateFullDistance / generateZonesWithPsychotype / getPsychotypeModifiers)
удалены. Бэкенд становится единственным источником правды.

distance_service:
- get_base_speed: перенесены каноничные displacement-скорости фронта (0.3–2.5)
  вместо расходящихся значений бэкенда (1.0–5.5) — согласовано с априорами ПСО
- реализованы заглушки СКД (get_diagnosis_coefficient: эпилепсия 0.6, ЗПР 0.8,
  РАС 1.0, СДВГ 1.1, здоров 1.0) и СУ (get_transport_coefficient: bike ×5,
  car ×8, иное ×3, none ×1) — критичная безопасность bike×5 теперь в бэкендe
- get_time_of_day_coefficient: сумерки/вечер 0.7 (было 0.5)

analyze.py:
- _derive_profiles: профили (РАС/эпилепсия/СДВГ/ЗПР/велосипед/самокат) формируются
  из diagnosis_type + has_transport, закрывая рассинхрон bike/велосипед на границе
- _derive_time_of_day: время суток из loss_time (порт getTimeOfDay фронта)
- психотип детектится ДО claude_analyze, модификаторы прокидываются в score_zone
- _as_case_data: фильтр пустых контейнеров ([],{}) — фикс затирания данных карточки
  дефолтами payload (psychotype_answers={} затирал реальные ответы)
- в ответ добавлены coefficients, time_of_day, active_profiles, critical_warnings

scoring_service.score_zone: применяется множитель полосы психотипа по дистанции
(порт getPsychotypeModifiers; таблица уже есть в psychotype_service).

AnalysisResult.jsx: рендер бэкенд-ответа, адаптер primary_zones→SearchMap
(score из приоритета, reasoning←reason), локализация пола m/f→М/Ж, бейдж
fallback/ИИ, блоки активных профилей + критических предупреждений + рекомендаций
по психотипу, исправлены ключи отображения (loss_time/behavior_description/
temperature_c). Поведение сохранено (bike 8yo 2h лес = 5.4 км, как во фронте).

Co-Authored-By: Claude <noreply@anthropic.com>
2026-08-20 16:36:35 +00:00
root d0f309cdf6 chore(frontend): remove dead components (B4)
Недостижимые от index.js -> App компоненты (23 файла):
- MobileForm.jsx/.tsx/.css (живая мобильная форма = CaseForm)
- BehavioralProfile.tsx/.css
- AnalysisLayout/, MapView/, ResultPanel/ (MapView/ResultPanel
  импортировались только из неиспользуемого AnalysisLayout; живая
  карта = SearchMap.jsx)
- admin/ (CaseDetail, CasesList, HeatmapView, Statistics) - AdminDashboard
  использует inline-UI, не эти компоненты
- CaseForm/Step5Resources.jsx - не подключён в CaseForm.jsx

Сборка проходит. Мёртвый код с его багами (isPsycotypeSelected опечатка,
хардкод URL, NaN-гварды) уходит вместе с файлами.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-08-20 16:14:25 +00:00
root bef93d159c feat(auth): minimal login/logout + ProtectedRoute (B-LOGOUT)
- 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>
2026-08-20 16:04:18 +00:00
Sadmin c2ad5c1915 Обновить vector_tasks.md 2026-08-15 13:36:23 +00:00
root 83e75e7c24 docs(tasks): add B11 (Anthropic -> local Ollama) and B12 (ISRID priors)
Both are Section B (needs-context): B11 touches the AnalysisResult
contract and the question of where an LLM is needed at all; B12 touches
scoring coefficients and the DB schema, which project rules keep off
limits to automated edits.

B11 records the key finding that the LLM does not compute priorities --
the math already lives in geo_service/scoring_service/psychotype_service
and analyze_with_fallback already returns a full AnalysisResult with no
API. The only unique in-hot-path LLM role is parsing free-text reports,
so a strict intake form and a local provider are independent levers.

B12 notes ISRID supplies empirical priors for the currently hand-tuned
zone weights, with the legal status of the database flagged as a
blocking question to resolve before any data enters the repo.

Summary table updated to B1-B12.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-25 13:31:04 +00:00
root b30ce86fa9 docs: fix LXC host address 192.168.0.108 -> 192.168.0.99
Revert of A9 address change. The .108 value was inferred from the
container VMID (108), not from its actual network config: net0 is
ip=dhcp and the container currently holds 192.168.0.99. Requests to
.108 fail with "No route to host", making the UI look down while all
four compose services are healthy.

A9 section in vector_tasks.md is kept as history and flagged stale so
the .99 -> .108 replacement is not repeated.

Note: the address is DHCP-assigned and may change again; a static IP
would be needed to make these docs durable. Hardcoded .99 URLs remain
in MobileForm.jsx:49 and HeatmapView.jsx:73 (tracked in vector_tasks.md,
untouched here).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-25 13:21:15 +00:00
root 3a0d2b0c2d B6: SPA navigation after case creation (useNavigate instead of window.location.href)
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.
2026-07-25 13:04:19 +00:00
root 8b3a2cbf7e B2: tolerant JSON extraction from Claude responses + graceful fallback
_extract_json_payload handles a json/JSON/bare fence, raw JSON and JSON
embedded in prose; any unparseable response or contract violation now
degrades to the deterministic scoring_service instead of raising.
Also guards the response envelope itself (content[0].text).

B3: single home for recommendation scoring

services/recommendation_service.py holds the rules; routers/stats.py and
backend/services/stats_service.py both delegate to it. Unified rules are the
union of the two old copies: same weights/threshold, substring matching
(superset of the old exact match), tolerant key aliases, health_flags rule
kept. Endpoint response contract unchanged.

Plus: Overpass circuit breaker and concurrent zone queries in geo_service -
128 sequential calls per analysis no longer each burn a connect timeout when
the host has no outbound network.

Tests: 152 -> 194 passed.
2026-07-25 13:01:02 +00:00
root 76278f5fe1 fix: apply A1/A2/A3 to the live services/ copy and ship it in the backend image
backend/routers/analyze.py imports services.* (root package), not
backend.services.* - so the earlier A1/A2/A3 edits landed in an unused
duplicate. Also COPY/mount services/ so the container can start at all
(ModuleNotFoundError: No module named services).
2026-07-25 12:31:07 +00:00
root 5a631f6553 A10-A16: datetime-local time parsing, step heading, gps_error state, unified leaflet 1.9.4 icons, drop debug log, dashboard error surfacing, isMobile on resize 2026-07-25 12:02:56 +00:00
root 0b033c402d A9: unify docs on 192.168.0.108 / vector_mchs / /root/vector 2026-07-25 11:57:36 +00:00
root cd65116a2a A2-A6: logging instead of print, claude-sonnet-5 model id, timezone-aware datetime, FastAPI lifespan, .docx parse errors -> HTTP 400 2026-07-25 11:57:03 +00:00
root 0de5beeb64 A7: enable pytest-asyncio (26 skipped async tests now run); fix stale distance assertion in test_geo_service 2026-07-25 11:49:53 +00:00
root 6ca59a04d0 A8: remove dead backend code (old api/ copy, models_* duplicates, .bak files) 2026-07-25 11:48:30 +00:00
Sadmin 5490f3c5f2 A1: guard None/empty args in distance_service coefficients 2026-07-23 21:41:40 +00:00
Sadmin 527b82767a Add vector tech-debt task queue 2026-07-23 21:01:44 +00:00
root 4ed1809d54 P4 clean repo artifacts 2026-06-08 16:40:42 +00:00
root 14b3f1af45 P3 auth cors and distance fixes 2026-06-08 16:38:01 +00:00
root 1755e9759b P2 tighten route auth 2026-06-08 16:34:28 +00:00
root 36123d784f P1 auth, CORS, and SQL filtering 2026-06-08 16:21:23 +00:00
root 4e80a0bdfe Make backend start on PostgreSQL 2026-06-08 11:50:29 +00:00
root 3548733019 Fix admin import chain and tests 2026-06-06 20:59:23 +00:00
root fcc22063ed Import Vector lab project 2026-06-06 18:31:55 +00:00