技术架构
深入了解 GEO Wiki Pro 的技术架构,包括前端、后端、存储和安全设计。
## 架构概览
GEO Wiki Pro 采用**前后端分离**架构,前端为单页应用(SPA),后端为 RESTful API 服务。整个系统设计遵循**文件即数据库**的理念,无需传统数据库。
```
┌─────────────────┐ ┌─────────────────┐
│ │ │ │
│ Vue 3 SPA │────▶│ Express.js API │
│ (Vite 5) │ │ (Node.js 22) │
│ │ │ │
└─────────────────┘ └────────┬────────┘
│
┌────────────┴────────────┐
│ │
┌─────┴─────┐ ┌───────┴───────┐
│ Markdown │ │ 上传的媒体 │
│ 文件存储 │ │ 文件存储 │
└───────────┘ └───────────────┘
```
## 前端架构
### 技术栈
- **框架**:Vue 3(Composition API)
- **构建工具**:Vite 5
- **样式**:Tailwind CSS 3.4
- **状态管理**:Pinia
- **路由**:Vue Router 4
- **搜索**:Fuse.js(客户端模糊搜索)
### 目录结构
```
src/
pages/ # 20 个页面组件,路由映射
components/ # 24 个可复用组件
stores/ # Pinia 状态仓库:docsStore, uiStore, siteConfigStore
api/ # API 客户端模块
client.js # 导出 apiClient 对象
request.js # request()(认证)+ requestPublic()(公开)
docs.js # 文档 CRUD + 搜索
auth.js # 登录/登出/注册
llm.js # AI 功能
admin.js # 管理后台 API
utils/ # 工具函数:i18n.js, markdown.js, icons.js, schema.js
i18n/ # 翻译文件:zh.json, en.json, jp.json
```
### 核心模块
- **docsStore**:管理文档列表、分类、标签的状态和缓存
- **uiStore**:管理 UI 状态(语言、侧边栏、主题等)
- **siteConfigStore**:管理站点配置(Hero 区域、Logo、特色文档等)
## 后端架构
### 技术栈
- **运行时**:Node.js 22
- **框架**:Express.js
- **存储**:文件系统(Markdown + JSON)
- **认证**:JWT(jsonwebtoken)
- **安全**:Helmet(CSP)、express-rate-limit
### 目录结构
```
server/
index.js # Express 入口,中间件链(固定顺序)
db.js # 文件系统数据库核心(读写/队列/缓存)
routes/
docs.js # 公开:GET /docs, GET /docs/:slug
auth.js # POST /login, POST /logout, GET /me
captcha.js # 验证码生成/验证
meta.js # GET /categories, GET /tags
geo.js # llms.txt, sitemap.xml, manifest
llm.js # AI 内容分析/生成
media.js # 文件上传/下载
config.js # 站点配置
versions.js # 文档版本历史
admin/ # 受保护的管理路由
index.js # 挂载所有管理子路由
docs.js # CRUD + 排序
drafts.js # 草稿审批流程
categories.js, tags.js, feedback.js
geo.js, stats.js, crawler-block.js
guestbook.js, users.js
middleware/
auth.js # JWT 验证、角色检查、密码修改检查
csrf.js # CSRF 保护(Double-Submit Cookie)
rateLimiter.js
crawlerTracker.js
utils/
logger.js # pino 结构化日志
promptGuard.js # LLM 提示注入检测
path.js # 路径遍历防护
```
### 中间件链(固定顺序)
```
Helmet → CORS → JSON 解析 → 速率限制 → 爬虫追踪 → URL 去重 →
日志 → CSRF → CSRF Cookie 刷新 → 认证路由 → 验证码路由 →
版本路由 → 文档路由 → 元数据路由 → GEO 路由 → LLM 路由 →
配置路由 → 媒体路由 → 管理路由(认证 + 角色 + 密码检查)
```
::: warning
中间件注册顺序至关重要。认证路由(login/logout)必须在管理路由之前注册,否则登录接口会被认证中间件拦截。
:::
## 文件存储设计
### 存储结构
```
data/
docs/{lang}/*.md # Markdown 文档(zh/en/jp)
drafts/{lang}/*.md # 草稿(AI 审核流程)
geo-wiki.json # 分类/标签/用户/反馈配置
media-meta.json # 上传者信息
history/{lang}/*.json # 文档版本历史
crawler-visits.json # AI 爬虫访问日志
csrf-secret.txt # CSRF 密钥(自动生成)
public/media/ # 上传的媒体文件
```
### 写入队列
所有文件写入通过 `enqueueWrite()` 进入串行 Promise 链。写入操作以 5 秒为周期批量合并,写入后自动调用 `invalidateCache()` 清除缓存。
**重要**:不要直接调用 `fs.writeFileSync`,始终使用 `saveDoc()`、`saveDb()` 或 `enqueueWrite()`。
### 缓存机制
- 缓存有效期:60 秒(`CACHE_TTL_MS`)
- 每次写入自动失效
- 支持手动失效:`invalidateCache()`
## 安全架构
### 认证流程
```
用户登录 → 验证密码 → 生成 JWT → 设置 httpOnly Cookie
↓
请求 API → 提取 Cookie → 验证 JWT → 检查角色 → 检查密码修改状态
```
### CSRF 保护
采用 Double-Submit Cookie HMAC 机制:
1. 服务器生成随机 Secret 并存入文件
2. Secret 同时写入 Cookie 和响应头
3. 客户端每次请求在 Header 中回传 Secret
4. 服务器验证 HMAC 签名
### CSP 策略
基于 Nonce 的 Content Security Policy:
- 每个请求生成唯一 Nonce
- 只允许具有正确 Nonce 的脚本执行
- 通过 MutationObserver 动态注入 Nonce 到动态加载的 CSS
## API 设计
### 公开 API
所有公开端点位于 `/api/v1/`,无需认证:
| 方法 | 端点 | 说明 |
|------|------|------|
| GET | `/api/v1/docs` | 文档列表(分页、可过滤) |
| GET | `/api/v1/docs/search` | 全文搜索 |
| GET | `/api/v1/docs/:slug` | 单个文档详情 |
| GET | `/api/v1/categories` | 分类列表 |
| GET | `/api/v1/tags` | 标签列表 |
| GET | `/api/v1/config` | 公开站点配置 |
| GET | `/api/v1/llms.txt` | AI 爬虫数据 |
| GET | `/api/v1/geo/sitemap.xml` | XML 站点地图 |
### 管理 API
需要认证和角色授权:
| 方法 | 端点 | 说明 |
|------|------|------|
| POST | `/api/v1/auth/login` | 登录 |
| POST | `/api/v1/auth/logout` | 登出 |
| GET | `/api/v1/auth/me` | 当前用户信息 |
| CRUD | `/api/v1/admin/docs` | 文档管理 |
| PUT | `/api/v1/admin/docs/reorder` | 文档排序 |
| CRUD | `/api/v1/admin/categories` | 分类管理 |
| CRUD | `/api/v1/admin/tags` | 标签管理 |
| POST | `/api/v1/media/upload` | 文件上传 |
| POST | `/api/v1/admin/geo/rebuild` | 重建 GEO 文件 |
### 响应格式
```json
// 成功
{ "success": true, "data": { ... } }
// 分页
{ "success": true, "data": [...], "pagination": { "page": 1, "limit": 20, "total": 42 } }
// 错误
{ "success": false, "message": "Not found" }
```
## 部署架构
### Docker 多阶段构建
```
阶段 1:构建前端
Node.js 22 → npm install → npm run build → dist/
阶段 2:生产运行
Node.js 22 → Express.js API + Nginx 静态文件
```
### 环境变量
关键配置项:
| 变量 | 说明 | 默认值 |
|------|------|--------|
| `PORT` | 服务端口 | 3002 |
| `JWT_SECRET` | JWT 密钥(必填) | - |
| `CORS_ORIGINS` | 允许的跨域来源 | - |
| `RATE_LIMIT_*` | 速率限制配置 | 300/min |