React + TypeScript + Vite приложение для визуализации и управления графом знаний, интегрированное с ИИ-ассистентом.
Полная документация доступна в мастер-индексе: docs/INDEX.md
Ключевые разделы:
- Архитектура и конвейер предложений (Proposal): ARCHITECTURE.md
- Каноническая спецификация графа (CANON): CANONICAL_SPEC.md
- API справочник: API_REFERENCE.md
- Векторный поиск и индексация: VECTOR_SPEC.md
- Деплой: DEPLOYMENT.md
- Миграция данных: MIGRATION_GUIDE.md
- Руководство разработчика: DEVELOPER_GUIDE.md
Для корректной работы приложения (включая граф, поиск и ИИ) требуется запущенная инфраструктура (Neo4j, Postgres, FastAPI).
Это самый быстрый способ поднять все сервисы одной командой.
-
Настройка окружения:
cp .env.example .env.prod # Проверьте настройки в .env.prod (пароли, хосты) -
Запуск всех контейнеров:
docker-compose up -d --build
-
Инициализация данных: Если база данных пуста, запустите скрипты загрузки данных внутри контейнера:
# Загрузка графа в Neo4j docker exec knowledgebase-fastapi-dev-1 python scripts/load_data.py docker exec knowledgebase-fastapi-dev-1 python scripts/push_to_neo4j.py
-
Доступ:
- Frontend:
http://localhost:5173 - Backend API:
http://localhost:8000/docs
- Frontend:
Если бэкенд уже запущен (в Docker или удаленно), вы можете запустить фронтенд локально для быстрой HMR-разработки.
-
Установка зависимостей:
cd frontend npm install -
Настройка API: Убедитесь, что в коде или переменных окружения указан правильный URL бэкенда (обычно
http://localhost:8000). -
Запуск:
npm run dev
Explore — это страница визуального исследования графа знаний на vis-network, заточенная под навигацию, анализ и быстрые “точечные” действия.
- Один клик по узлу: открывает правый сайдбар с деталями узла.
- Двойной клик по узлу: делает узел новым центром графа (перестраивает viewport).
- Kind: фильтрация узлов по типу (без повторных запросов).
- Depth: глубина построения viewport (влияет на объём данных).
- Навигация по приложению: камера и раскладка сохраняются — можно уходить/возвращаться без потери контекста.
Что сделано
GraphContextхранит “живое” состояние графа:viewport,selectedUid,depth,camera,positions.- На странице
ExplorePage.tsxиспользуется проверка валидности контекста (совпадаютselectedUidиdepth) — если валиден, не делаемgetViewport. - Состояние камеры и позиции узлов сохраняются на
cleanup(unmount/пересоздание сети) и восстанавливаются при возвращении:- камера восстанавливается через
network.moveTo(...)с анимацией; - при восстановлении отключается стабилизация (
stabilization.enabled = !isContextValid) и запрещён авто‑fit (stabilization.fit = false).
- камера восстанавливается через
- Для стабильности React‑эффектов применяются
useRef(networkRef,cameraRef,graphStateRef), чтобы не пересоздавать сеть из‑за обновлений состояния.
Исправленные баги
- Сброс камеры при переходах между страницами → сохраняем
cameraв контекст и восстанавливаем черезmoveTo. - Потеря раскладки (узлы “разъезжались” заново) → сохраняем
getPositions()и при восстановлении отключаем стабилизацию. - Авто‑зум/fit от vis-network ломал анализ →
stabilization.fit = false, камерой управляем сами. - Рывки из-за пересоздания
Networkпри обновлении камеры → камера убрана из зависимостей эффекта, чтение черезgraphStateRef. - Гонка отложенного
moveToпри быстром уходе со страницы → блокировка отложенного вызова флагомisMounted.
Что сделано
- Добавлен
NodeDetailsSidebar(drawer справа). - На событие
selectNodeвvis-networkвыставляетсяdetailsUid→ сайдбар открывается поuid. - Детали подгружаются через
useNodeDetails(uid)→ UI отрабатываетloading/error/empty. - Кнопка “Спросить AI” интегрирована через
toggleChat()(открывает чат).
Исправленные баги
- Повторный клик по тому же узлу не открывал сайдбар (узел уже выделен,
selectNodeне срабатывает) → при закрытии делаемnetworkRef.current?.unselectAll(). setStateпосле unmount в загрузке деталей → вuseNodeDetailsдобавленcancelled‑флаг.
Что сделано
- Типы для фильтра автоматически вычисляются из
viewport(уникальныеkind), плюс опцияAll. - Фильтрация применяется реактивно без повторных запросов к API: меняется набор узлов перед
toVisData(...). kindнормализован к стандарту 4.2 ('concept' | 'skill' | 'resource') черезAPP_CONFIG.kindMap, с fallback наdefaultKind.- Для стабильности данных:
- устранены дубли узлов по
uid(черезseenIds); - добавлен перенос длинных названий в
labelиfont.multi = true.
- устранены дубли узлов по
Исправленные баги
- Неизвестные типы ломали цвета/размеры узлов →
kindMap+ fallback + проверка наличия стиля в теме. - Дубли
uidвызывали артефакты/конфликтыidвvis-network→ дедупликация черезseenIds. - Длинные подписи делали граф нечитаемым → перенос строк +
font.multi = true.