docs: 增加架构图

This commit is contained in:
2026-04-28 12:44:08 +08:00
parent d967e74125
commit 3ff8f3951a
2 changed files with 80 additions and 82 deletions
-82
View File
@@ -1,82 +0,0 @@
# CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
## Project Overview
This is a knowledge graph visualization system with a Go backend providing REST APIs and a React frontend using AntV G6 for interactive graph rendering. The system stores graph data in Neo4j and provides nodes, edges, and relationship visualization.
## Architecture
### Backend (`/backend`)
- **Entry point**: `main.go` - Sets up Gin router, initializes Neo4j connection, registers handlers
- **Handlers** (`/handlers`): HTTP request handlers for `/api/graph`, `/api/search`, `/api/nodes/:id`, `/api/nodes/:id/neighbors`
- **Services** (`/services`): Business logic layer. `Neo4jService` queries Neo4j and converts results to domain models
- **Models** (`/models`): Domain models (`Node`, `Edge`, `GraphData`) and API response types
- **Neo4j client** (`/neo4j`): Connection wrapper using `github.com/neo4j/neo4j-go-driver/v5`
- **Config** (`/config`): Configuration loading from `.env` with CORS and server settings
**Important**: Neo4j connection config is in `backend/config/.env` which contains credentials. The service queries Neo4j by executing Cypher queries and converting results to JSON.
### Frontend (`/frontend`)
- **React 19 + TypeScript + Vite** build system
- **State management**: Zustand stores (`graphStore.ts`, `layoutStore.ts`)
- **Graph visualization**: AntV G6 v5 for force-directed layout and interactive graphs
- **Styling**: Tailwind CSS v4 + HeroUI components
- **API client**: Axios (`services/graphApi.ts`)
**Key frontend components**:
- `KnowledgeGraph.tsx` - Main page that wires up search, graph view, and node panel
- `GraphView/index.tsx` - G6 graph rendering with node selection, highlighting
- `NodePanel/index.tsx` - Sidebar showing selected node details
- `SearchBar/index.tsx` - Search input with node autocomplete
## Common Commands
### Backend
```bash
cd backend
go run main.go # Start dev server on :3001
swag init -g main.go # Regenerate Swagger docs
```
### Frontend
```bash
cd frontend
npm run dev # Start dev server on :5173
npm run build # Production build
npm run lint # Lint code
```
### API Endpoints
- `GET /health` - Health check
- `GET /api/graph` - Get all graph data (nodes + edges)
- `GET /api/graph/stats` - Graph statistics
- `GET /api/search?q=query` - Search nodes by label, ID, or type
- `GET /api/nodes/:id` - Get node by ID
- `GET /api/nodes/:id/neighbors` - Get node neighbors and related edges
- `GET /swagger/*` - Swagger UI documentation
## Data Flow
1. Frontend fetches graph data via `/api/graph`
2. Graph data is stored in `graphStore` (Zustand)
3. `GraphView` renders with G6 force-directed layout
4. Node clicks highlight connected nodes and trigger `NodePanel` updates
5. Search queries `/api/search` and selects matching nodes
## Neo4j Queries
The backend uses these Cypher query patterns:
- All nodes: `MATCH (n) RETURN n`
- All edges: `MATCH (a)-[r]->(b) RETURN a.id AS source, b.id AS target, r`
- Node by ID: `MATCH (n {id: $id}) RETURN n`
- Search: `MATCH (n) WHERE toLower(n.label) CONTAINS toLower($query) OR ... RETURN n`
- Neighbors: `MATCH ({id: $id})-[r]-(m) RETURN m, r, startNode(r).id AS source, endNode(r).id AS target`
## File Conventions
- Backend handlers follow `*_handler.go` naming
- Swagger annotations in handlers with `@Summary`, `@Router`, etc.
- Frontend types in `types/graph.ts` shared between components
- Graph styling utilities in `utils/graphStyle.ts`
+80
View File
@@ -0,0 +1,80 @@
<svg xmlns="http://www.w3.org/2000/svg" width="1920" height="1200" viewBox="0 0 960 600">
<defs>
<marker id="arrow" markerWidth="10" markerHeight="7" refX="10" refY="3.5" orient="auto">
<polygon points="0 0, 10 3.5, 0 7" fill="#2563eb"/>
</marker>
<marker id="arrow-orange" markerWidth="10" markerHeight="7" refX="10" refY="3.5" orient="auto">
<polygon points="0 0, 10 3.5, 0 7" fill="#ea580c"/>
</marker>
<style>
.title { font: 700 20px Arial, sans-serif; fill: #0f172a; }
.label { font: 600 14px Arial, sans-serif; fill: #0f172a; }
.small { font: 12px Arial, sans-serif; fill: #334155; }
.box { stroke: #1e293b; stroke-width: 1.5; rx: 16; ry: 16; }
.layer { fill: #f8fafc; stroke: #cbd5e1; stroke-dasharray: 7 5; stroke-width: 1.5; rx: 20; ry: 20; }
</style>
</defs>
<rect x="0" y="0" width="960" height="600" fill="#ffffff"/>
<text x="480" y="42" text-anchor="middle" class="title">knowledge-graph-agent 项目架构图</text>
<text x="480" y="66" text-anchor="middle" class="small">知识图谱 + 层级记忆 + 自省反馈 + AI 对话 + 邮件自动化</text>
<rect x="40" y="100" width="880" height="120" class="layer"/>
<text x="60" y="124" class="label">用户交互层</text>
<rect x="40" y="240" width="880" height="130" class="layer"/>
<text x="60" y="264" class="label">应用服务层</text>
<rect x="40" y="395" width="880" height="140" class="layer"/>
<text x="60" y="419" class="label">数据与外部能力层</text>
<rect x="90" y="145" width="220" height="48" class="box" fill="#dbeafe"/>
<text x="200.0" y="167" text-anchor="middle" class="label">React 前端</text>
<text x="200.0" y="185" text-anchor="middle" class="small">Graph UI / Chat UI</text>
<rect x="350" y="145" width="220" height="48" class="box" fill="#dbeafe"/>
<text x="460.0" y="167" text-anchor="middle" class="label">AntV G6 + Zustand</text>
<text x="460.0" y="185" text-anchor="middle" class="small">图谱渲染 / 状态管理</text>
<rect x="610" y="145" width="240" height="48" class="box" fill="#dbeafe"/>
<text x="730.0" y="167" text-anchor="middle" class="label">Axios + Tailwind</text>
<text x="730.0" y="185" text-anchor="middle" class="small">API 请求 / UI 样式</text>
<rect x="90" y="285" width="220" height="52" class="box" fill="#dcfce7"/>
<text x="200.0" y="307" text-anchor="middle" class="label">Gin API 层</text>
<text x="200.0" y="325" text-anchor="middle" class="small">REST 接口 / 路由 / 校验</text>
<rect x="350" y="285" width="220" height="52" class="box" fill="#dcfce7"/>
<text x="460.0" y="307" text-anchor="middle" class="label">Graph Service</text>
<text x="460.0" y="325" text-anchor="middle" class="small">查询 / 搜索 / 邻居 / CRUD</text>
<rect x="610" y="285" width="240" height="52" class="box" fill="#dcfce7"/>
<text x="730.0" y="307" text-anchor="middle" class="label">AI & Conversation</text>
<text x="730.0" y="325" text-anchor="middle" class="small">Prompt / 会话 / 上下文增强</text>
<rect x="120" y="435" width="220" height="54" class="box" fill="#fef3c7"/>
<text x="230.0" y="457" text-anchor="middle" class="label">Neo4j 5.x</text>
<text x="230.0" y="475" text-anchor="middle" class="small">知识图谱持久化</text>
<rect x="390" y="435" width="220" height="54" class="box" fill="#fef3c7"/>
<text x="500.0" y="457" text-anchor="middle" class="label">AI Provider</text>
<text x="500.0" y="475" text-anchor="middle" class="small">硅基流动 OpenAI 接口</text>
<rect x="660" y="435" width="180" height="54" class="box" fill="#fef3c7"/>
<text x="750.0" y="457" text-anchor="middle" class="label">邮件自动化</text>
<text x="750.0" y="475" text-anchor="middle" class="small">后续增强</text>
<line x1="200" y1="193" x2="200" y2="285" stroke="#2563eb" stroke-width="2" marker-end="url(#arrow)"/>
<rect x="154.0" y="217.0" width="92" height="20" rx="6" ry="6" fill="#ffffff" opacity="0.96"/>
<text x="200.0" y="231.0" text-anchor="middle" class="small">用户操作 / 查询</text>
<line x1="460" y1="193" x2="460" y2="285" stroke="#2563eb" stroke-width="2" marker-end="url(#arrow)"/>
<rect x="414.0" y="217.0" width="92" height="20" rx="6" ry="6" fill="#ffffff" opacity="0.96"/>
<text x="460.0" y="231.0" text-anchor="middle" class="small">图谱浏览 / 编辑</text>
<line x1="730" y1="193" x2="730" y2="285" stroke="#2563eb" stroke-width="2" marker-end="url(#arrow)"/>
<rect x="684.0" y="217.0" width="92" height="20" rx="6" ry="6" fill="#ffffff" opacity="0.96"/>
<text x="730.0" y="231.0" text-anchor="middle" class="small">提交消息 / 交互</text>
<line x1="240" y1="337" x2="240" y2="435" stroke="#2563eb" stroke-width="2" marker-end="url(#arrow)"/>
<rect x="194.0" y="364.0" width="92" height="20" rx="6" ry="6" fill="#ffffff" opacity="0.96"/>
<text x="240.0" y="378.0" text-anchor="middle" class="small">读写图数据</text>
<line x1="460" y1="337" x2="460" y2="435" stroke="#2563eb" stroke-width="2" marker-end="url(#arrow)"/>
<rect x="414.0" y="364.0" width="92" height="20" rx="6" ry="6" fill="#ffffff" opacity="0.96"/>
<text x="460.0" y="378.0" text-anchor="middle" class="small">检索上下文 / 记忆</text>
<line x1="730" y1="337" x2="520" y2="435" stroke="#2563eb" stroke-width="2" marker-end="url(#arrow)"/>
<rect x="579.0" y="364.0" width="92" height="20" rx="6" ry="6" fill="#ffffff" opacity="0.96"/>
<text x="625.0" y="378.0" text-anchor="middle" class="small">生成回复 / 调用模型</text>
<path d="M 850 462 C 900 462, 900 520, 850 520" fill="none" stroke="#ea580c" stroke-width="2" marker-end="url(#arrow-orange)"/>
<rect x="780" y="520" width="140" height="36" rx="10" ry="10" fill="#fff7ed" stroke="#fb923c"/>
<text x="850" y="543" text-anchor="middle" class="small">定时任务 / 邮件</text>
<rect x="60" y="535" width="250" height="42" rx="10" ry="10" fill="#f8fafc" stroke="#cbd5e1"/>
<line x1="78" y1="556" x2="130" y2="556" stroke="#2563eb" stroke-width="2" marker-end="url(#arrow)"/>
<text x="146" y="561" class="small">主要请求 / 数据流</text>
<rect x="340" y="535" width="250" height="42" rx="10" ry="10" fill="#f8fafc" stroke="#cbd5e1"/>
<line x1="358" y1="556" x2="410" y2="556" stroke="#ea580c" stroke-width="2" marker-end="url(#arrow-orange)"/>
<text x="426" y="561" class="small">外部能力 / 触发流</text>
</svg>

After

Width:  |  Height:  |  Size: 6.3 KiB