chore: stop tracking docs/ (spec and plan are local-only artifacts)

This commit is contained in:
Tianyang 2026-08-01 09:20:18 +08:00
parent 9ef22f9f0a
commit a6b04c1538
3 changed files with 3 additions and 3762 deletions

3
.gitignore vendored
View File

@ -10,3 +10,6 @@ dist/
# Editor # Editor
.DS_Store .DS_Store
# Docs
docs/

File diff suppressed because it is too large Load Diff

View File

@ -1,153 +0,0 @@
# DocHub 设计文档
## 背景与目标
小团队10 人以下)需要一个基于 MinIO 的文档管理系统,支持:
- 浏览 MinIO 中存储的文档(主要是 Markdown / HTML图片为次要内容
- 全文内容检索(不只是文件名搜索)
- 在线编辑文档内容并保存
- 上传新文档
无需用户登录和权限管理(内部工具,信任团队内所有成员)。
## 技术栈
| 层 | 选型 | 理由 |
|----|------|------|
| 前端 | React + Vite + Monaco Editor | Monaco 提供代码级编辑体验(语法高亮、查找替换),适合 Markdown/HTML 源码编辑 |
| 后端 | Python + FastAPI | 团队熟悉度高,异步 IO 足够应对 MinIO/Meilisearch 网络调用瓶颈生态利于后续扩展文档解析、AI 摘要等) |
| 存储 | MinIO独立部署 | S3 兼容对象存储,文档内容和元数据(大小/时间/路径)都存在这里,不引入额外数据库 |
| 检索 | Meilisearch | 轻量、内置中文分词、MIT 协议、Docker 一条命令部署,检索延迟低 |
明确不引入的组件:
- 关系型数据库(内容和元数据用 MinIO 承载,索引用 Meilisearch 承载,当前需求下够用)
- 用户认证/权限系统(团队内部工具,暂不需要)
## 架构
```
┌─────────────┐
HTTPS │ nginx │
───────────▶ │ (反向代理) │
└──────┬──────┘
┌────────────┼────────────┐
▼ ▼ ▼
app.domain api.domain minio.domain(可选)
│ │
┌───────▼───────┐ ┌──▼──────────────┐
│ React 前端 │ │ FastAPI 后端 │
│ Vite + Monaco│ │ (Python) │
└───────────────┘ └───┬──────────┬───┘
│ │
S3 API │ │ REST API
▼ ▼
┌─────────────┐ ┌──────────────┐
│ MinIO │ │ Meilisearch │
│ (独立部署) │ │ (与后端同机) │
└─────────────┘ └──────────────┘
```
**部署形态**:两套独立的 docker-compose各自独立生命周期
- `minio/docker-compose.yml` — 仅 MinIO独立服务器或独立栈长期稳定运行可被其他项目复用
- `app/docker-compose.yml` — frontend + backend + meilisearch可整体重启/升级而不影响已存储的数据
两套 compose 之间通过共享 Docker 网络或宿主机 IP 通信(后端配置 MinIO endpoint 即可,代码不感知部署形态差异,因为走的是标准 S3 API
**域名与端口**:通过 nginx 反向代理 + 子域名区分服务,无需在域名上绑定端口:
```
app.domain → React 前端
api.domain → FastAPI 后端
minio.domain → MinIO 控制台(可选对外)
```
Meilisearch 仅供后端内网访问,不对外暴露子域名。
## 数据流
**上传文档**
```
前端上传文件 → 后端 PUT 到 MinIO
→ 后端解析内容Markdown/HTML 转纯文本)
→ 推送索引到 Meilisearch
→ 返回成功
```
**浏览文件列表**
```
前端请求文件树 → 后端调用 MinIO ListObjects → 返回文件夹/文件结构
```
**查看/编辑文档**
```
点击文件 → 后端从 MinIO GetObject 取内容 → 前端 Monaco Editor 加载展示
保存编辑 → 后端覆盖写入 MinIO → 同步更新 Meilisearch 索引
```
**全局搜索**
```
输入关键词 → 后端转发查询到 Meilisearch
→ 返回匹配文档(含高亮片段)
→ 前端展示结果列表,点击跳转到对应文档
```
**删除文档**
```
后端从 MinIO 删除对象 → 同步从 Meilisearch 删除对应索引
```
**关键决策:索引更新采用后端同步处理**,即写完 MinIO 后立即在同一请求中更新 Meilisearch 索引,不引入 MinIO webhook 异步机制。理由:团队规模小、写入量低,同步更新逻辑更简单、更容易保证一致性,避免维护额外的 webhook 消费者服务。
## 模块设计
### 前端React + Vite + Monaco Editor
| 组件 | 职责 |
|------|------|
| `FileExplorer` | 左侧文件树,展示文件夹/文件,支持点击导航 |
| `DocumentViewer/Editor` | 主区域,用 Monaco 加载文档内容,支持编辑与保存 |
| `SearchBar` | 顶部全局搜索框输入即查debounce |
| `SearchResults` | 搜索结果列表,展示高亮匹配片段,点击跳转对应文档 |
| `UploadButton` | 拖拽或选择文件上传 |
| `apiClient` | 封装对后端的 fetch 调用documents CRUD + search是前端与后端之间的唯一边界 |
### 后端FastAPI
API 层:
| 接口 | 方法 | 职责 |
|------|------|------|
| `/api/documents` | GET | 列出文件树(基于 MinIO ListObjects |
| `/api/documents/{key}` | GET | 读取单个文档内容 |
| `/api/documents/{key}` | PUT | 创建/覆盖文档(写 MinIO + 更新索引) |
| `/api/documents/{key}` | DELETE | 删除文档(删 MinIO + 删索引) |
| `/api/upload` | POST | 处理文件上传multipart |
| `/api/search` | GET | 转发查询到 Meilisearch返回结果 |
内部模块划分(各模块单一职责,可独立测试):
- `minio_client.py` — 封装 MinIO 操作list/get/put/delete只负责与 MinIO 交互,不含业务逻辑
- `search_client.py` — 封装 Meilisearch 操作index/update/delete/search只负责与 Meilisearch 交互
- `document_service.py` — 业务逻辑层,协调 `minio_client``search_client`(保存文档先写 MinIO 再更新索引;删除时顺序相反),并负责 Markdown/HTML 转纯文本供索引使用
- `routes/documents.py`、`routes/search.py` — API 路由层,只做参数校验和调用 service不直接触碰 MinIO/Meilisearch 客户端
依赖方向:`routes` → `document_service``minio_client` / `search_client`。上层不了解下层实现细节,替换 MinIO 为其他 S3 兼容存储或替换 Meilisearch 为其他搜索引擎时,只需改动对应的 client 模块。
## 错误处理
- MinIO 写入成功但索引更新失败:记录日志,不阻塞用户操作(文档已保存成功),后续可手动触发全量重建索引
- 请求的文档不存在:返回 404
- 上传文件类型/大小校验:在后端 `document_service` 层做校验(限制非文档类型或超大文件),拒绝时返回明确错误信息
## 测试策略
- 后端pytest 测试 `document_service` 业务逻辑mock `minio_client``search_client`,覆盖保存/删除时序、索引失败降级等场景
- 前端:暂不强制要求自动化测试覆盖(小型内部工具,手动验证优先级更高)
## 部署资源参考
学习/小团队场景下DocHub 各服务的大致资源占用(供部署规划参考,非强制要求):
- MinIO约 256-512MB 内存
- Meilisearch约 512MB-1GB 内存(随索引文档量增长)
- FastAPI 后端:约 256-512MB 内存
- React/nginx 前端:约 128-256MB 内存
4 核 / 4GB 内存足以运行 DocHub 全部服务;若与其他自建服务(如 Gitea、数据库共享同一台机器建议预留合计 8GB 以上内存。