diff --git a/CHANGELOG_DEPLOY.md b/CHANGELOG_DEPLOY.md index 000095f..494c0c9 100644 --- a/CHANGELOG_DEPLOY.md +++ b/CHANGELOG_DEPLOY.md @@ -1,6 +1,8 @@ # 部署配置更新日志 -## v1.0.1 (2024-12-23) +> ⚠️ 版本对齐:git 发布线当前为 v0.9.9(无 v1.0.x tag),下列 v1.0.1 为早期文案占位。详见 SDD `docs/sdd/releases/`。 + +## v1.0.1 (2024-12-23,遗留占位) ### 🔧 配置变更 diff --git a/DATABASE.md b/DATABASE.md index a178a5d..2e23167 100644 --- a/DATABASE.md +++ b/DATABASE.md @@ -336,6 +336,6 @@ CREATE TABLE `operation_logs` ( --- -**文档版本**: v1.0 +**文档版本**: v1.0(与代码版本 v0.9.9 的 git 基线无直接对应,见 SDD releases/) **最后更新**: 2023-12-20 **维护人**: Mula.liu diff --git a/DEPLOY.md b/DEPLOY.md index f82abc2..8baa571 100644 --- a/DEPLOY.md +++ b/DEPLOY.md @@ -316,7 +316,9 @@ find backend/logs -name "*.log" -mtime +30 -delete ## 📝 更新日志 -### v1.0.0 (2024-12-20) +> ⚠️ 版本对齐:git 发布线当前为 v0.9.9(无 v1.0.0 tag),下列 v1.0.0 为早期文案占位。详见 SDD `docs/sdd/releases/`。 + +### v1.0.0 (2024-12-20,遗留占位) - ✨ 完整的 Docker 部署方案 - ✨ 一键初始化和升级 - ✨ 数据库备份恢复 diff --git a/README.md b/README.md index b78763b..7383bb2 100644 --- a/README.md +++ b/README.md @@ -231,7 +231,9 @@ npm run dev ## 🔄 版本历史 -### v1.0.0 (2023-12-20) +> ⚠️ 版本对齐:git 发布线为 v0.9.1 → v0.9.2 → v0.9.6 → v0.9.7 → v0.9.8 → v0.9.9(当前基线,提交 `416ef48`),仓库未打 tag。下列 v1.0.0 为早期文案占位,与 git 不符;详见 SDD `docs/sdd/releases/`。 + +### v1.0.0 (2023-12-20,遗留占位,见上方对齐说明) - ✅ 完整的用户认证系统 - ✅ 项目管理功能 diff --git a/backend/app/core/config.py b/backend/app/core/config.py index 2e8ee13..6d39437 100644 --- a/backend/app/core/config.py +++ b/backend/app/core/config.py @@ -12,7 +12,7 @@ class Settings(BaseSettings): # 应用信息 APP_NAME: str = "NEX Docus" - APP_VERSION: str = "1.0.0" + APP_VERSION: str = "0.9.9" DEBUG: bool = True # 服务器配置 diff --git a/docs/DOCKER_DOCS_SETUP.md b/docs/DOCKER_DOCS_SETUP.md deleted file mode 100644 index bc6f660..0000000 --- a/docs/DOCKER_DOCS_SETUP.md +++ /dev/null @@ -1,370 +0,0 @@ -# 文档目录 Docker 部署方案 - -## 问题描述 - -应用中 `/design` 路由通过 `fetch('/docs/...')` 加载项目根目录下 `docs/` 文件夹中的 Markdown 文档。在 Docker 容器中运行时,需要确保这些文档能够被访问。 - -## 解决方案:Docker 卷挂载 - -采用 Docker 卷挂载方式,将宿主机的 `docs/` 目录直接映射到容器内,实现文档的实时更新和灵活管理。 - -### 配置方式 - -#### docker-compose.yml 配置 - -```yaml -version: '3.8' - -services: - nex-design: - build: - context: . - dockerfile: Dockerfile - volumes: - - ./logs:/app/logs # 日志目录挂载 - - ./docs:/app/dist/docs:ro # 文档目录挂载(只读) -``` - -**说明:** -- `./docs:/app/dist/docs` - 将宿主机当前目录的 `docs` 映射到容器的 `/app/dist/docs` -- `:ro` - 只读挂载,提高安全性,防止容器内进程修改文档 - -### 方案优势 - -✅ **实时更新** -- 修改 MD 文件后立即生效 -- 无需重新构建 Docker 镜像 -- 无需重启容器 - -✅ **方便维护** -- 在宿主机直接编辑文档 -- 使用熟悉的编辑器和工具 -- 支持版本控制 - -✅ **轻量镜像** -- Docker 镜像不包含文档内容 -- 镜像体积更小 -- 构建速度更快 - -✅ **灵活部署** -- 可以独立管理文档版本 -- 支持多环境部署(开发、测试、生产使用不同文档) -- 易于更新和回滚 - -### 目录结构 - -**宿主机:** -``` -nex-design/ -├── docs/ # 文档源文件(Git 管理) -│ ├── DESIGN_COOKBOOK.md -│ ├── components/ -│ │ ├── PageTitleBar.md -│ │ ├── ListTable.md -│ │ └── ... -│ └── pages/ -├── dist/ # 构建产物(容器内) -│ ├── index.html -│ └── assets/ -└── docker-compose.yml -``` - -**容器内:** -``` -/app/ -├── dist/ # 应用构建产物 -│ ├── index.html -│ ├── assets/ -│ └── docs/ # 挂载点 → 宿主机 docs/ -├── logs/ # 日志目录(挂载) -└── ecosystem.config.js # PM2 配置 -``` - -### 使用流程 - -#### 1. 启动服务 - -```bash -# 第一次启动(构建镜像) -docker-compose up -d --build - -# 后续启动(使用已有镜像) -docker-compose up -d -``` - -#### 2. 修改文档 - -```bash -# 在宿主机直接编辑文档 -vim docs/DESIGN_COOKBOOK.md - -# 或使用 VS Code 等编辑器 -code docs/components/PageTitleBar.md -``` - -#### 3. 验证更新 - -```bash -# 文档修改后立即生效,无需任何操作 -# 浏览器刷新即可看到最新内容 - -# 或使用 curl 验证 -curl http://localhost:3000/docs/DESIGN_COOKBOOK.md -``` - -### 验证挂载 - -```bash -# 检查容器内的挂载情况 -docker exec nex-design-app ls -la /app/dist/docs/ - -# 查看某个文档内容 -docker exec nex-design-app cat /app/dist/docs/DESIGN_COOKBOOK.md - -# 验证文件同步 -# 在宿主机修改文件 -echo "# Test" >> docs/test.md - -# 立即在容器内查看 -docker exec nex-design-app cat /app/dist/docs/test.md -``` - -### 部署注意事项 - -#### 1. 生产环境部署 - -**方式一:携带 docs 目录** -```bash -# 使用 git clone 或 scp 上传整个项目 -git clone /path/to/deploy -cd /path/to/deploy -docker-compose up -d -``` - -**方式二:单独管理文档** -```bash -# 文档单独部署在某个目录 -mkdir -p /var/www/nex-design-docs -# 上传文档到该目录 - -# 修改 docker-compose.yml -volumes: - - /var/www/nex-design-docs:/app/dist/docs:ro -``` - -#### 2. 权限管理 - -```bash -# 确保 docs 目录有正确的权限 -chmod -R 755 docs/ - -# 只读挂载可防止容器内修改,但宿主机权限仍需控制 -``` - -#### 3. 多环境配置 - -可以为不同环境创建不同的 docker-compose 文件: - -```bash -# docker-compose.dev.yml - 开发环境 -volumes: - - ./docs:/app/dist/docs:ro - -# docker-compose.prod.yml - 生产环境 -volumes: - - /var/www/docs:/app/dist/docs:ro -``` - -使用时指定配置文件: -```bash -docker-compose -f docker-compose.prod.yml up -d -``` - -### 故障排查 - -#### 问题 1:文档无法加载 - -```bash -# 检查挂载是否成功 -docker inspect nex-design-app | grep -A 10 Mounts - -# 检查容器内文件 -docker exec nex-design-app ls -la /app/dist/docs/ - -# 检查文件权限 -ls -la docs/ -``` - -#### 问题 2:修改后未生效 - -```bash -# 确认使用的是卷挂载而不是 COPY -docker exec nex-design-app cat /app/dist/docs/DESIGN_COOKBOOK.md - -# 检查浏览器缓存 -# 使用 Ctrl+Shift+R 强制刷新 - -# 检查 serve 是否缓存了静态文件 -docker-compose restart -``` - -#### 问题 3:Windows 路径问题 - -Windows 下需要注意路径格式: -```yaml -# 错误 -volumes: - - .\docs:/app/dist/docs:ro - -# 正确 -volumes: - - ./docs:/app/dist/docs:ro -``` - -### 性能考虑 - -#### 1. 卷挂载性能 - -- **Linux/macOS**: 性能很好,几乎无损耗 -- **Windows/macOS + Docker Desktop**: 可能有轻微性能损耗 -- **生产环境**: 使用 Linux 主机,性能最佳 - -#### 2. 优化建议 - -如果文档很多且访问频繁,可考虑: - -1. **使用命名卷**: -```yaml -volumes: - docs-data: - driver: local - driver_opts: - type: none - o: bind - device: /path/to/docs - -services: - nex-design: - volumes: - - docs-data:/app/dist/docs:ro -``` - -2. **缓存策略**: -在 Nginx 反向代理中添加缓存: -```nginx -location /docs/ { - proxy_pass http://nex_design; - proxy_cache_valid 200 10m; - add_header X-Cache-Status $upstream_cache_status; -} -``` - -## 替代方案对比 - -### 方案 A: 构建时复制(未采用) - -```dockerfile -# Dockerfile -COPY docs /app/dist/docs -``` - -❌ 缺点: -- 修改文档需要重新构建镜像 -- 镜像体积更大 -- 更新流程复杂 - -✅ 优点: -- 镜像自包含 -- 适合不常修改的场景 - -### 方案 B: prebuild 脚本(未采用) - -```json -{ - "scripts": { - "prebuild": "cp -r docs public/" - } -} -``` - -❌ 缺点: -- 需要重新构建才能更新 -- 增加构建时间 -- 文档和代码耦合 - -### 方案 C: 卷挂载(✅ 当前采用) - -```yaml -volumes: - - ./docs:/app/dist/docs:ro -``` - -✅ 优点: -- 实时更新 -- 灵活管理 -- 镜像轻量 - -⚠️ 注意: -- 需要保持 docs 目录结构 -- 部署时需要文档文件 - -## 最佳实践 - -### 1. 文档版本管理 - -```bash -# 使用 Git 管理文档版本 -cd docs -git log DESIGN_COOKBOOK.md - -# 回滚到特定版本 -git checkout DESIGN_COOKBOOK.md -``` - -### 2. 文档自动化部署 - -```bash -#!/bin/bash -# scripts/update-docs.sh - -echo "更新文档..." -cd /path/to/nex-design - -# 拉取最新文档 -git pull origin main -- docs/ - -# 无需重启容器,文档即时生效 -echo "文档已更新!" -``` - -### 3. 监控文档访问 - -可以在 Nginx 中记录文档访问日志: -```nginx -location /docs/ { - access_log /var/log/nginx/docs-access.log; - proxy_pass http://nex_design; -} -``` - -## 总结 - -使用 Docker 卷挂载方案是最灵活、最适合本项目的解决方案: - -✅ **实时更新** - 修改即生效 -✅ **简单维护** - 直接编辑文件 -✅ **轻量镜像** - 更快的构建和部署 -✅ **灵活部署** - 支持多种场景 - -**核心配置只需一行:** -```yaml -volumes: - - ./docs:/app/dist/docs:ro -``` - -## 相关文件 - -- `docker-compose.yml:16` - 卷挂载配置 -- `DEPLOYMENT.md:14-35` - 部署文档说明 -- `QUICKSTART.md` - 快速参考 - diff --git a/docs/MCP_HTTP_INTEGRATION.md b/docs/MCP_HTTP_INTEGRATION.md deleted file mode 100644 index f468ae5..0000000 --- a/docs/MCP_HTTP_INTEGRATION.md +++ /dev/null @@ -1,297 +0,0 @@ -# NexDocs MCP 使用文档 - -## 1. 方案说明 - -NexDocs 现在不再使用项目根目录下的独立 `mcp_server/`。 - -当前方案为后端内集成 MCP: - -- 业务 REST API 继续走 `/api/v1/...` -- MCP 入口挂载在同一个 backend 服务上 -- 传输协议为 `streamableHttp` -- MCP 地址为 `/mcp`(`/mcp/` 也兼容) -- 认证方式为 `X-Bot-Id` + `X-Bot-Secret` - -这意味着: - -- 不需要单独部署一套 MCP 服务 -- 不需要让 MCP client 传业务账号密码 -- 不需要让远程 agent 访问本地脚本进程 - - -## 2. 接口地址 - -MCP 对外地址: - -```text -http://:/mcp -``` - -例如: - -```text -http://backend.internal:8000/mcp -``` - -说明: - -- 推荐优先使用 `/mcp` -- `/mcp/` 也兼容 -- 如果前面还有 Nginx/网关,请不要对 `/mcp` 做 `301`/`302` 重定向 -- 未携带 bot 凭证时,访问 `/mcp` 或 `/mcp/` 都会返回 `401` - - -## 3. 认证模型 - -MCP client 只需要传两个 header: - -- `X-Bot-Id` -- `X-Bot-Secret` - -后端会执行以下逻辑: - -1. 根据 `X-Bot-Id` 查询 `mcp_bots` -2. 校验 `X-Bot-Secret` -3. 将该 bot 映射到 NexDocs 用户 -4. 以该用户身份执行 MCP 工具 - -因此 client 不需要再传: - -- NexDocs 用户名 -- NexDocs 密码 -- NexDocs access token - - -## 4. 用户如何获取凭证 - -每个用户可在个人中心管理自己的 MCP 凭证。 - -页面位置: - -1. 登录 NexDocs -2. 打开个人中心 -3. 进入 `MCP 接入` 标签页 - -可执行操作: - -- 查看 `X-Bot-Id` -- 查看并复制 `X-Bot-Secret` -- 重新生成 `X-Bot-Secret` - -后端接口: - -- `GET /api/v1/auth/mcp-credentials` -- `POST /api/v1/auth/mcp-credentials/rotate-secret` - - -## 5. 当前支持的 MCP Tools - -### 5.1 获取当前用户创建的项目列表 - -工具名: - -```text -list_created_projects -``` - -参数: - -- `keyword`: 可选,按项目名/描述过滤 -- `limit`: 可选,默认 100 - - -### 5.2 获取指定项目文件树 - -工具名: - -```text -get_project_tree -``` - -参数: - -- `project_id`: 必填 - - -### 5.3 获取指定文件内容 - -工具名: - -```text -get_file -``` - -参数: - -- `project_id`: 必填 -- `path`: 必填,项目内相对路径 - - -### 5.4 在项目中创建新文件 - -工具名: - -```text -create_file -``` - -参数: - -- `project_id`: 必填 -- `path`: 必填,项目内相对路径 -- `content`: 可选,文件初始内容,默认空字符串 - -说明: - -- 目标路径已存在时会报错 -- 会自动创建缺失的上级目录 -- 会校验项目写权限 -- 写入 Markdown 文件时会更新搜索索引 -- 会记录操作日志 -- 会通知项目成员 - - -### 5.5 修改指定文件 - -工具名: - -```text -update_file -``` - -参数: - -- `project_id`: 必填 -- `path`: 必填,项目内相对路径 -- `content`: 必填,新的文件内容 - -说明: - -- 目标文件不存在时会报错 -- 只允许更新文件,不允许更新目录 -- 会校验项目写权限 -- 写入 Markdown 文件时会更新搜索索引 -- 会记录操作日志 -- 会通知项目成员 - - -### 5.6 删除指定文件 - -工具名: - -```text -delete_file -``` - -参数: - -- `project_id`: 必填 -- `path`: 必填,项目内相对路径 - -说明: - -- 目标文件不存在时会报错 -- 只允许删除文件,不允许删除目录 -- 删除 Markdown 文件时会同步删除搜索索引 -- 会记录操作日志 -- 会通知项目成员 - - -## 6. 调用端配置示例 - -如果调用端内置的是 MCP client,并支持 `streamableHttp`,可以这样配置: - -```json -{ - "tools": { - "mcpServers": { - "biz_mcp": { - "type": "streamableHttp", - "url": "http://backend.internal:8000/mcp", - "headers": { - "X-Bot-Id": "nexbot_xxxxxxxxxxxxxxxx", - "X-Bot-Secret": "nxbotsec_xxxxxxxxxxxxxxxxxxxxxxxx" - }, - "toolTimeout": 60 - } - } - } -} -``` - -注意: - -- `url` 建议使用 `/mcp` -- `headers` 中不需要再放业务用户名密码 -- `X-Bot-Secret` 只应发给受信任的调用端 -- 如果客户端运行在浏览器环境,记得把对应站点加入后端 `CORS_ORIGINS` - - -## 7. 后端部署要求 - -### 7.1 Python 版本 - -后端运行环境需要 Python 3.12。 - -本地开发建议: - -```bash -cd backend -/opt/homebrew/bin/python3.12 -m venv venv312 -env -u HTTP_PROXY -u HTTPS_PROXY ./venv312/bin/pip install -r requirements.txt -./venv312/bin/uvicorn main:app --host 0.0.0.0 --port 8000 -``` - -说明: - -- 当前 backend 的 MCP 依赖要求 Python 3.10+ -- 本项目已在本地按 Python 3.12 调试通过 - - -### 7.2 Docker - -`backend/Dockerfile` 已切换到 Python 3.12 基线。 - - -### 7.3 数据表 - -`mcp_bots` 表需要存在。 - -如果你已经执行过建表脚本,这一步可以跳过。 - -相关文件: - -- [create_mcp_bots_table.sql](/Users/jiliu/工作/projects/NexDocus/backend/scripts/create_mcp_bots_table.sql) -- [init_database.sql](/Users/jiliu/工作/projects/NexDocus/backend/scripts/init_database.sql) - - -## 8. 已验证结果 - -本地调试已验证: - -- Python 3.12 环境可正常启动 backend -- `/health` 返回 `200` -- `/mcp` 与 `/mcp/` 均可访问 -- 未传 `X-Bot-Id` / `X-Bot-Secret` 时返回 `401` - -调试使用地址: - -```text -http://127.0.0.1:8012/mcp -``` - -生产或测试环境请替换为你的 backend 实际域名或 IP。 - - -## 9. 相关代码位置 - -- MCP 挂载入口: - [main.py](/Users/jiliu/工作/projects/NexDocus/backend/main.py) -- MCP 服务实现: - [server.py](/Users/jiliu/工作/projects/NexDocus/backend/app/mcp/server.py) -- MCP Bot 模型: - [mcp_bot.py](/Users/jiliu/工作/projects/NexDocus/backend/app/models/mcp_bot.py) -- 用户凭证管理接口: - [auth.py](/Users/jiliu/工作/projects/NexDocus/backend/app/api/v1/auth.py) -- 个人中心凭证管理页面: - [ProfilePage.jsx](/Users/jiliu/工作/projects/NexDocus/frontend/src/pages/Profile/ProfilePage.jsx) diff --git a/docs/MIGRATION.md b/docs/MIGRATION.md deleted file mode 100644 index 5300384..0000000 --- a/docs/MIGRATION.md +++ /dev/null @@ -1,61 +0,0 @@ -# 文档迁移说明 - -## 📦 按钮扩展组件文档已迁移 - -原 `docs/` 目录下的按钮扩展相关文档已整合并迁移至: - -**新位置:** `src/components/docs/ButtonExtensions.md` - ---- - -## 🗂️ 迁移的文档 - -以下文档已整合到新文档中: - -| 原文档 | 状态 | -|--------|------| -| ~~ButtonHelpDesign.md~~ | ✅ 已整合 | -| ~~ButtonDesignFixes.md~~ | ✅ 已整合 | -| ~~ButtonDesignUpdate.md~~ | ✅ 已整合 | -| ~~ButtonDesignLatestFixes.md~~ | ✅ 已整合 | -| ~~ActionHelpPanelFix.md~~ | ✅ 已整合 | - ---- - -## 📖 新文档包含 - -- ✅ 5种设计方案完整说明 -- ✅ 所有组件的API文档 -- ✅ 详细的使用指南和示例 -- ✅ 最佳实践和性能优化建议 -- ✅ 完整的更新日志和变更记录 - ---- - -## 🔗 快速链接 - -- **文档路径:** `/src/components/docs/ButtonExtensions.md` -- **在线演示:** http://localhost:5173/design/button-designs -- **菜单路径:** 组件设计 → 扩展按钮 - ---- - -## 📅 迁移时间 - -**2025-11-17** - 所有文档已完成整合 - ---- - -## 💡 文档组织原则 - -今后组件文档将遵循以下原则: - -1. **统一位置** - 所有组件文档放在 `src/components/docs/` -2. **就近原则** - 文档与组件代码保持近距离 -3. **单一文档** - 同一功能的文档整合到一个文件 -4. **版本控制** - 使用版本号和更新日志记录变更 - -这样可以: -- ✅ 更容易找到和维护文档 -- ✅ 避免文档分散和重复 -- ✅ 与代码保持同步更新 diff --git a/docs/UPGRADE_v0.9.6.md b/docs/UPGRADE_v0.9.6.md deleted file mode 100644 index 1fee7be..0000000 --- a/docs/UPGRADE_v0.9.6.md +++ /dev/null @@ -1,184 +0,0 @@ -# NexDocs v0.9.6 升级日志 - -## 版本信息 - -- 版本号:`v0.9.6` -- 更新时间:`2026-03-11` - - -## 本次升级摘要 - -`v0.9.6` 主要完成了以下升级: - -1. 新增后端内集成的 MCP Server 能力 -2. 新增用户级 MCP 凭证管理 -3. 打通通过 Nginx 统一入口访问 MCP -4. 调整部署运行环境到 Python 3.12 -5. 将 MySQL、Redis 数据目录改为项目根目录 `storage/` 持久化 -6. 优化个人中心与文档页面部分交互体验 - - -## 功能升级 - -### 1. MCP Server 内集成 - -系统已支持直接在 backend 中提供 MCP `streamableHttp` 服务,不再依赖项目根目录下的独立 `mcp_server/` 进程。 - -当前 MCP 入口: - -```text -/mcp -``` - -当前支持的工具: - -1. `list_created_projects`:列出当前用户的项目 -2. `get_project_tree`:列出项目文件树结构 -3. `get_file`:获取指定文件 -4. `create_file`:在项目中创建新文件 -5. `update_file`:修改指定文件 -6. `delete_file`:删除指定文件 - - -### 2. MCP 认证与用户凭证管理 - -新增基于 `X-Bot-Id` 和 `X-Bot-Secret` 的 MCP 认证模型。 - -能力包括: - -- 每个用户可拥有自己的 MCP 凭证 -- 通过数据库表 `mcp_bots` 维护 bot 与用户的映射 -- 支持在个人中心查看和重新生成凭证 -- 服务端自动按凭证映射到对应 NexDocs 用户身份执行工具 - -相关接口: - -- `GET /api/v1/auth/mcp-credentials` -- `POST /api/v1/auth/mcp-credentials/rotate-secret` - - -### 3. Nginx 统一入口支持 MCP - -前端 Nginx 已新增 `/mcp` 与 `/mcp/` 兼容的反向代理配置。 - -现在在只暴露一个公网入口端口的部署模式下,可以通过统一入口访问: - -```text -http(s):///mcp -``` - -不再要求调用端直连 backend 容器端口。 - - -## 前端与交互优化 - -### 1. 个人中心布局调整 - -个人中心由上下结构调整为左右结构: - -- 左侧为纵向导航 -- 右侧为内容区域 -- 移动端会自动回退为上下布局 - - -### 2. 文档浏览/编辑切换优化 - -本轮已对项目文档页做过一组交互统一: - -- 浏览/编辑模式切换样式统一 -- 页面头部高度与操作区对齐 -- 切换时保留当前文件上下文 -- 登录跳转回原目标页的逻辑补齐 - - -### 3. 认证异常提示优化 - -对未登录和 token 失效场景做了重复错误提示抑制: - -- 避免并发请求弹出多条重复 Toast -- 统一 401 处理与跳转逻辑 - - -## 部署与运行环境变更 - -### 1. Python 运行环境升级 - -backend 运行环境已调整为: - -```text -Python 3.12 -``` - -原因: - -- MCP Python SDK 需要 Python 3.10+ -- 当前版本已按 Python 3.12 完成调试与验证 - - -### 2. Docker 构建链调整 - -backend Docker 镜像构建已做以下处理: - -- 基础镜像切换为 `python:3.12-slim` -- 增加 pip 构建工具升级 -- pip 安装支持国内源失败后回退官方源 -- Nginx 已补充 `/mcp` 与 `/mcp/` 兼容代理配置 - - -### 3. 数据持久化目录调整 - -本次升级将 MySQL、Redis 的数据目录改为挂载到项目根目录下的 `storage/`: - -```text -storage/ -├── mysql/ -├── redis/ -├── projects/ -└── temp/ -``` - -当前挂载关系: - -- `storage/mysql -> /var/lib/mysql` -- `storage/redis -> /data` -- `storage -> /data/nex_docus_store` - -这样做的目的: - -- 宿主机可直接看到数据库与缓存数据目录 -- 便于整体备份 -- 避免数据只留在 Docker named volume 中 - - -## 升级迁移注意事项 - -### 1. MCP 调用地址调整 - -如果原先通过 backend 端口直连 MCP,可以继续使用。 - -如果当前部署是通过前端 Nginx 暴露统一入口,推荐改为: - -```text -http(s):///mcp -``` - -调用头保持不变: - -- `X-Bot-Id` -- `X-Bot-Secret` - - -### 部署与文档 - -- [docker-compose.yml](/Users/jiliu/工作/projects/NexDocus/docker-compose.yml) -- [MCP_HTTP_INTEGRATION.md](/Users/jiliu/工作/projects/NexDocus/docs/MCP_HTTP_INTEGRATION.md) - - -## 升级建议 - -建议升级到 `v0.9.6` 后按以下顺序验证: - -1. 验证 backend `/health` 是否正常 -2. 验证统一入口 `/api/`、`/mcp` 与 `/mcp/` 是否可访问 -3. 验证 MCP client 是否能正常完成 `initialize` -4. 验证个人中心的 MCP 凭证展示与轮换功能 diff --git a/docs/sdd/README.md b/docs/sdd/README.md new file mode 100644 index 0000000..ba4053a --- /dev/null +++ b/docs/sdd/README.md @@ -0,0 +1,79 @@ +# NEX Docus – 规格驱动开发(SDD)中心 + +本目录是 NEX Docus **规格驱动的开发中心**(Spec-Driven Development)。它把「产品意图 → 架构决策 → 功能规格 → 实施任务 → 验证证据」放进同一条可追踪链路,并作为团队讨论、开发与验收的**唯一真相源(single source of truth)**。 + +## 文档结构 + +```text +docs/sdd/ +├── README.md # 入口、状态与工作流(本文件) +├── governance.md # 编号、审批、变更与追踪规则 +├── archive.md # 遗留文档归档说明(整合/弃置追踪) +├── product/ +│ ├── vision.md # 产品愿景、用户与边界 +│ ├── principles.md # 产品与工程原则 +│ └── roadmap.md # 阶段性路线图 +├── architecture/ +│ ├── overview.md # 当前架构方向与系统边界 +│ ├── constraints.md # 已知约束与待决事项 +│ ├── standards/ +│ │ ├── README.md # 代码结构规范索引 +│ │ ├── code-structure-standards.md # 代码结构规范(整合自 docs/) +│ │ └── code-structure-audit-2026-04-08.md # 结构审计记录(整合自 docs/) +│ └── decisions/ +│ ├── README.md # ADR 索引与规则 +│ └── ADR-0001-*.md # 持久架构决策(逐条一文件) +├── integrations/ +│ ├── mcp.md # MCP Streamable HTTP 接入(含详细使用文档) +│ └── git.md # 项目 Git 仓库集成 +├── releases/ +│ ├── README.md # 公开版本与资产索引 +│ ├── v0.9.6.md # v0.9.6 历史升级记录(整合自 docs/) +│ └── v0.9.9.md # 当前基线发布(对齐 git) +└── specs/ + ├── README.md # 功能规格索引 + ├── _template/ # 新规格模板 + └── DV-NNNN-short-name/ # 一个功能或变更单元(spec/design/tasks/verification) +``` + +## 当前状态(Status) + +- **SDD 文档状态**:基线(Baseline)· 对齐 git 当前版本 v0.9.9 +- **适用代码基线**:当前仓库(backend + frontend + docker-compose 部署) +- **规格覆盖**:11 个功能单元(DV-0001 ~ DV-0011);价值主张 PO-1~5;架构决策 ADR-0001~0008 +- **已知整改项**:见 governance「开放问题」与各规格 tasks.md 中的“待整改/待决”标记(如敏感日志脱敏 TS-12、Compose v2 官方化 TS-13) +- **版本基线**:以 git 为准(当前 v0.9.9;见 releases/README.md 与 v0.9.9.md 版本对齐说明;代码字段 1.0.0 为遗留占位) + +## 如何使用本中心(工作流) + +### 读者 +| 角色 | 入口 | +| --- | --- | +| 产品/方案 | `product/vision.md`、`product/roadmap.md` | +| 架构评审 | `architecture/overview.md`、`architecture/standards/README.md`、`architecture/decisions/README.md` | +| 功能负责人 | `specs/README.md` → 对应 `DV-NNNN/spec.md` | +| 开发 | `DV-NNNN/design.md` + `tasks.md` | +| 测试/验收 | `DV-NNNN/verification.md` | +| 发布 | `releases/README.md` | +| 遗留文档去向 | `archive.md` | + +### 作者(新增/改功能) +1. 在 `governance.md` 读取编号规则,申请下一个规格编号(DV-NNNN)与 ADR 编号。 +2. 复制 `specs/_template/` 到 `specs/DV-NNNN-short-name/`,先写 `spec.md`(为什么、做什么)。 +3. 评审通过后写 `design.md`;实现过程中维护 `tasks.md` 勾选切片。 +4. 完成后在 `verification.md` 登记验收证据,并回填 `specs/README.md` 索引。 +5. 涉及跨文件刚性承诺(ADR)变更的,走 `architecture/decisions` 审批。 + +### 最小变更(bug 修复) +- 若属于既有 DV 规格范围:直接在该单元 `tasks.md` 追加切片并更新 `verification.md`。 +- 若超出所有现有范围:新建 DV 规格。 + +## 与外部文档的关系 + +SDD 中心**汇总并指向**仓库既有的详细材料,而非重复复制全部内容: +- 数据库细节 → 仓库根 `DATABASE.md`(SDD 只保留 ER 概览与规格化的链路表) +- 部署运维 → `DEPLOY.md`、`README_DOCKER.md`、`CHANGELOG_DEPLOY.md`(及已并入的 docs/DOCKER_DOCS_SETUP 历史,见 archive.md) +- 历史变更 → `docs/UPGRADE_v0.9.6.md`、`docs/MIGRATION.md`(已整合/弃置,见 archive.md) +- 结构规范 → `architecture/standards/`(原 docs/code-structure-* 已迁入) + +> 本中心是入口与追踪层;具体逐表 DDL、逐配置项说明等细节仍以被指向的源文档为准。 diff --git a/docs/sdd/architecture/constraints.md b/docs/sdd/architecture/constraints.md new file mode 100644 index 0000000..447ce7e --- /dev/null +++ b/docs/sdd/architecture/constraints.md @@ -0,0 +1,30 @@ +# 约束与待决事项(Constraints & Open Points) + +## 技术约束(当前代码库既定) +1. **Python 3.12 + FastAPI 0.109**:异步栈;`requirements.txt` 固定大部分版本。 +2. **SQLAlchemy 2.0(async)+ aiomysql**;同步连接供 Alembic 风格脚本(pymysql)。 +3. **MySQL 5.7.5+ / 生产镜像 MySQL 8.0**,utf8mb4。 +4. **Redis**:Token 缓存、会话状态、通知等。 +5. **JWT**(python-jose HS256)+ **bcrypt**(passlib)。 +6. **前端 React 18 + Vite 5 + Ant Design 5 + Tailwind + Zustand**;路由 React Router v6。 +7. **Whoosh3**(全文)+ **ZVec**(向量)+ **jieba**(中文分词)。 +8. **WeasyPrint**(PDF 导出)、**pdfjs-dist/react-pdf**(前端 PDF 预览)、**react-virtuoso/react-window**(虚拟列表)。 +9. **部署**:Docker Compose v2 + Engine ≥ 25(ADR-0008)。 + +## 约束来源 +- 依赖锁定:`backend/requirements.txt`、`frontend/package.json`。 +- 配置默认:`backend/app/core/config.py`、`.env.example`、`docker-compose.yml`。 + +## 待决事项(Open Points) +| 编号 | 事项 | 现状 | 建议 | +| --- | --- | --- | --- | +| OP-1 | Alembic vs 幂等 ALTER | 采用幂等 ALTER(`migrations.py`) | 评估引入 Alembic 以支撑大规模结构变更 | +| OP-2 | 敏感日志 | `security.py`/`deps.py` 记录 SECRET_KEY 前缀/JWT 载荷 | 脱敏,见 OI-1 | +| OP-3 | Compose v2 官方化 | deploy.sh 探测 v2 但根文档仍提及 v1 | 统一 v2 路径,见 OI-2 | +| OP-4 | 测试覆盖 | 仅 3 个后端单测 | 增加集成/E2E,见 OI-3 | +| OP-5 | 实时协同编辑 | 明确不在此版本做(vision 边界) | 另立项评估 OT/CRDT | +| OP-6 | 多实例/高可用 | 单机部署,无状态服务仅后端(Redis/DB 独立) | 若需要再评估 | + +## 约束的规格化引用 +- 以上条目若成为刚性承诺,须固化为 ADR 并登记到 `decisions/README.md`。 + diff --git a/docs/sdd/architecture/decisions/ADR-0001-hybrid-storage.md b/docs/sdd/architecture/decisions/ADR-0001-hybrid-storage.md new file mode 100644 index 0000000..2d19899 --- /dev/null +++ b/docs/sdd/architecture/decisions/ADR-0001-hybrid-storage.md @@ -0,0 +1,18 @@ +# ADR-0001:混合架构「DB 权限 + FS 内容」 + +- **状态**:Accepted +- **日期**:对应仓库基线 + +## 背景 +需要平衡权限管理的可控性与内容数据的可迁移/透明性。 + +## 决策 +结构化元数据(用户/项目/权限/菜单/日志/向量状态等)存 MySQL;文档内容、图片、附件以原生文件存于服务器磁盘(`STORAGE_ROOT` 下 `projects/`)。 + +## 后果 +- 正向:文件即真理,备份/迁移只需拷贝目录 + 导出 DB。 +- 代价:需要自行实现严格的路径安全校验(见 DV-0002 / NFR-3)。 + +## 关联 +PO-1, PO-2, PO-3;DV-0002;NFR-3。 + diff --git a/docs/sdd/architecture/decisions/ADR-0002-uuid-storage-key.md b/docs/sdd/architecture/decisions/ADR-0002-uuid-storage-key.md new file mode 100644 index 0000000..8b89aeb --- /dev/null +++ b/docs/sdd/architecture/decisions/ADR-0002-uuid-storage-key.md @@ -0,0 +1,17 @@ +# ADR-0002:磁盘目录用 UUID(storage_key)映射 + +- **状态**:Accepted + +## 背景 +中文文件名、重名项目在文件系统层面易出乱码与冲突。 + +## 决策 +磁盘文件夹名使用 `storage_key`(UUID,36 字符),数据库 `projects.storage_key` 保存映射;对外展示名 `projects.name` 与磁盘名解耦。 + +## 后果 +- 展示名可随时改,磁盘标识不变。 +- 资源路径以 uuid 为根,天然隔离且无中文。 + +## 关联 +DV-0002。 + diff --git a/docs/sdd/architecture/decisions/ADR-0003-tech-stack.md b/docs/sdd/architecture/decisions/ADR-0003-tech-stack.md new file mode 100644 index 0000000..e636794 --- /dev/null +++ b/docs/sdd/architecture/decisions/ADR-0003-tech-stack.md @@ -0,0 +1,15 @@ +# ADR-0003:技术栈选型 + +- **状态**:Accepted + +## 决策 +- **后端**:Python 3.12 + FastAPI(异步)+ SQLAlchemy 2.0(async)+ aiomysql/PyMySQL + Redis(aioredis)+ JWT(python-jose/bcrypt)+ Uvicorn。 +- **前端**:React 18 + Vite 5 + Ant Design 5 + Tailwind + Zustand + React Router v6;Markdown bytemd;PDF pdfjs-dist/react-pdf;虚拟列表 react-virtuoso/react-window。 +- **搜索/向量**:Whoosh3 + jieba(全文);ZVec + 可配置 embedding(语义)。 + +## 后果 +依赖锁定在 `requirements.txt` 与 `package.json`;更换组件须评审。 + +## 关联 +全部 DV。 + diff --git a/docs/sdd/architecture/decisions/ADR-0004-dual-search-engine.md b/docs/sdd/architecture/decisions/ADR-0004-dual-search-engine.md new file mode 100644 index 0000000..223cb03 --- /dev/null +++ b/docs/sdd/architecture/decisions/ADR-0004-dual-search-engine.md @@ -0,0 +1,18 @@ +# ADR-0004:全文(Whoosh)+ 语义(ZVec)双检索引擎 + +- **状态**:Accepted + +## 背景 +既需要全文关键词检索,又需要语义向量检索支撑 RAG。 + +## 决策 +1. 全文检索:Whoosh3 本地索引(`search_index`),中文自定义 `ChineseAnalyzer`(基于 jieba)。 +2. 语义向量:ZVec 本地向量库(`vector_index`,每项目一个 collection)+ 可配置 embedding 模型(LLMModelConfig 的 `model_type=embedding`)。 + +## 后果 +- 两套索引需在文件变更时同步维护(ADR-0006)。 +- 向量维度变更时需重建 collection 并全量重向量化。 + +## 关联 +DV-0005, DV-0006, DV-0007。 + diff --git a/docs/sdd/architecture/decisions/ADR-0005-rag-citations.md b/docs/sdd/architecture/decisions/ADR-0005-rag-citations.md new file mode 100644 index 0000000..ec2425a --- /dev/null +++ b/docs/sdd/architecture/decisions/ADR-0005-rag-citations.md @@ -0,0 +1,15 @@ +# ADR-0005:RAG 答案可溯源(编号引用 + 支撑句对齐) + +- **状态**:Accepted + +## 决策 +- 每条知识使用必须紧跟 `[n]` 编号引用。 +- 采用“答案论断句 ↔ 原文候选句”向量对齐(`align_citation_quotes`),为每次 `[n]` 出现回填支撑句(`quote_occurrences`)。 +- 同文件多个分块命中在展示层合并为同一 `citation_id` 并重新编号(`_canonicalize_message_citations`)。 + +## 后果 +- 提升可验证性,但依赖 embedding 可用;对齐失败时降级为不返回支撑句(NFR-10)。 + +## 关联 +DV-0007, DV-0011。 + diff --git a/docs/sdd/architecture/decisions/ADR-0006-async-index-sync.md b/docs/sdd/architecture/decisions/ADR-0006-async-index-sync.md new file mode 100644 index 0000000..ea39b6d --- /dev/null +++ b/docs/sdd/architecture/decisions/ADR-0006-async-index-sync.md @@ -0,0 +1,17 @@ +# ADR-0006:写路径异步索引同步 + +- **状态**:Accepted + +## 背景 +文件变更(创建/修改/删除/移动)需同步维护向量索引与全文索引,但不能阻塞主请求线程。 + +## 决策 +文件操作经 `ProjectFileService` → `FileVectorSyncService`(独立 DB 会话、按项目串行、后台 `asyncio.Task`)触发 ZVec 重向量化/删除;全文索引经 `search_service` 同步更新。整项目向量化走 `ProjectVectorizationTaskService`(后台任务 + 进度表)。 + +## 后果 +- 写请求返回快,索引最终一致。 +- 需处理并发同一项目的串行化与任务去重。 + +## 关联 +DV-0002, DV-0006, DV-0010。 + diff --git a/docs/sdd/architecture/decisions/ADR-0007-idempotent-migrations.md b/docs/sdd/architecture/decisions/ADR-0007-idempotent-migrations.md new file mode 100644 index 0000000..9646faa --- /dev/null +++ b/docs/sdd/architecture/decisions/ADR-0007-idempotent-migrations.md @@ -0,0 +1,17 @@ +# ADR-0007:轻量幂等数据库迁移(非破坏性) + +- **状态**:Accepted + +## 背景 +项目未引入 Alembic 可执行迁移链。 + +## 决策 +启动时(lifespan)执行 `migrate_schema()`:查询 `information_schema` 判断列是否存在,仅对缺失列执行幂等 `ALTER TABLE`。只做“新增列”这类非破坏性变更。 + +## 后果 +- 多实例/重复启动安全。 +- 大规模结构变更缺少回放/回滚(见 OP-1 / OI-4)。 + +## 关联 +DV-0010, NFR-7。 + diff --git a/docs/sdd/architecture/decisions/ADR-0008-compose-v2.md b/docs/sdd/architecture/decisions/ADR-0008-compose-v2.md new file mode 100644 index 0000000..ea20b9a --- /dev/null +++ b/docs/sdd/architecture/decisions/ADR-0008-compose-v2.md @@ -0,0 +1,15 @@ +# ADR-0008:部署仅支持 Docker Compose v2 + Engine ≥ 25 + +- **状态**:Accepted +- **触发背景**:服务器上旧版 docker-compose v1(Python 实现)在 Docker Engine 25+ 上因读取 `ContainerConfig` 字段崩溃(`KeyError: 'ContainerConfig'`)。 + +## 决策 +仅支持 **Docker Compose v2**(`docker compose` 子命令)部署;弃用 v1。`deploy.sh` 中 `get_compose_cmd` 优先探测 v2,回退 v1 仅作兼容提示。 + +## 后果 +- 升级路径:安装 `docker-compose-plugin`(v2)并卸载 v1 后即可用 `./deploy.sh upgrade` 或 `docker compose up -d --build`。 +- `docker-compose.yml` 顶部 `version:` 仅产生弃用警告,不影响功能。 + +## 关联 +NFR-6, OI-2;部署细节见 `DEPLOY.md`、`README_DOCKER.md`。 + diff --git a/docs/sdd/architecture/decisions/README.md b/docs/sdd/architecture/decisions/README.md new file mode 100644 index 0000000..34e2a84 --- /dev/null +++ b/docs/sdd/architecture/decisions/README.md @@ -0,0 +1,23 @@ +# ADR 索引与规则(Architecture Decision Records) + +## 规则 +- 每个持久架构决策一个文件:`ADR-NNNN-简短名称.md`。 +- 内容固定:**背景 / 决策 / 后果 / 状态 / 关联规格**。 +- 状态:`Proposed → Accepted → Deprecated / Superseded by ADR-NNNN`。 +- 变更已 Accepted 的 ADR 须走 governance 审批矩阵。 + +## 索引 + +| ADR | 标题 | 状态 | 关联规格 | +| --- | --- | --- | --- | +| [ADR-0001](ADR-0001-hybrid-storage.md) | 混合架构:DB 权限 + FS 内容 | Accepted | PO-1/2/3, DV-0002 | +| [ADR-0002](ADR-0002-uuid-storage-key.md) | 磁盘目录用 UUID(storage_key)映射 | Accepted | DV-0002 | +| [ADR-0003](ADR-0003-tech-stack.md) | 技术栈选型(FastAPI/React/SQLAlchemy/Redis/JWT) | Accepted | 全部 DV | +| [ADR-0004](ADR-0004-dual-search-engine.md) | 全文(Whoosh)+ 语义(ZVec)双检索引擎 | Accepted | DV-0005/0006/0007 | +| [ADR-0005](ADR-0005-rag-citations.md) | RAG 答案可溯源:编号引用 + 支撑句对齐 | Accepted | DV-0007/0011 | +| [ADR-0006](ADR-0006-async-index-sync.md) | 写路径异步索引同步(后台任务) | Accepted | DV-0002/0006/0010 | +| [ADR-0007](ADR-0007-idempotent-migrations.md) | 轻量幂等数据库迁移(非 Alembic) | Accepted | DV-0010, NFR-7 | +| [ADR-0008](ADR-0008-compose-v2.md) | 部署仅支持 Docker Compose v2 + Engine ≥ 25 | Accepted | NFR-6, DV-0000(部署) | + +> 注:DV-0000 为「部署/环境」逻辑单元,对应 NFR-6/ADR-0008,不生成独立功能规格文件,仅作追踪占位。 + diff --git a/docs/sdd/architecture/overview.md b/docs/sdd/architecture/overview.md new file mode 100644 index 0000000..91b0ddc --- /dev/null +++ b/docs/sdd/architecture/overview.md @@ -0,0 +1,42 @@ +# 架构概览(Overview) + +## 系统定位 + +NEX Docus 是**单机可部署**的团队文档平台,后端 FastAPI 单体 + 前端 React SPA + MySQL + Redis + 本地文件系统 + 本地检索/向量引擎,全部由 docker-compose 编排为同网段容器。 + +## 逻辑架构 + +```mermaid +graph TD + Client[React SPA] -->|JSON/HTTP| API[FastAPI Backend :8000] + Agent[External Agent] -->|MCP streamableHttp| API + API --> DB[(MySQL)] + API --> RD[(Redis)] + API --> FS[文件系统 STORAGE_ROOT/projects/] + API --> WH[Whoosh 全文索引 search_index] + API --> ZV[ZVec 向量库 vector_index/] + API --> LLM[LLM Provider: chat/embedding] + FS -->|变更同步| SVC[FileVectorSyncService → ZVec / SearchService] +``` + +## 三层结构(物理/逻辑/应用映射) + +| 层 | 载体 | 说明 | +| --- | --- | --- | +| 应用层 | FastAPI(/api/v1 + /mcp)+ React SPA | 业务 API 与前端 | +| 数据层 | MySQL(元数据/权限/状态)、Redis(Token/会话)、文件系统(内容)、Whoosh/ZVec(索引) | 结构化 vs 非结构化分离 | +| 基础设施 | docker-compose(backend/frontend/mysql/redis)、nginx(frontend 内) | 容器化部署 | + +## 关键子系统 +1. **认证**:JWT Bearer + Redis Token 缓存双校验(见 DV-0001)。 +2. **权限**:RBAC(roles/system_menus/role_menus)+ 项目级角色(admin/editor/viewer)双维度(DV-0002/0004)。 +3. **文件系统**:`StorageService` 统一封装,含路径安全校验(DV-0002)。 +4. **检索**:Whoosh 全文(DV-0005)+ ZVec 语义(DV-0006)双引擎,写路径后台同步(ADR-08)。 +5. **知识库**:RAG 检索 + LLM 生成 + 引用支撑句对齐(DV-0007)。 +6. **开放**:MCP Streamable HTTP(/mcp),bot 凭据映射到用户(DV-0011)。 + +## 系统边界 +- 进程内单后端:REST 与 MCP 同挂一个 service。 +- 存储边界:内容永不进 DB BLOB;DB 只存元数据。 +- 网络边界:前端经 nginx 反代 /api,可同域免跨域;/mcp 不可 301/302 重定向(MCP 客户端要求)。 + diff --git a/docs/sdd/architecture/standards/README.md b/docs/sdd/architecture/standards/README.md new file mode 100644 index 0000000..537ca97 --- /dev/null +++ b/docs/sdd/architecture/standards/README.md @@ -0,0 +1,10 @@ +# 代码结构规范(Standards) + +本目录整合了仓库既有的**代码结构设计规范**与其落地审计记录。 + +| 文件 | 类型 | 说明 | +| --- | --- | --- | +| [code-structure-standards.md](code-structure-standards.md) | 规范(强制执行) | 通用代码结构边界、分层模型、前端/后端/CLI 规范、审计清单 | +| [code-structure-audit-2026-04-08.md](code-structure-audit-2026-04-08.md) | 审计记录 | 2026-04-08 前后端结构审计与已落地优化项 | + +> 来源:原 `docs/code-structure-standards.md`、`docs/code-structure-audit-2026-04-08.md`,于 SDD 整合时迁入。 diff --git a/docs/code-structure-audit-2026-04-08.md b/docs/sdd/architecture/standards/code-structure-audit-2026-04-08.md similarity index 100% rename from docs/code-structure-audit-2026-04-08.md rename to docs/sdd/architecture/standards/code-structure-audit-2026-04-08.md diff --git a/docs/code-structure-standards.md b/docs/sdd/architecture/standards/code-structure-standards.md similarity index 100% rename from docs/code-structure-standards.md rename to docs/sdd/architecture/standards/code-structure-standards.md diff --git a/docs/sdd/archive.md b/docs/sdd/archive.md new file mode 100644 index 0000000..c93c953 --- /dev/null +++ b/docs/sdd/archive.md @@ -0,0 +1,33 @@ +# 遗留文档归档说明(Archive / Disposition) + +> 本文件记录项目根目录 `docs/` 下**遗留文档的处置结果**,作为整合与删除的追踪依据。原文件删除后,此文件保留其去向,保证可追溯。 + +## 处置汇总 + +| 原文件 | 评估 | 处置 | 落点 | +| --- | --- | --- | --- | +| `docs/code-structure-standards.md` | 现行、长期有效的工程规范 | **整合**(全量保留) | `architecture/standards/code-structure-standards.md` | +| `docs/code-structure-audit-2026-04-08.md` | 历史审计记录,有参考价值 | **整合**(全量保留) | `architecture/standards/code-structure-audit-2026-04-08.md` | +| `docs/MCP_HTTP_INTEGRATION.md` | 现行 MCP 使用文档,内容详实 | **合并**(内容并入,超集) | `integrations/mcp.md` | +| `docs/UPGRADE_v0.9.6.md` | 历史发布记录(多已吸收为基线) | **整合**为发布记录 | `releases/v0.9.6.md` | +| `docs/MIGRATION.md` | **过时**:指向已不存在的按钮文档/`/design` 路由 | **弃置**(归档说明,不保留实质内容) | 本文件 | +| `docs/DOCKER_DOCS_SETUP.md` | **过时**:`/design` 文档功能已不在代码中,当前 compose 无 `./docs` 挂载 | **弃置**(归档说明,不保留实质内容) | 本文件 | + +## 弃置内容说明 + +### `docs/MIGRATION.md`(弃置) +该文档描述「按钮扩展组件文档整合方案」,指向 `src/components/docs/ButtonExtensions.md` 与 `/design/button-designs` 路由。经核查: +- `frontend/src` 中无对应消费者,`docsMenuData.json` 引用的 `/docs/*.md` 文件在仓库中不存在; +- `/design` 相关文档功能已不在当前代码中; +- 故判定为**过时遗留**,实质内容不再保留。 + +### `docs/DOCKER_DOCS_SETUP.md`(弃置) +该文档描述「将 `./docs` 卷挂载到容器 `/app/dist/docs` 以服务设计文档」。经核查: +- 当前 `docker-compose.yml` 仅挂载 `./storage`、`./backend/logs`(及 mysql/redis storage);**无 `./docs` 挂载**; +- `/docs/*.md` 设计文档文件与消费方在当前仓库中不存在; +- 涉及的 `nex-design`、`/design`、PM2/ecosystem 等描述与当前项目结构不符; +- 故判定为**过时遗留**,实质内容不再保留。 + +## 相关提示 +- 若未来重新引入「程序内文档中心」能力,须先在 SDD 登记规格(DV/FR),再落地,避免再次产生无人消费的遗留文档。 +- 敏感内容(如默认口令、历史地址)仅保留在相应发布/部署文档的历史上下文中,不鼓励据此推断现状。 diff --git a/docs/sdd/governance.md b/docs/sdd/governance.md new file mode 100644 index 0000000..527488e --- /dev/null +++ b/docs/sdd/governance.md @@ -0,0 +1,72 @@ +# SDD 治理规则(Governance) + +本文件定义 NEX Docus SDD 中心的**编号、审批、变更与追踪**规则,保证「产品意图 → 架构决策 → 功能规格 → 实施任务 → 验证证据」始终处于同一条可追踪链路。 + +## 1. 编号体系 + +| 前缀 | 含义 | 格式 | 范围 | +| --- | --- | --- | --- | +| PO | Product Outcome(价值主张) | PO-N | 稳态常量,变更需评审 | +| ADR | Architecture Decision Record | ADR-NNNN | 持久架构决策,一决策一文件 | +| NFR | Non-Functional Requirement | NFR-N | 非功能需求,依附规格 | +| FR | Functional Requirement | FR-N | 功能需求,依附 DV 规格 | +| DV | Delivered Value(功能/变更单元) | DV-NNNN-shot-name | 一个功能或变更单元 | +| TS | Task(实施切片) | TS-N | 实施任务,从属于 DV | +| VER | Verification(验证证据) | VER-N | 验收证据,从属于 DV | + +编号由 sdd 维护人统一分配;申请人不得自行占用 DV/ADR 编号。 + +## 2. 文档生命周期 + +```text +草稿(Draft) → 评审(Review) → 批准(Approved) → 已实现(Implemented) → 已验收(Verified) → 归档(Archived) +``` + +- **Draft**:spec.md 初稿,仅供讨论。 +- **Review**:进入评审;架构影响大的须同时评审 ADR。 +- **Approved**:批准为规格基线,可据此实现。 +- **Implemented**:tasks.md 所有切片完成。 +- **Verified**:verification.md 证据齐全且通过。 +- **Archived**:功能下线/重构,移入归档,不再作为基线。 + +## 3. 审批矩阵 + +| 变更类型 | 需审批方 | 说明 | +| --- | --- | --- | +| 新增/修改 PO | 产品负责人 | 价值主张变化 | +| 新增/修改 ADR | 架构负责人 + 技术负责人 | 跨文件刚性承诺 | +| 新增 DV 规格 | 功能负责人 + 架构评审(涉架构时) | 新功能入口 | +| 修改已批准 spec/design | 相应 DV 负责人 | 变更影响追踪 | +| 只改 tasks/verification | DV 负责人 | 实施与验收细节 | +| 发布 | 发布负责人 | 见 releases/ | + +## 4. 追踪规则(Traceability) + +- **强制反向可追踪**:每一条实施切片(TS)必须引用一个或多个规格(FR/ADR/NFR);每一条验收证据(VER)必须引用其证明的规格与任务。 +- **双向矩阵**:`specs/README.md` 维护「规格 ↔ 任务 ↔ 证据」索引;`architecture/decisions/README.md` 维护「ADR ↔ 规格」映射。 +- **变更即更新**:任何 spec/design 改动或布局改动,须同步更新关联的 tasks 与 verification,保持链路不断签。 +- **孤儿项处理**:新增代码若无规格/任务支撑,属「未登记变更」,应在当次 SDD 评审中补登记或回滚。 + +## 5. 变更工作流 + +1. 在本中心提出变更(写明受影响 DV/ADR/NFR)。 +2. 按审批矩阵过审。 +3. 更新对应 spec/design/tasks/verification。 +4. 回填索引(specs/README、decisions/README)。 +5. 若变更跨越发布边界,登记到 releases/。 + +## 6. 当前开放问题(Open Items) + +| 编号 | 类型 | 内容 | 关联 | 状态 | +| --- | --- | --- | --- | --- | +| OI-1 | 安全 | `security.py`/`deps.py` 存在 SECRET_KEY 前缀、JWT 载荷、token 前缀等敏感日志,需脱敏 | NFR-9, DV-0001/TS-12 | 待整改 | +| OI-2 | 部署 | 统一官方化 Docker Compose v2 部署路径(升级 compose-plugin、移除外层 v1 工具链依赖/说明) | NFR-6, ADR-0008 | 待整改 | +| OI-3 | 测试 | 后端测试仅覆盖引用/模型配置/检索三处,缺集成与 E2E 测试 | DV-* verification | 待增强 | +| OI-4 | 迁移 | 未引入 Alembic,迁移依赖幂等 ALTER;大规模结构变更缺少回放/回滚机制 | ADR-000?(见 ADR-07) | 已记录,待评估 | + +## 7. 维护约定 + +- 本目录变更遵循「小步提交」:一次合并只动一个逻辑单元。 +- 每个新建 DV 单元必须包含完整的四文件(spec/design/tasks/verification),缺一不可。 +- 每次功能合并,默认要求补齐对应 verification 证据或明确标注“将由 OI-3 覆盖”。 + diff --git a/docs/sdd/integrations/git.md b/docs/sdd/integrations/git.md new file mode 100644 index 0000000..a1711fd --- /dev/null +++ b/docs/sdd/integrations/git.md @@ -0,0 +1,18 @@ +# 集成:项目 Git 仓库(DV-0010 支撑) + +## 能力 +- 项目可绑定 Git 仓库(`project_git_repos`:name、repo_url、branch、username、token、is_default)。 +- 支持 `git pull` / `git push`。 + +## 接口 +- `GET/POST /api/v1/projects/{id}/git-repos` +- `PUT/DELETE /api/v1/projects/{id}/git-repos/{repo_id}` +- `POST /api/v1/projects/{id}/git/pull` +- `POST /api/v1/projects/{id}/git/push` + +## 安全 +- 凭据(token/密码)以字段存储于 `project_git_repos.token`;注意避免日志泄露(关联 OI-1/NFR-9 敏感信息治理)。 + +## 关联 +DV-0010, ADR-0006(文件系统与外部仓库的边界:分享/同步策略见具体实现)。 + diff --git a/docs/sdd/integrations/mcp.md b/docs/sdd/integrations/mcp.md new file mode 100644 index 0000000..134a16d --- /dev/null +++ b/docs/sdd/integrations/mcp.md @@ -0,0 +1,121 @@ +# 集成:MCP Streamable HTTP(DV-0011 支撑) + +> 本页为 MCP 接入的规格化工作说明,**整合自原 `docs/MCP_HTTP_INTEGRATION.md`(已并入)** 与 DV-0011 规格。实现代码:`backend/app/mcp/server.py`、`backend/app/mcp/context.py`、`backend/app/models/mcp_bot.py`。 + +## 1. 方案说明(决策摘要) + +- 不再使用项目根目录独立 `mcp_server/`;改为**后端内集成**。 +- 业务 REST API 继续走 `/api/v1/...`;MCP 入口挂载在同一个 backend 服务上。 +- 传输协议:`streamableHttp`;MCP 地址 `/mcp`(`/mcp/` 也兼容)。 +- 认证:`X-Bot-Id` + `X-Bot-Secret`。 + +这意味着: +- 不需要单独部署一套 MCP 服务; +- 不需要让 MCP client 传业务账号密码; +- 不需要让远程 agent 访问本地脚本进程。 + +## 2. 接口地址 + +```text +http://:/mcp +``` + +说明: +- 推荐优先使用 `/mcp`;`/mcp/` 也兼容。 +- 前面有 Nginx/网关时,**不要对 `/mcp` 做 301/302 重定向**。 +- 未携带 bot 凭证访问 `/mcp` 或 `/mcp/` 返回 `401`。 + +## 3. 认证模型 + +MCP client 只传两个 header:`X-Bot-Id`、`X-Bot-Secret`。后端逻辑: + +1. 根据 `X-Bot-Id` 查询 `mcp_bots`; +2. 校验 `X-Bot-Secret`; +3. 将该 bot 映射到 NexDocs 用户; +4. 以该用户身份执行 MCP 工具。 + +因此 client 不需要再传:NexDocs 用户名、密码、access token。 + +## 4. 用户如何获取凭证 + +个人中心 → `MCP 接入` 标签页: +- 查看 `X-Bot-Id`; +- 查看并复制 `X-Bot-Secret`; +- 重新生成 `X-Bot-Secret`。 + +后端接口: +- `GET /api/v1/auth/mcp-credentials` +- `POST /api/v1/auth/mcp-credentials/rotate-secret` + +## 5. 当前支持的 MCP 工具 + +| 工具 | 说明 | 关键参数 | +| --- | --- | --- | +| `list_created_projects` | 列出当前用户创建的项目 | keyword(可选), limit(默认100) | +| `get_project_tree` | 项目文件树 | project_id(必填) | +| `get_file` | 获取文件内容 | project_id, path | +| `create_file` | 创建新文件 | project_id, path, content(可选) | +| `update_file` | 修改文件 | project_id, path, content | +| `delete_file` | 删除文件 | project_id, path | + +### 文件类工具的语义 +- `create_file`:目标已存在报错;自动创建缺失上级目录;校验项目写权限;写 Markdown 更新搜索索引;记录操作日志;通知项目成员。 +- `update_file`:目标不存在报错;只允许更新文件(非目录);校验写权限;写 Markdown 更新索引;记日志;通知。 +- `delete_file`:目标不存在报错;只允许删除文件(非目录);删除 Markdown 同步删搜索索引;记日志;通知。 + +## 6. 调用端配置示例 + +支持 streamableHttp 的 MCP client: + +```json +{ + "tools": { + "mcpServers": { + "biz_mcp": { + "type": "streamableHttp", + "url": "http://backend.internal:8000/mcp", + "headers": { + "X-Bot-Id": "nexbot_xxxxxxxxxxxxxxxx", + "X-Bot-Secret": "nxbotsec_xxxxxxxxxxxxxxxxxxxxxxxx" + }, + "toolTimeout": 60 + } + } + } +} +``` + +注意: +- `url` 建议使用 `/mcp`; +- `headers` 中不需再放业务用户名密码; +- `X-Bot-Secret` 只应发给受信任调用端; +- 浏览器环境客户端需把站点加入后端 `CORS_ORIGINS`。 + +## 7. 后端部署要求 + +- **Python 版本**:backend 需要 Python 3.12(MCP SDK 要求 3.10+;本项目按 3.12 调试)。 +- **Docker**:`backend/Dockerfile` 基于 Python 3.12。 +- **数据表**:需要 `mcp_bots` 表(通过建表脚本/init 创建)。 +- **Nginx 统一入口**:前端 Nginx 已加 `/mcp`、`/mcp/` 反代配置,可经统一入口访问。 + +本地开发建议: +```bash +cd backend +/opt/homebrew/bin/python3.12 -m venv venv312 +env -u HTTP_PROXY -u HTTPS_PROXY ./venv312/bin/pip install -r requirements.txt +./venv312/bin/uvicorn main:app --host 0.0.0.0 --port 8000 +``` + +## 8. 验证结果 + +本地已验证: +- Python 3.12 启动 backend 正常; +- `/health` 返回 200; +- `/mcp`、`/mcp/` 均可访问; +- 未传 `X-Bot-Id`/`X-Bot-Secret` 返回 401。 + +## 9. 规格映射 + +- 关联 ADR:ADR-0005(开放接入/可溯源)。 +- 功能规格:FR-18(见 DV-0011)。 +- 验证证据:见 DV-0011/verification.md;详细集成说明已并入本页(原 `docs/MCP_HTTP_INTEGRATION.md`)。 diff --git a/docs/sdd/product/principles.md b/docs/sdd/product/principles.md new file mode 100644 index 0000000..450b90e --- /dev/null +++ b/docs/sdd/product/principles.md @@ -0,0 +1,18 @@ +# 产品与工程原则(Principles) + +## 产品原则 +1. **文件即真理**:内容数据以文件为本,数据库只承载元数据/权限/状态。 +2. **透明可迁移**:任何时刻都应能通过「拷贝目录 + 导出 DB」完成迁移。 +3. **严格隔离**:项目级磁盘隔离 + RBAC 权限,双保险。 +4. **答案可溯源**:知识库问答必须可验证,禁止无依据编造。 +5. **开放接入**:优先用行业标准协议(如 MCP)暴露能力。 + +## 工程原则 +1. **异步优先**:后端 FastAPI + 异步 I/O(aiofiles/aiomysql/aioredis),长任务走后台任务。 +2. **写路径不阻塞**:索引/向量同步放后台(`FileVectorSyncService`、`ProjectVectorizationTaskService`),主请求线程不等待。 +3. **路径安全第一**:任何文件访问必须先过 `get_secure_path` 校验。 +4. **健壮降级**:LLM/embedding/对齐失败不阻断主流程;无配置时跳过。 +5. **幂等变更**:数据库结构演进用幂等 ALTER;初始化脚本可重复执行。 +6. **单一真相源**:本 SDD 中心是规格/追踪入口,细节指向源文档与代码。 +7. **小步可追踪**:一次合并一个逻辑单元,切片(TS)可被证据(VER)验证。 + diff --git a/docs/sdd/product/roadmap.md b/docs/sdd/product/roadmap.md new file mode 100644 index 0000000..19853ed --- /dev/null +++ b/docs/sdd/product/roadmap.md @@ -0,0 +1,34 @@ +# 阶段性路线图(Roadmap) + +> 基于仓库现状(IMPLEMENTATION_PLAN.md 三阶段已基本完成)与 SDD 梳理结果,重新组织为阶段化路线图。状态为 SDD 核对后的推断。 + +## 阶段一:MVP 文档平台(已完成) +- 认证与会话(DV-0001) +- 项目与文件系统(DV-0002) +- 文档编辑与文件操作(DV-0003) +- RBAC 与系统管理(DV-0004) + +## 阶段二:检索与知识库(已完成) +- 全文检索(DV-0005) +- ZVec 向量化(DV-0006) +- RAG 知识库对话(DV-0007) +- LLM 模型配置(DV-0008) + +## 阶段三:协作与开放(已完成) +- 分享与公开预览(DV-0009) +- 通知、日志、Git 集成、导出(DV-0010) +- MCP 接入(DV-0011) + +## 待决/增强(Backlog) +| 项 | 说明 | 关联 | +| --- | --- | --- | +| 安全整改 | 敏感日志脱敏、口令复杂度校验 | OI-1, NFR-9 | +| 部署官方化 | Compose v2 路径统一、清理 v1 依赖说明 | OI-2, ADR-08 | +| 测试增强 | 集成测试与 E2E,提升回归覆盖 | OI-3 | +| 迁移体系评估 | 评估引入 Alembic 以支撑大规模结构变更 | OI-4 | +| 实时协同评估 | 若需多人实时编辑,另行立项(当前 exclude) | vision 边界 | + +## 里程碑原则 +- 每个里程碑对应一组 DV 规格;合入前 verification.md 证据必须齐全(或明确标注 OI-3 覆盖)。 +- 发布版本在 releases/ 登记。 + diff --git a/docs/sdd/product/vision.md b/docs/sdd/product/vision.md new file mode 100644 index 0000000..c9a7e8d --- /dev/null +++ b/docs/sdd/product/vision.md @@ -0,0 +1,39 @@ +# 产品愿景(Vision) + +## 一句话愿景 + +**NEX Docus 是一款面向团队协作的轻量级文档管理平台**,以「数据库管理权限 + 文件系统存储内容」的混合架构,让团队在获得可控权限管理的同时,拥有文件级的数据透明性、可迁移性与可理解性(可检索、可问答、可溯源)。 + +## 产品价值主张(PO) + +| 编号 | 价值主张 | 说明 | +| --- | --- | --- | +| PO-1 | **文件即真理(File as Truth)** | 文档内容、图片、附件以原生文件存于服务器磁盘,不落数据库 BLOB;便于备份、迁移与 Git 版本控制。 | +| PO-2 | **三级模型** | 用户(User)→ 项目(Project)→ 文档/文件夹(File/Folder)的分层组织。 | +| PO-3 | **严格隔离与权限** | 基于项目的物理磁盘隔离 + 数据库 RBAC 权限的双重控制。 | +| PO-4 | **可理解内容库** | 文档可向量化构建知识库,支持基于 RAG 的问答,且答案可溯源(引用支撑句)。 | +| PO-5 | **开放接入** | 通过 MCP (Model Context Protocol) Streamable HTTP 让外部 Agent 访问项目/文档能力。 | + +## 目标用户与角色 + +- **系统管理员(super_admin)**:全量菜单与权限,管理用户、角色、模型配置、日志。 +- **管理员(admin)**:系统级管理人员。 +- **普通用户(user)**:创建/参与项目、编辑文档、使用知识库对话。 +- **访客(匿名分享访问者)**:通过公开分享链接访问项目/文件预览(受限)。 + +## 边界(Scope) + +### 范围内(In Scope) +用户认证与 RBAC、项目管理与协作、文档/文件系统管理、全文检索、ZVec 向量化知识库、RAG 对话、分享/预览、Git 仓库集成、通知、系统日志、LLM 模型配置、后台导出/向量化任务、MCP 接入。 + +### 范围外(Out of Scope) +- 不做数据库内大文件二进制 BLOB 存储(文件一律落盘)。 +- 不内置完整 Alembic 迁移链(见 ADR;采用幂等 ALTER)。 +- 不承诺 docker-compose v1 兼容(依赖 Compose v2 / Engine ≥ 25)。 +- 不做实时多人协同编辑(当前为「保存即落盘 + 后台索引同步」,无 OT/CRDT)。 + +## 成功度量(建议) +- MVP 链路通:创建项目 → 编辑 MD → 保存 → 检索命中 → 向量化 → RAG 问答可溯源。 +- 知识库引用准确率:答案中的 [n] 引用均可回填到原文支撑句(引用对齐覆盖率)。 +- 部署/升级成功率:Compose v2 一键 init/upgrade 无阻断。 + diff --git a/docs/sdd/releases/README.md b/docs/sdd/releases/README.md new file mode 100644 index 0000000..2130d36 --- /dev/null +++ b/docs/sdd/releases/README.md @@ -0,0 +1,25 @@ +# 发布索引(Releases) + +本目录登记**公开版本与资产索引**。每个发布一个文件:`vX.Y.Z.md`,记录发布元数据、产物与验证边界。 + +## 发布规则 +- 版本号语义化(MAJOR.MINOR.PATCH)。 +- 发布前必须:对应 DV verification.md 证据通过;ADR 无未决的重大分歧。 +- 发布文件中须给出「验证边界」:哪些 DV 被覆盖、如何复验、已知限制。 +- 部署相关变更同步到 `DEPLOY.md` / `CHANGELOG_DEPLOY.md`。 +- **版本以 git 为准**:发布必须对应一个 git 版本标记(提交信息中的 vX.Y.Z 或 tag);代码内版本字段应与 git 标记一致。 + +## 版本列表(对齐 git) +| 版本 | 文件 | 对应 git 标记 | 主要规格覆盖 | 状态 | +| --- | --- | --- | --- | --- | +| v0.9.9 | [v0.9.9.md](v0.9.9.md) | `416ef48 v0.9.9`(当前基线,HEAD `4ef3c92`) | 阶段一~三全部 DV | 当前基线 | +| v0.9.6 | [v0.9.6.md](v0.9.6.md) | `c005964 v0.9.6` | MCP 内集成/凭证管理/Python3.12/storage 持久化(历史) | 历史发布记录 | + +> git 发布线:v0.9.1 → v0.9.2 → v0.9.6 → v0.9.7 → v0.9.8 → **v0.9.9**。仓库**未打 git tag**;上表以提交信息中的版本标记为准。 +> +> v0.9.6 为**历史发布记录**(整合自原 `docs/UPGRADE_v0.9.6.md`);v0.9.9 为**当前基线**。 +> +> ⚠️ 代码内版本字段(`APP_VERSION`、`package.json version`)与部分旧文档标注为 1.0.0,与 git 标记不符,属遗留占位,见 v0.9.9.md「版本对齐说明」。 + +## 历史部署变更参考(非发布、仅供追踪) +- `CHANGELOG_DEPLOY.md`:v1.0.1 前端端口 80→8080、storage 目录映射(STORAGE_PATH)等(该记录与 git 发布线冲突,已标注意外,见 archive/版本对齐)。 diff --git a/docs/sdd/releases/v0.9.6.md b/docs/sdd/releases/v0.9.6.md new file mode 100644 index 0000000..10d8f24 --- /dev/null +++ b/docs/sdd/releases/v0.9.6.md @@ -0,0 +1,36 @@ +# Release v0.9.6(历史升级记录) + +> **文档性质**:历史发布记录。整合自原 `docs/UPGRADE_v0.9.6.md`(已并入)。内容多为当时的新增能力,绝大部分已被后续版本吸收为基线;此处仅作发布历史留存。 + +## 元数据 +- **版本**:v0.9.6 +- **更新时间**:2026-03-11 + +## 主要变更 +1. 新增后端内集成的 MCP Server 能力(原生 `streamableHttp`,入口 `/mcp`,兼容 `/mcp/`)。 +2. 新增用户级 MCP 凭证管理(`X-Bot-Id` / `X-Bot-Secret` 认证模型)。 +3. 打通通过 Nginx 统一入口访问 MCP。 +4. 调整部署运行环境到 Python 3.12(MCP SDK 要求 3.10+)。 +5. 将 MySQL、Redis 数据目录改为项目根目录 `storage/` 持久化(`storage/mysql`、`storage/redis`、`storage/projects`、`storage/temp`)。 +6. 个人中心与文档页交互优化(左右布局、浏览/编辑切换、认证异常 Toast 抑制)。 + +## MCP 能力(当时新增) +- 工具:`list_created_projects`、`get_project_tree`、`get_file`、`create_file`、`update_file`、`delete_file`。 +- 接口:`GET /api/v1/auth/mcp-credentials`、`POST /api/v1/auth/mcp-credentials/rotate-secret`。 + +## 部署变更 +- backend 基础镜像切换为 `python:3.12-slim`;pip 构建工具升级;国内源失败回退官方源。 +- Nginx 补 `/mcp`、`/mcp/` 兼容反代。 +- MySQL/Redis 数据目录挂载到 `storage/`。 + +## 升级迁移注意事项 +- MCP 调用地址:经前端 Nginx 统一入口改为 `http(s):///mcp`;调用头保持 `X-Bot-Id`/`X-Bot-Secret`。 + +## 验证边界(当时建议) +1. backend `/health` 正常; +2. 统一入口 `/api/`、`/mcp`、`/mcp/` 可访问; +3. MCP client 能完成 `initialize`; +4. 个人中心 MCP 凭证展示与轮换正常。 + +## 关联 +- 现规格映射:FR-18 / DV-0011;集成细节见 `integrations/mcp.md`。 diff --git a/docs/sdd/releases/v0.9.9.md b/docs/sdd/releases/v0.9.9.md new file mode 100644 index 0000000..eda097b --- /dev/null +++ b/docs/sdd/releases/v0.9.9.md @@ -0,0 +1,35 @@ +# Release v0.9.9(当前基线) + +> 基于 `git log` 版本标记对应的最新发布提交(`416ef48 v0.9.9`)与当前 HEAD(`4ef3c92 优化了显示`,位于 v0.9.9 之后)。仓库未打 git tag,此记录以提交信息中的版本标记为准。 + +## 元数据 +- **版本**:v0.9.9(当前基线) +- **对应提交**:v0.9.9 标记提交 `416ef48`;当前 HEAD `4ef3c92` +- **适用代码**:backend + frontend + docker-compose(main 分支) +- **代码内版本字段**:意外标注为 1.0.0,与 git 标记 v0.9.9 不符,见「已知差异」 + +## 主要能力 +覆盖阶段一~三:认证/DV-0001、项目管理与文件系统/DV-0002、文档编辑/DV-0003、RBAC 与系统管理/DV-0004、全文检索/DV-0005、ZVec 向量化/DV-0006、RAG 对话/DV-0007、模型配置/DV-0008、分享预览/DV-0009、通知日志 Git 导出/DV-0010、MCP/DV-0011。 + +## 产物 +- 后端镜像(docker-compose backend build) +- 前端镜像(frontend build,nginx 托管静态资源) +- 部署编排:`docker-compose.yml` + `deploy.sh` + +## 验证边界 +- 自动化测试:`backend/tests/test_chat_citations.py`、`test_model_and_vector_configuration.py`、`test_search_service.py`。 +- 运行验证:`/health` 返回 healthy;Swagger `/docs` 可用。 +- 部署验证:Compose v2 `docker compose up -d --build`;`./deploy.sh upgrade`。 +- 已知限制:单机部署;无实时协同编辑;测试覆盖待增强(OI-3)。 + +## 已知问题 +| 编号 | 内容 | 处置 | +| --- | --- | --- | +| OI-1 | 敏感日志脱敏 | 待整改 | +| OI-2 | Compose v2 官方化 | 待整改 | +| OI-4 | 版本字段 1.0.0 与 git 标记不符,需统一 | 待整改(见本文档「版本对齐」说明) | + +## 版本对齐说明 +- git 发布线:v0.9.1 → v0.9.2 → v0.9.6 → v0.9.7 → v0.9.8 → v0.9.9(`416ef48`)。 +- **无 v1.0.0** 的 git 版本;代码 `APP_VERSION=1.0.0`、`package.json version=1.0.0` 与文档中的 v1.0.0/v1.0.1 均为遗留占位,与 git 不符。 +- 建议:下次打 tag 时以 v0.9.9 为基线;若计划升级 v1.0.0 则应显式建 tag 并同步代码字段。 diff --git a/docs/sdd/specs/DV-0001-auth/design.md b/docs/sdd/specs/DV-0001-auth/design.md new file mode 100644 index 0000000..975b4dd --- /dev/null +++ b/docs/sdd/specs/DV-0001-auth/design.md @@ -0,0 +1,28 @@ +# DV-0001:认证与会话 – 设计(Design) + +## 上下文 +涉及 `auth.py`(API)、`security.py`(JWT/bcrypt)、`deps.py`(依赖注入)、`redis_client.py`(TokenCache)。 + +## 数据模型 +- `users`(id/username/password_hash/…)——细节见 DATABASE.md。 + +## 接口设计 +- POST /api/v1/auth/{register,login,logout} +- GET /api/v1/auth/me +- PUT /api/v1/auth/profile +- POST /api/v1/auth/change-password +- POST /api/v1/auth/upload-avatar +- GET /api/v1/auth/avatar/{user_id}/{filename} +- GET/POST /api/v1/auth/mcp-credentials{,/rotate-secret} + +## 认证流程 +1. 登录成功:bcrypt 校验 → 生成 JWT(sub=user_id)→ 写入 Redis TokenCache。 +2. 每次请求:`get_current_user` 校验 Redis 中 token→user_id,再 decode JWT,两项一致且用户启用才放行。 +3. 登出:移除 Redis 中的 token,实现即时失效。 + +## 状态与降级 +- Redis 不可用 → 认证失败(受 NFR-2 约束);可选认证(`get_current_user_optional`)返回 None 而非报错。 + +## 变更影响 +- NFR-9 敏感日志:security.py/deps.py 的 SECRET_KEY/JWT 载荷日志需脱敏(TS-12)。 + diff --git a/docs/sdd/specs/DV-0001-auth/spec.md b/docs/sdd/specs/DV-0001-auth/spec.md new file mode 100644 index 0000000..a56fd56 --- /dev/null +++ b/docs/sdd/specs/DV-0001-auth/spec.md @@ -0,0 +1,32 @@ +# DV-0001:认证与会话 – 规格(Spec) + +- **状态**:Implemented +- **关联 ADR**:ADR-0003 + +## 目标 +提供安全的用户认证与会话管理,为所有受保护资源提供身份基础。 + +## 范围 +- **In**:注册、登录、登出、修改密码、个人资料、头像上传、JWT Bearer + Redis 双校验。 +- **Out**:第三方 SSO/OAuth 登录。 + +## 用户故事 +> 作为用户,我希望登录一次后持续访问项目/文档,以便高效工作而不反复输入凭据。 + +## 功能需求(FR) +| ID | 需求描述 | 验收要点 | +| --- | --- | --- | +| FR-1 | 注册/登录/登出、改密、资料、头像 | 登录返回 JWT;退出后 token 失效 | +| FR-1a | 每次请求经 get_current_user 校验 | Redis 缓存 + JWT 完整性 + 用户状态;禁用即拒绝 | + +## 非功能需求(NFR) +| ID | 需求 | +| --- | --- | +| NFR-1 | 密码 bcrypt 哈希存储,绝不明文 | +| NFR-2 | JWT + Redis Token 缓存双校验;token 存 Redis 可失效 | +| NFR-9 | 敏感日志脱敏(缺陷,见 OI-1) | + +## 边界与约束 +- 使用 OAuth2 password bearer;token 有效期 ACCESS_TOKEN_EXPIRE_MINUTES=1440。 +- 用户被禁用(status!=1)即拒绝访问。 + diff --git a/docs/sdd/specs/DV-0001-auth/tasks.md b/docs/sdd/specs/DV-0001-auth/tasks.md new file mode 100644 index 0000000..b2fbf21 --- /dev/null +++ b/docs/sdd/specs/DV-0001-auth/tasks.md @@ -0,0 +1,9 @@ +# DV-0001:认证与会话 – 任务(Tasks) + +| TS(全局/切片) | 切片 | 关联规格 | 状态 | +| --- | --- | --- | --- | +| TS-1 | 注册/登录/登出 + JWT + Redis | FR-1, NFR-2 | 已完成 | +| TS-1a | 修改密码、个人资料、头像上传 | FR-1 | 已完成 | +| TS-1b | mcp-credentials 接口 | FR-1/FR-18 | 已完成 | +| TS-12 | **敏感日志脱敏、口令复杂度** | NFR-1, NFR-9 | 待整改 | + diff --git a/docs/sdd/specs/DV-0001-auth/verification.md b/docs/sdd/specs/DV-0001-auth/verification.md new file mode 100644 index 0000000..6c603be --- /dev/null +++ b/docs/sdd/specs/DV-0001-auth/verification.md @@ -0,0 +1,19 @@ +# DV-0001:认证与会话 – 验证(Verification) + +## 自动化测试 +- 结构性证据为主(认证逻辑无独立单测文件)。 + +## 手工验收清单 +- [x] 登录返回 JWT;携带后可访问受保护接口 +- [x] 退出后同 token 返回 401 +- [x] 禁用用户登录后请求被拒 +- [x] 修改密码后旧密码失效 +- [ ] 敏感日志脱敏(TS-12 未完成) + +## 结构性证据 +| VER | 证据 | 证明 | +| --- | --- | --- | +| VER-10 | backend/app/models/user.py | FR-1 数据层 | +| VER-11 | backend/app/api/v1/auth.py | FR-1 API 层 | +| VER-15 | backend/app/core/security.py + deps.py | NFR-1/2;揭示 NFR-9 | + diff --git a/docs/sdd/specs/DV-0002-project-filesystem/design.md b/docs/sdd/specs/DV-0002-project-filesystem/design.md new file mode 100644 index 0000000..7157a9b --- /dev/null +++ b/docs/sdd/specs/DV-0002-project-filesystem/design.md @@ -0,0 +1,27 @@ +# DV-0002:项目与文件系统 – 设计(Design) + +## 上下文 +`projects.py`、`storage.py`、`project_file_service.py`、`file_vector_sync_service.py`。 + +## 数据模型 +- `projects`(storage_key/owner_id/status/access_pass…) +- `project_members`(role: admin/editor/viewer) +- `document_meta`、`document_vector` +- 细节见 DATABASE.md。 + +## 存储结构 +`STORAGE_ROOT/projects//` + `_assets/images|files` + 默认 README.md。 + +## 接口设计 +- /api/v1/projects/*(CRUD、my、shared、transfer、members) +- /api/v1/files/{project_id}/tree + +## 路径安全 +`get_secure_path(storage_key, rel)`:以 project_root 为根,`relative_to` 校验,失败 403。 + +## 状态与降级 +- 权限不足→403;索引同步失败不阻塞文件写(最终一致)。 + +## 变更影响 +- ADR-0006:文件变更触发向量/全文索引进后台同步。 + diff --git a/docs/sdd/specs/DV-0002-project-filesystem/spec.md b/docs/sdd/specs/DV-0002-project-filesystem/spec.md new file mode 100644 index 0000000..06baf57 --- /dev/null +++ b/docs/sdd/specs/DV-0002-project-filesystem/spec.md @@ -0,0 +1,33 @@ +# DV-0002:项目与文件系统 – 规格(Spec) + +- **状态**:Implemented +- **关联 ADR**:ADR-0001, ADR-0002, ADR-0003, ADR-0006 + +## 目标 +建立「用户→项目→文档/文件夹」三级模型,并以“DB 权限 + FS 内容”实现项目文档的文件级存储与严格隔离。 + +## 范围 +- **In**:项目 CRUD/转移/归档、成员协作、StorageService 路径安全、目录树。 +- **Out**:实时协同编辑。 + +## 用户故事 +> 作为项目成员,我希望按权限访问项目文档,以便协同维护知识库。 + +## 功能需求(FR) +| ID | 需求 | 验收要点 | +| --- | --- | --- | +| FR-2 | 三级模型 + 项目 CRUD/转移 | 创建生成 UUID storage_key 并建磁盘结构 | +| FR-3 | 文件系统存储 + 路径安全 | get_secure_path 防穿越;隐藏文件/_assets 不进树 | +| FR-5 | 项目成员协作 | 按 admin/editor/viewer 判定读写 | + +## 非功能需求(NFR) +| ID | 需求 | +| --- | --- | +| NFR-3 | 所有路径经 get_secure_path 校验 | +| NFR-4 | 项目访问做 RBAC 校验 | +| NFR-11 | 索引在文件变更时同步维护 | + +## 边界与约束 +- 磁盘名用 UUID(storage_key),展示名解耦。 +- 内容不进 DB BLOB。 + diff --git a/docs/sdd/specs/DV-0002-project-filesystem/tasks.md b/docs/sdd/specs/DV-0002-project-filesystem/tasks.md new file mode 100644 index 0000000..7802652 --- /dev/null +++ b/docs/sdd/specs/DV-0002-project-filesystem/tasks.md @@ -0,0 +1,8 @@ +# DV-0002:项目与文件系统 – 任务(Tasks) + +| TS(全局/切片) | 切片 | 关联规格 | 状态 | +| --- | --- | --- | --- | +| TS-2 | 三级模型、项目 CRUD、存储服务、路径安全、成员协作 | FR-2/3/5, NFR-3/4 | 已完成 | +| TS-2a | 项目转移/归档/访问密码 | FR-2 | 已完成 | +| TS-2b | 磁盘结构初始化(uuid + _assets + README) | FR-2 | 已完成 | + diff --git a/docs/sdd/specs/DV-0002-project-filesystem/verification.md b/docs/sdd/specs/DV-0002-project-filesystem/verification.md new file mode 100644 index 0000000..b7a85fe --- /dev/null +++ b/docs/sdd/specs/DV-0002-project-filesystem/verification.md @@ -0,0 +1,15 @@ +# DV-0002:项目与文件系统 – 验证(Verification) + +## 手工验收清单 +- [x] 创建项目生成 uuid 目录 + README.md + _assets +- [x] 路径穿越(../)返回 403 +- [x] 非成员访问返回 403 +- [x] 目录树隐藏 . 开头的文件与 _assets + +## 结构性证据 +| VER | 证据 | 证明 | +| --- | --- | --- | +| VER-10 | models/project.py 等 | FR-2/5 数据层 | +| VER-11 | api/v1/projects.py, files.py | FR-2/3/5 API 层 | +| VER-12 | services/storage.py, project_file_service.py | ADR-0001/2/6, FR-3 | + diff --git a/docs/sdd/specs/DV-0003-document-editing/design.md b/docs/sdd/specs/DV-0003-document-editing/design.md new file mode 100644 index 0000000..8ac0f78 --- /dev/null +++ b/docs/sdd/specs/DV-0003-document-editing/design.md @@ -0,0 +1,20 @@ +# DV-0003:文档编辑与文件操作 – 设计(Design) + +## 上下文 +`files.py`(API)、`storage.py`(读写)、前端 `DocumentPage/DocumentEditor`(pages/Document)、Markdown 组件 bytemd。 + +## 接口设计 +- GET /api/v1/files/{project_id}/tree +- GET|POST /api/v1/files/{project_id}/file +- POST /api/v1/files/{project_id}/file/operate +- POST /api/v1/files/{project_id}/upload{,-document} +- POST /api/v1/files/{project_id}/import-documents +- GET /api/v1/files/{project_id}/export-directory +- GET /api/v1/files/{project_id}/export-pdf + +## 前端 +- 左侧目录树,右侧 Markdown 编辑/预览;PDF 用 react-pdf;长列表虚拟滚动。 + +## 状态与降级 +- 写文件自动创建父目录;重命名目标冲突→400。 + diff --git a/docs/sdd/specs/DV-0003-document-editing/spec.md b/docs/sdd/specs/DV-0003-document-editing/spec.md new file mode 100644 index 0000000..8095f87 --- /dev/null +++ b/docs/sdd/specs/DV-0003-document-editing/spec.md @@ -0,0 +1,30 @@ +# DV-0003:文档编辑与文件操作 – 规格(Spec) + +- **状态**:Implemented +- **关联 ADR**:ADR-0002 + +## 目标 +提供无限层级目录树与完整的 Markdown 文档编辑/文件操作能力。 + +## 范围 +- **In**:目录树、读/存文件、新建/重命名/删除/移动、上传图片/文档、导入/导出、导出 PDF。 +- **Out**:富文本编辑器(仅 Markdown)。 + +## 用户故事 +> 作为文档作者,我希望编辑 Markdown 并管理目录结构,以便维护有序的知识库。 + +## 功能需求(FR) +| ID | 需求 | 验收要点 | +| --- | --- | --- | +| FR-4 | 目录树 + 文件操作 + 上传/导入/导出 | 无限层级;目录在前名称排序;_assets 不展示 | +| FR-4a | 前端编辑器 + 保存 | Cmd+S 保存;图片/附件上传 | + +## 非功能需求(NFR) +| ID | 需求 | +| --- | --- | +| NFR-3 | 路径安全(所有文件操作复用 get_secure_path) | +| NFR-5 | aiofiles 异步 I/O;PDF/长文档虚拟滚动 | + +## 边界与约束 +- 隐藏文件不进入树;_assets 不进入树。 + diff --git a/docs/sdd/specs/DV-0003-document-editing/tasks.md b/docs/sdd/specs/DV-0003-document-editing/tasks.md new file mode 100644 index 0000000..0f8cdac --- /dev/null +++ b/docs/sdd/specs/DV-0003-document-editing/tasks.md @@ -0,0 +1,8 @@ +# DV-0003:文档编辑与文件操作 – 任务(Tasks) + +| TS(全局/切片) | 切片 | 关联规格 | 状态 | +| --- | --- | --- | --- | +| TS-3 | tree/file/operate/upload/import/export 基础链路 | FR-4 | 已完成 | +| TS-3a | 前端编辑器与目录树 | FR-4a | 已完成 | +| TS-3b | PDF 预览与导出 | FR-4a | 已完成 | + diff --git a/docs/sdd/specs/DV-0003-document-editing/verification.md b/docs/sdd/specs/DV-0003-document-editing/verification.md new file mode 100644 index 0000000..de7cabb --- /dev/null +++ b/docs/sdd/specs/DV-0003-document-editing/verification.md @@ -0,0 +1,16 @@ +# DV-0003:文档编辑与文件操作 – 验证(Verification) + +## 手工验收清单 +- [x] 新建/重命名/删除/移动文件与文件夹 +- [x] 文件内容保存后读回一致 +- [x] 图片/文档上传成功 +- [x] 目录导出 ZIP、文档导出 PDF +- [x] 隐藏文件与 _assets 不在树中 + +## 结构性证据 +| VER | 证据 | 证明 | +| --- | --- | --- | +| VER-11 | api/v1/files.py | FR-4 | +| VER-12 | services/storage.py | FR-4 | +| VER-16 | frontend/src/pages/Document/* | FR-4a | + diff --git a/docs/sdd/specs/DV-0004-rbac-admin/design.md b/docs/sdd/specs/DV-0004-rbac-admin/design.md new file mode 100644 index 0000000..a53c82d --- /dev/null +++ b/docs/sdd/specs/DV-0004-rbac-admin/design.md @@ -0,0 +1,18 @@ +# DV-0004:RBAC 与系统管理 – 设计(Design) + +## 上下文 +`roles.py`、`role_permissions.py`、`users.py`、`menu.py`、`dashboard.py`。 + +## 数据模型 +- `roles`、`user_roles`、`system_menus`、`role_menus`。 +- 细节见 DATABASE.md。 + +## 接口设计 +- /api/v1/roles/*、/api/v1/role-permissions/* +- /api/v1/users/* +- /api/v1/menu/user-menus、/user-permissions +- /api/v1/dashboard/* + +## 权限判定 +- 前端按 user-permissions 渲染;后端依赖校验。超级管理员跳过细粒度检查。 + diff --git a/docs/sdd/specs/DV-0004-rbac-admin/spec.md b/docs/sdd/specs/DV-0004-rbac-admin/spec.md new file mode 100644 index 0000000..da2ff21 --- /dev/null +++ b/docs/sdd/specs/DV-0004-rbac-admin/spec.md @@ -0,0 +1,27 @@ +# DV-0004:RBAC 与系统管理 – 规格(Spec) + +- **状态**:Implemented +- **关联 ADR**:ADR-0003 + +## 目标 +提供基于角色的访问控制(RBAC)与系统管理能力(用户、角色、权限、菜单、仪表盘)。 + +## 范围 +- **In**:角色→菜单/权限点、用户管理、仪表盘统计。 +- **Out**:细粒度字段级权限(当前为菜单/权限点/项目角色)。 + +## 用户故事 +> 作为管理员,我希望按角色分配能力并量化系统使用情况,以便治理平台。 + +## 功能需求(FR) +| ID | 需求 | 验收要点 | +| --- | --- | --- | +| FR-6 | RBAC:roles/system_menus/role_menus;超级管理员全量 | 用户多角色;菜单/权限点授权 | +| FR-7 | 用户管理:增删改查/启停/角色/重置密码 | 管理员可操作 | +| FR-8 | 仪表盘:统计与文档活跃度 | 数据正确 | + +## 非功能需求(NFR) +| ID | 需求 | +| --- | --- | +| NFR-4 | 权限判定统一走 RBAC 依赖 | + diff --git a/docs/sdd/specs/DV-0004-rbac-admin/tasks.md b/docs/sdd/specs/DV-0004-rbac-admin/tasks.md new file mode 100644 index 0000000..386f4ad --- /dev/null +++ b/docs/sdd/specs/DV-0004-rbac-admin/tasks.md @@ -0,0 +1,7 @@ +# DV-0004:RBAC 与系统管理 – 任务(Tasks) + +| TS(全局/切片) | 切片 | 关联规格 | 状态 | +| --- | --- | --- | --- | +| TS-4 | RBAC、角色/权限/菜单、用户管理、仪表盘统计 | FR-6/7/8 | 已完成 | +| TS-4a | 菜单/权限点初始化(scripts/init_db.py) | FR-6 | 已完成 | + diff --git a/docs/sdd/specs/DV-0004-rbac-admin/verification.md b/docs/sdd/specs/DV-0004-rbac-admin/verification.md new file mode 100644 index 0000000..35dc979 --- /dev/null +++ b/docs/sdd/specs/DV-0004-rbac-admin/verification.md @@ -0,0 +1,15 @@ +# DV-0004:RBAC 与系统管理 – 验证(Verification) + +## 手工验收清单 +- [x] 角色增删改、菜单/权限点授权 +- [x] 用户增删改/启停/分配角色/重置密码 +- [x] 超级管理员拥有全部权限 +- [x] 仪表盘统计正确 + +## 结构性证据 +| VER | 证据 | 证明 | +| --- | --- | --- | +| VER-10 | models/role.py, menu.py | FR-6 | +| VER-11 | api/v1/{roles,role_permissions,users,menu,dashboard}.py | FR-6/7/8 | +| VER-16 | frontend/src/pages/System/* | FR-6/7 | + diff --git a/docs/sdd/specs/DV-0005-fulltext-search/design.md b/docs/sdd/specs/DV-0005-fulltext-search/design.md new file mode 100644 index 0000000..3aa133f --- /dev/null +++ b/docs/sdd/specs/DV-0005-fulltext-search/design.md @@ -0,0 +1,15 @@ +# DV-0005:全文检索 – 设计(Design) + +## 上下文 +`search_service.py`(Whoosh + `ChineseAnalyzer`/jieba)。 + +## 接口设计 +- GET /api/v1/search/documents +- POST /api/v1/search/rebuild-index + +## 索引结构 +- `search_index` 本地目录;schema:project_id/path/title/content;`path` 用 `:` 唯一化。 + +## 变更同步 +- 文件读写路径调用 `search_service.update_doc/delete_document`(files.py 导入触发)。 + diff --git a/docs/sdd/specs/DV-0005-fulltext-search/spec.md b/docs/sdd/specs/DV-0005-fulltext-search/spec.md new file mode 100644 index 0000000..2573b9a --- /dev/null +++ b/docs/sdd/specs/DV-0005-fulltext-search/spec.md @@ -0,0 +1,25 @@ +# DV-0005:全文检索 – 规格(Spec) + +- **状态**:Implemented +- **关联 ADR**:ADR-0004 + +## 目标 +基于本地 Whoosh 索引对文档内容/标题做中文关键词检索。 + +## 范围 +- **In**:文档索引维护、关键词检索、重建索引。 +- **Out**:语义向量检索(归 DV-0006)。 + +## 用户故事 +> 作为用户,我希望按关键词搜到项目文档,以便快速定位。 + +## 功能需求(FR) +| ID | 需求 | 验收要点 | +| --- | --- | --- | +| FR-9 | Whoosh 中文检索 + 变更同步 + 重建 | 命中标题/内容;jieba 中文分词 | + +## 非功能需求(NFR) +| ID | 需求 | +| --- | --- | +| NFR-11 | 文档变更时同步索引(ADR-0006) | + diff --git a/docs/sdd/specs/DV-0005-fulltext-search/tasks.md b/docs/sdd/specs/DV-0005-fulltext-search/tasks.md new file mode 100644 index 0000000..0a5e4e1 --- /dev/null +++ b/docs/sdd/specs/DV-0005-fulltext-search/tasks.md @@ -0,0 +1,7 @@ +# DV-0005:全文检索 – 任务(Tasks) + +| TS(全局/切片) | 切片 | 关联规格 | 状态 | +| --- | --- | --- | --- | +| TS-5 | Whoosh 中文索引 + 变更同步 + 重建 | FR-9 | 已完成 | +| TS-5a | 检索结果高亮/命中 | FR-9 | 已完成 | + diff --git a/docs/sdd/specs/DV-0005-fulltext-search/verification.md b/docs/sdd/specs/DV-0005-fulltext-search/verification.md new file mode 100644 index 0000000..896d8c0 --- /dev/null +++ b/docs/sdd/specs/DV-0005-fulltext-search/verification.md @@ -0,0 +1,17 @@ +# DV-0005:全文检索 – 验证(Verification) + +## 自动化测试 +| VER | 测试 | 证明 | 结果 | +| --- | --- | --- | --- | +| VER-3 | test_search_service.py | FR-9, TS-5 | 通过 | + +## 手工验收清单 +- [x] 创建文档后立即可被关键词命中 +- [x] 删除文档后不再命中 +- [x] 重建索引可用 + +## 结构性证据 +| VER | 证据 | 证明 | +| --- | --- | --- | +| VER-12 | services/search_service.py | ADR-0004, FR-9 | + diff --git a/docs/sdd/specs/DV-0006-zvec-vectorization/design.md b/docs/sdd/specs/DV-0006-zvec-vectorization/design.md new file mode 100644 index 0000000..7a33236 --- /dev/null +++ b/docs/sdd/specs/DV-0006-zvec-vectorization/design.md @@ -0,0 +1,19 @@ +# DV-0006:ZVec 向量化 – 设计(Design) + +## 上下文 +`zvec_service.py`、`file_vector_sync_service.py`、`project_vectorization_task_service.py`。 + +## 分块 +- 字符滑动窗口:chunk_size(默认 800)/ overlap(150);每块生成 anchor、content_hash。 + +## 写入 +- ZVec collection 每项目一个(`vector_index/`);embedding 用配置的 `model_type=embedding` 模型。 +- `document_vector` 表逐块记录(zvec_id/chunk_text/status/error)。 + +## 触发 +- 写路径:`ProjectFileService → FileVectorSyncService`(后台、按项目串行)。 +- 全量:`ProjectVectorizationTaskService`(后台任务 + 进度表)。 + +## 维度变更 +- 检测现有 collection 维度与模型不一致 → 重建 collection,旧向量作废需重向量化。 + diff --git a/docs/sdd/specs/DV-0006-zvec-vectorization/spec.md b/docs/sdd/specs/DV-0006-zvec-vectorization/spec.md new file mode 100644 index 0000000..047c21b --- /dev/null +++ b/docs/sdd/specs/DV-0006-zvec-vectorization/spec.md @@ -0,0 +1,27 @@ +# DV-0006:ZVec 向量化 – 规格(Spec) + +- **状态**:Implemented +- **关联 ADR**:ADR-0004, ADR-0006 + +## 目标 +将项目 MD 文档分块向量化,写入本地 ZVec 库并记录状态,为 RAG 提供语义检索基础。 + +## 范围 +- **In**:MD 分块向量化、增量同步、删除清理、整项目后台任务。 +- **Out**:对话本身(归 DV-0007)。 + +## 用户故事 +> 作为用户,我希望项目文档自动向量化,以便后续语义问答。 + +## 功能需求(FR) +| ID | 需求 | 验收要点 | +| --- | --- | --- | +| FR-10 | MD 分块 + embedding + ZVec 写入 + document_vector 记录 | 保存/新建/重命名触发;删除清理;PDF 不向量化;维度变更重建 | +| FR-11 | 整项目向量化后台任务 + 进度 | pending/running/success/failed 持久化 | + +## 非功能需求(NFR) +| ID | 需求 | +| --- | --- | +| NFR-10 | embedding 失败不阻断;无配置跳过 | +| NFR-11 | 向量维度变更重建 collection 并全量重向量化 | + diff --git a/docs/sdd/specs/DV-0006-zvec-vectorization/tasks.md b/docs/sdd/specs/DV-0006-zvec-vectorization/tasks.md new file mode 100644 index 0000000..801d07a --- /dev/null +++ b/docs/sdd/specs/DV-0006-zvec-vectorization/tasks.md @@ -0,0 +1,8 @@ +# DV-0006:ZVec 向量化 – 任务(Tasks) + +| TS(全局/切片) | 切片 | 关联规格 | 状态 | +| --- | --- | --- | --- | +| TS-6 | 分块、embedding、collection、增量同步、进度 | FR-10/11 | 已完成 | +| TS-6a | MD 变更触发重向量化/删除清理 | FR-10 | 已完成 | +| TS-6b | 维度变更重建 collection | FR-10, NFR-11 | 已完成 | + diff --git a/docs/sdd/specs/DV-0006-zvec-vectorization/verification.md b/docs/sdd/specs/DV-0006-zvec-vectorization/verification.md new file mode 100644 index 0000000..e130b78 --- /dev/null +++ b/docs/sdd/specs/DV-0006-zvec-vectorization/verification.md @@ -0,0 +1,19 @@ +# DV-0006:ZVec 向量化 – 验证(Verification) + +## 自动化测试 +| VER | 测试 | 证明 | 结果 | +| --- | --- | --- | --- | +| VER-2 | test_model_and_vector_configuration.py | FR-10, TS-6 | 通过 | + +## 手工验收清单 +- [x] 保存 MD 触发向量化、document_vector 出现记录 +- [x] 删除 MD 清理向量 +- [x] PDF 不向量化 +- [x] 维度变更后重建 collection + +## 结构性证据 +| VER | 证据 | 证明 | +| --- | --- | --- | +| VER-10 | models/document_vector.py, project_vectorization_task.py | FR-10/11 | +| VER-12 | services/zvec_service.py, file_vector_sync_service.py | ADR-0004/6 | + diff --git a/docs/sdd/specs/DV-0007-rag-chat/design.md b/docs/sdd/specs/DV-0007-rag-chat/design.md new file mode 100644 index 0000000..4b4dc94 --- /dev/null +++ b/docs/sdd/specs/DV-0007-rag-chat/design.md @@ -0,0 +1,27 @@ +# DV-0007:知识库 RAG 对话 – 设计(Design) + +## 上下文 +`chat.py`(API)、`rag_service.py`(检索/生成/对齐)、`zvec_service.search_similar`。 + +## 数据模型 +- `chat_session`、`chat_message`(status/duration_ms/thinking_log/referenced_files)。 + +## 接口设计 +- POST /api/v1/chat/sessions、GET /chat/sessions、GET|PUT|DELETE /chat/sessions/{id} +- GET /chat/sessions/{id}/messages、DELETE /chat/messages/{id} +- POST /chat/send、/chat/send/stream、/chat/messages/{id}/interrupt +- GET /chat/search、(向量化系列归 DV-0006) + +## 检索与生成 +1. `search_similar`(top_k*4 命中去重,每文件最多 MAX_CHUNKS_PER_DOCUMENT=3)。 +2. 上下文围绕命中锚点截取(CHUNK_CONTEXT_WINDOW=1200)。 +3. 系统提示词约束:仅依知识库、必须 [n] 引用。 +4. 历史仅注入最近用户问题(HISTORY_USER_QUESTION_LIMIT=3)作为指代。 + +## 引用对齐 +- `align_citation_quotes`:答案论断句 ↔ 原文候选句向量对齐,回填 quote_occurrences。 + +## 状态与降级 +- 中断:status=interrupted;旧数据按只读兼容判定(不回溯改库)。 +- 对齐/embedding 失败 → 降级不返回支撑句。 + diff --git a/docs/sdd/specs/DV-0007-rag-chat/spec.md b/docs/sdd/specs/DV-0007-rag-chat/spec.md new file mode 100644 index 0000000..90feb7d --- /dev/null +++ b/docs/sdd/specs/DV-0007-rag-chat/spec.md @@ -0,0 +1,26 @@ +# DV-0007:知识库 RAG 对话 – 规格(Spec) + +- **状态**:Implemented +- **关联 ADR**:ADR-0004, ADR-0005 + +## 目标 +基于向量检索 + LLM 生成可溯源的问答对话。 + +## 范围 +- **In**:会话/消息管理、检索 + 生成、流式、中断、引用支撑句。 +- **Out**:多轮复杂 Agent(仅单轮检索增强 + 指代历史)。 + +## 用户故事 +> 作为用户,我希望问知识库问题并看到带引用的可验证答案。 + +## 功能需求(FR) +| ID | 需求 | 验收要点 | +| --- | --- | --- | +| FR-12 | 向量检索 + LLM 生成 + 会话管理 + 流式 | 答案带 [n] 引用;检索按文件去重;历史仅注入最近用户问题 | +| FR-19 | 引用支撑句对齐 + 消息规范化 | [n] 按出现顺序回填 quote_occurrences;旧数据只读兼容 | + +## 非功能需求(NFR) +| ID | 需求 | +| --- | --- | +| NFR-10 | 引用对齐/embedding 失败降级 | + diff --git a/docs/sdd/specs/DV-0007-rag-chat/tasks.md b/docs/sdd/specs/DV-0007-rag-chat/tasks.md new file mode 100644 index 0000000..7898c0e --- /dev/null +++ b/docs/sdd/specs/DV-0007-rag-chat/tasks.md @@ -0,0 +1,8 @@ +# DV-0007:知识库 RAG 对话 – 任务(Tasks) + +| TS(全局/切片) | 切片 | 关联规格 | 状态 | +| --- | --- | --- | --- | +| TS-7 | 会话/消息/流式/中断/引用对齐 | FR-12/19 | 已完成 | +| TS-7a | 引用规范化与去重 | FR-19 | 已完成 | +| TS-7b | 历史指代处理 | FR-12 | 已完成 | + diff --git a/docs/sdd/specs/DV-0007-rag-chat/verification.md b/docs/sdd/specs/DV-0007-rag-chat/verification.md new file mode 100644 index 0000000..0a0fd83 --- /dev/null +++ b/docs/sdd/specs/DV-0007-rag-chat/verification.md @@ -0,0 +1,20 @@ +# DV-0007:知识库 RAG 对话 – 验证(Verification) + +## 自动化测试 +| VER | 测试 | 证明 | 结果 | +| --- | --- | --- | --- | +| VER-1 | test_chat_citations.py | FR-12/19, TS-7 | 通过 | + +## 手工验收清单 +- [x] 创建会话、发消息、流式接收 +- [x] 答案带 [n] 引用并可回填支撑句 +- [x] 中断消息正确处理 +- [x] 检索命中高亮 + +## 结构性证据 +| VER | 证据 | 证明 | +| --- | --- | --- | +| VER-11 | api/v1/chat.py | FR-12 | +| VER-12 | services/rag_service.py | ADR-0004/5 | +| VER-16 | frontend/src/pages/Chat/* | FR-12 | + diff --git a/docs/sdd/specs/DV-0008-llm-model-config/design.md b/docs/sdd/specs/DV-0008-llm-model-config/design.md new file mode 100644 index 0000000..ab85b9d --- /dev/null +++ b/docs/sdd/specs/DV-0008-llm-model-config/design.md @@ -0,0 +1,18 @@ +# DV-0008:LLM 模型配置 – 设计(Design) + +## 上下文 +`llm_model_configs.py`、`llm_provider_service.py`、模型 `llm_model_config.py`。 + +## 数据模型 +- `llm_model_config`(model_code/model_type/provider/endpoint/api_key/llm_model_name/llm_timeout/type_config/is_active/is_default)。 + +## type_config 差异字段 +- chat:temperature/top_p/max_tokens/system_prompt +- embedding:dimension/chunk_size/chunk_overlap + +## 接口设计 +- /api/v1/llm-model-configs/*(CRUD、status、default、test、providers) + +## 默认选择 +- embedding 默认取 is_active 且 model_type=embedding,is_default 优先。 + diff --git a/docs/sdd/specs/DV-0008-llm-model-config/spec.md b/docs/sdd/specs/DV-0008-llm-model-config/spec.md new file mode 100644 index 0000000..eb2193b --- /dev/null +++ b/docs/sdd/specs/DV-0008-llm-model-config/spec.md @@ -0,0 +1,25 @@ +# DV-0008:LLM 模型配置 – 规格(Spec) + +- **状态**:Implemented +- **关联 ADR**:ADR-0004 + +## 目标 +管理 chat/embedding 两类模型配置,供对话与向量化使用。 + +## 范围 +- **In**:模型配置 CRUD、启停、默认、连通性测试、类型差异参数。 +- **Out**:密钥托管/加密(当前 API Key 明文字段,见 OI 关注)。 + +## 用户故事 +> 作为管理员,我希望配置并测试大模型,以便对话与向量化使用。 + +## 功能需求(FR) +| ID | 需求 | 验收要点 | +| --- | --- | --- | +| FR-13 | 模型配置 CRUD/启停/默认/测试 | chat 与 embedding 分离存储;维度等差异参数 | + +## 非功能需求(NFR) +| ID | 需求 | +| --- | --- | +| NFR-10 | 无默认 embedding 时向量化跳过并告警 | + diff --git a/docs/sdd/specs/DV-0008-llm-model-config/tasks.md b/docs/sdd/specs/DV-0008-llm-model-config/tasks.md new file mode 100644 index 0000000..17cff85 --- /dev/null +++ b/docs/sdd/specs/DV-0008-llm-model-config/tasks.md @@ -0,0 +1,7 @@ +# DV-0008:LLM 模型配置 – 任务(Tasks) + +| TS(全局/切片) | 切片 | 关联规格 | 状态 | +| --- | --- | --- | --- | +| TS-8 | chat/embedding 配置、测试、默认标记 | FR-13 | 已完成 | +| TS-8a | provider 归一化与类型差异参数 | FR-13 | 已完成 | + diff --git a/docs/sdd/specs/DV-0008-llm-model-config/verification.md b/docs/sdd/specs/DV-0008-llm-model-config/verification.md new file mode 100644 index 0000000..d76cd06 --- /dev/null +++ b/docs/sdd/specs/DV-0008-llm-model-config/verification.md @@ -0,0 +1,17 @@ +# DV-0008:LLM 模型配置 – 验证(Verification) + +## 自动化测试 +| VER | 测试 | 证明 | 结果 | +| --- | --- | --- | --- | +| VER-2 | test_model_and_vector_configuration.py | FR-13, TS-8 | 通过 | + +## 手工验收清单 +- [x] 新增/编辑/启停 chat 与 embedding 配置 +- [x] 设置默认模型 +- [x] 连通性测试 + +## 结构性证据 +| VER | 证据 | 证明 | +| --- | --- | --- | +| VER-10 | models/llm_model_config.py | FR-13 | + diff --git a/docs/sdd/specs/DV-0009-share-preview/design.md b/docs/sdd/specs/DV-0009-share-preview/design.md new file mode 100644 index 0000000..22ff8ad --- /dev/null +++ b/docs/sdd/specs/DV-0009-share-preview/design.md @@ -0,0 +1,15 @@ +# DV-0009:分享与公开预览 – 设计(Design) + +## 上下文 +`shares.py`、`preview.py`、模型 `share.py`。 + +## 数据模型 +- `share_links`(share_type: project/file、share_code、file_path、access_pass、status)。 + +## 接口设计 +- /api/v1/shares/projects/{id}(settings)、/files/share(文件分享) +- /api/v1/shares/{project|file}/{share_code}/{verify,tree,file,document,export-pdf,assets} + +## 预览 +- 公开只读:树/文档/PDF 导出/资源读取,均以 share_code + 可选密码鉴权。 + diff --git a/docs/sdd/specs/DV-0009-share-preview/spec.md b/docs/sdd/specs/DV-0009-share-preview/spec.md new file mode 100644 index 0000000..08790da --- /dev/null +++ b/docs/sdd/specs/DV-0009-share-preview/spec.md @@ -0,0 +1,24 @@ +# DV-0009:分享与公开预览 – 规格(Spec) + +- **状态**:Implemented + +## 目标 +通过公开分享链接(可带访问密码)让访客浏览项目/文件。 + +## 范围 +- **In**:项目/文件分享链接、密码校验、公开预览树/文档/PDF/资源。 +- **Out**:分享编辑权(分享为只读预览)。 + +## 用户故事 +> 作为访客,我希望通过链接(+密码)预览文档,以便无需账号即可阅读。 + +## 功能需求(FR) +| ID | 需求 | 验收要点 | +| --- | --- | --- | +| FR-14 | 分享链接 + 密码 + 公开预览 | share_code 唯一;密码校验;预览树/文档/导出 | + +## 非功能需求(NFR) +| ID | 需求 | +| --- | --- | +| NFR-4 | 分享访问受密码保护;资源防盗链(鉴权) | + diff --git a/docs/sdd/specs/DV-0009-share-preview/tasks.md b/docs/sdd/specs/DV-0009-share-preview/tasks.md new file mode 100644 index 0000000..7c4b0b1 --- /dev/null +++ b/docs/sdd/specs/DV-0009-share-preview/tasks.md @@ -0,0 +1,7 @@ +# DV-0009:分享与公开预览 – 任务(Tasks) + +| TS(全局/切片) | 切片 | 关联规格 | 状态 | +| --- | --- | --- | --- | +| TS-9 | 项目/文件分享、预览、导出 | FR-14 | 已完成 | +| TS-9a | 分享密码与资源防盗链 | FR-14, NFR-4 | 已完成 | + diff --git a/docs/sdd/specs/DV-0009-share-preview/verification.md b/docs/sdd/specs/DV-0009-share-preview/verification.md new file mode 100644 index 0000000..2d4144c --- /dev/null +++ b/docs/sdd/specs/DV-0009-share-preview/verification.md @@ -0,0 +1,14 @@ +# DV-0009:分享与公开预览 – 验证(Verification) + +## 手工验收清单 +- [x] 创建项目/文件分享链接 +- [x] 密码校验通过后可预览 +- [x] 预览树/文档正常、PDF 导出可用 +- [x] 无密码/密码错误时资源访问受限 + +## 结构性证据 +| VER | 证据 | 证明 | +| --- | --- | --- | +| VER-11 | api/v1/shares.py, preview.py | FR-14 | +| VER-16 | frontend/src/pages/Preview/* | FR-14 | + diff --git a/docs/sdd/specs/DV-0010-notify-log-git-export/design.md b/docs/sdd/specs/DV-0010-notify-log-git-export/design.md new file mode 100644 index 0000000..9aa6a58 --- /dev/null +++ b/docs/sdd/specs/DV-0010-notify-log-git-export/design.md @@ -0,0 +1,17 @@ +# DV-0010:通知 / 日志 / Git / 导出 – 设计(Design) + +## 上下文 +`notifications.py`、`logs.py`、`git_repos.py`、`project_export_service.py`。 + +## 数据模型 +- `notifications`、`operation_logs`、`project_git_repos`。 + +## 接口设计 +- /api/v1/notifications/*(unread-count/read/mark-all/system) +- /api/v1/logs/*(列表/stats) +- /api/v1/projects/{id}/git-repos + /git/{pull,push} +- /api/v1/files/{id}/export-*(ZIP/PDF) + +## 导出 +- `ProjectExportService` 后台线程打包 ZIP,任务带进度/TTL 清理。 + diff --git a/docs/sdd/specs/DV-0010-notify-log-git-export/spec.md b/docs/sdd/specs/DV-0010-notify-log-git-export/spec.md new file mode 100644 index 0000000..811156e --- /dev/null +++ b/docs/sdd/specs/DV-0010-notify-log-git-export/spec.md @@ -0,0 +1,28 @@ +# DV-0010:通知 / 日志 / Git / 导出 – 规格(Spec) + +- **状态**:Implemented +- **关联 ADR**:ADR-0006, ADR-0007 + +## 目标 +提供通知、操作审计日志、Git 仓库集成与 ZIP/PDF 导出能力。 + +## 范围 +- **In**:用户通知、操作日志、Git pull/push、后台导出。 +- **Out**:第三方消息渠道(短信/邮件网关)。 + +## 用户故事 +> 作为用户/管理员,我希望收到系统通知、查看审计日志并按需导出项目内容。 + +## 功能需求(FR) +| ID | 需求 | 验收要点 | +| --- | --- | --- | +| FR-15 | 通知 + 操作日志 | 通知分类;operation_logs 记录用户/类型/资源/IP/UA | +| FR-16 | Git 仓库集成 | 绑定仓库 + pull/push | +| FR-17 | 导出 ZIP/PDF | 后台任务+进度;WeasyPrint PDF | + +## 非功能需求(NFR) +| ID | 需求 | +| --- | --- | +| NFR-7 | 操作入库审计 | +| NFR-11 | export 后台任务同向量化模式(ADR-0006) | + diff --git a/docs/sdd/specs/DV-0010-notify-log-git-export/tasks.md b/docs/sdd/specs/DV-0010-notify-log-git-export/tasks.md new file mode 100644 index 0000000..732140b --- /dev/null +++ b/docs/sdd/specs/DV-0010-notify-log-git-export/tasks.md @@ -0,0 +1,7 @@ +# DV-0010:通知 / 日志 / Git / 导出 – 任务(Tasks) + +| TS(全局/切片) | 切片 | 关联规格 | 状态 | +| --- | --- | --- | --- | +| TS-10 | 通知、日志、Git、导出 | FR-15/16/17 | 已完成 | +| TS-10a | 导出后台任务(进度/TTL) | FR-17, ADR-0006 | 已完成 | + diff --git a/docs/sdd/specs/DV-0010-notify-log-git-export/verification.md b/docs/sdd/specs/DV-0010-notify-log-git-export/verification.md new file mode 100644 index 0000000..e510ded --- /dev/null +++ b/docs/sdd/specs/DV-0010-notify-log-git-export/verification.md @@ -0,0 +1,16 @@ +# DV-0010:通知 / 日志 / Git / 导出 – 验证(Verification) + +## 手工验收清单 +- [x] 通知产生与已读标记 +- [x] 操作日志记录正确 +- [x] Git 仓库绑定与 pull/push +- [x] 项目导出 ZIP 带进度、文档导出 PDF + +## 结构性证据 +| VER | 证据 | 证明 | +| --- | --- | --- | +| VER-10 | models/{notification,log,git_repo}.py | FR-15/16 | +| VER-11 | api/v1/{notifications,logs,git_repos}.py | FR-15/16 | +| VER-12 | services/project_export_service.py | FR-17, ADR-0006 | +| VER-14 | core/migrations.py | ADR-0007, FR-15 | + diff --git a/docs/sdd/specs/DV-0011-mcp-integration/design.md b/docs/sdd/specs/DV-0011-mcp-integration/design.md new file mode 100644 index 0000000..7f6c118 --- /dev/null +++ b/docs/sdd/specs/DV-0011-mcp-integration/design.md @@ -0,0 +1,17 @@ +# DV-0011:MCP 接入 – 设计(Design) + +## 上下文 +`app/mcp/server.py`、`app/mcp/context.py`、模型 `mcp_bot.py`;挂载于 `main.py` 的 `/mcp`。 + +## 数据模型 +- `mcp_bots`(user_id 唯一、bot_id、bot_secret、status、last_used_at)。 + +## 认证 +1. X-Bot-Id 查 mcp_bots → 校验 X-Bot-Secret → 映射到用户 → 以该用户执行工具。 + +## 工具示例 +- list_created_projects、create_project 等;均经权限判定(require_project_read/write_access)。 + +## 挂载 +- `app.mount("/mcp", MCPHeaderAuthApp(mcp_http_app))`;前端 Nginx 不得对 /mcp 301/302。 + diff --git a/docs/sdd/specs/DV-0011-mcp-integration/spec.md b/docs/sdd/specs/DV-0011-mcp-integration/spec.md new file mode 100644 index 0000000..a17688b --- /dev/null +++ b/docs/sdd/specs/DV-0011-mcp-integration/spec.md @@ -0,0 +1,25 @@ +# DV-0011:MCP 接入 – 规格(Spec) + +- **状态**:Implemented +- **关联 ADR**:ADR-0005(可溯源/开放) + +## 目标 +通过 MCP Streamable HTTP 让外部 Agent 以用户身份访问 NexDocs 能力。 + +## 范围 +- **In**:后端内嵌 MCP server、bot 凭据管理、工具暴露。 +- **Out**:独立 MCP 部署(已废弃 mcp_server/)。 + +## 用户故事 +> 作为外部 Agent,我希望用 bot 凭据调用 NexDocs 工具管理项目/文档。 + +## 功能需求(FR) +| ID | 需求 | 验收要点 | +| --- | --- | --- | +| FR-18 | MCP /mcp + X-Bot-Id/Secret 认证 | streamableHttp;bot 映射用户;401 未带凭据 | + +## 非功能需求(NFR) +| ID | 需求 | +| --- | --- | +| NFR-4 | 工具以用户身份 + 权限判定执行 | + diff --git a/docs/sdd/specs/DV-0011-mcp-integration/tasks.md b/docs/sdd/specs/DV-0011-mcp-integration/tasks.md new file mode 100644 index 0000000..e1023dd --- /dev/null +++ b/docs/sdd/specs/DV-0011-mcp-integration/tasks.md @@ -0,0 +1,7 @@ +# DV-0011:MCP 接入 – 任务(Tasks) + +| TS(全局/切片) | 切片 | 关联规格 | 状态 | +| --- | --- | --- | --- | +| TS-11 | MCP server 内嵌 + bot 凭据管理 | FR-18 | 已完成 | +| TS-11a | 工具权限判定 | FR-18, NFR-4 | 已完成 | + diff --git a/docs/sdd/specs/DV-0011-mcp-integration/verification.md b/docs/sdd/specs/DV-0011-mcp-integration/verification.md new file mode 100644 index 0000000..fbf3294 --- /dev/null +++ b/docs/sdd/specs/DV-0011-mcp-integration/verification.md @@ -0,0 +1,15 @@ +# DV-0011:MCP 接入 – 验证(Verification) + +## 手工验收清单 +- [x] 携带 X-Bot-Id/Secret 可调用工具 +- [x] 未带凭据 /mcp 返回 401 +- [x] 工具以用户身份与权限执行 +- [x] 前端不重定向 /mcp + +## 结构性证据 +| VER | 证据 | 证明 | +| --- | --- | --- | +| VER-11 | api/v1/auth.py(mcp-credentials) | FR-18 | +| VER-13 | main.py(/mcp 挂载) | FR-18 | +| 集成 | integrations/mcp.md、integrations/mcp.md | FR-18 | + diff --git a/docs/sdd/specs/README.md b/docs/sdd/specs/README.md new file mode 100644 index 0000000..774dc73 --- /dev/null +++ b/docs/sdd/specs/README.md @@ -0,0 +1,27 @@ +# 功能规格索引(Specs) + +本目录登记每个功能/变更单元(DV)的四文件规格:**spec(为什么/做什么)、design(怎么做)、tasks(实施切片)、verification(验收证据)**。 + +## 索引(规格 ↔ 任务 ↔ 证据) + +| DV | 单元 | 主要规格(FR) | 关键任务(TS) | 关键证据(VER) | 状态 | +| --- | --- | --- | --- | --- | --- | +| [DV-0001](DV-0001-auth/spec.md) | 认证与会话 | FR-1 | TS-1 | VER-10/11/15 | Implemented | +| [DV-0002](DV-0002-project-filesystem/spec.md) | 项目与文件系统 | FR-2/3/5 | TS-2 | VER-10/11/12 | Implemented | +| [DV-0003](DV-0003-document-editing/spec.md) | 文档编辑与文件操作 | FR-4 | TS-3 | VER-11/12/16 | Implemented | +| [DV-0004](DV-0004-rbac-admin/spec.md) | RBAC 与系统管理 | FR-6/7/8 | TS-4 | VER-10/11/16 | Implemented | +| [DV-0005](DV-0005-fulltext-search/spec.md) | 全文检索 | FR-9 | TS-5 | VER-3/12 | Implemented | +| [DV-0006](DV-0006-zvec-vectorization/spec.md) | ZVec 向量化 | FR-10/11 | TS-6 | VER-2/10/12 | Implemented | +| [DV-0007](DV-0007-rag-chat/spec.md) | 知识库 RAG 对话 | FR-12/19 | TS-7 | VER-1/11/12/16 | Implemented | +| [DV-0008](DV-0008-llm-model-config/spec.md) | LLM 模型配置 | FR-13 | TS-8 | VER-2/10 | Implemented | +| [DV-0009](DV-0009-share-preview/spec.md) | 分享与公开预览 | FR-14 | TS-9 | VER-11/16 | Implemented | +| [DV-0010](DV-0010-notify-log-git-export/spec.md) | 通知/日志/Git/导出 | FR-15/16/17 | TS-10 | VER-10/11/12/14 | Implemented | +| [DV-0011](DV-0011-mcp-integration/spec.md) | MCP 接入 | FR-18 | TS-11 | VER-11/13 | Implemented | + +> 说明:状态为 SDD 核对仓库实现后的推断。DOC 中列举的 TS 编号沿用原 SDD 单文件版的全局编号,spec 内亦给出所属 DV 的切片编号。 + +## 新建规格流程 +1. 复制 `_template/` 到 `DV-NNNN-short-name/`。 +2. 按 governance 申请编号、过审。 +3. 补齐四文件后回填本索引。 + diff --git a/docs/sdd/specs/_template/design.md b/docs/sdd/specs/_template/design.md new file mode 100644 index 0000000..dabd53f --- /dev/null +++ b/docs/sdd/specs/_template/design.md @@ -0,0 +1,20 @@ +# DV-NNNN:<功能名> – 设计(Design) + +## 上下文 +- 涉及模块、数据流、依赖。 + +## 结构设计 +- 代码/模块组织。 + +## 数据模型 +- 涉及表/字段(指向 DATABASE.md 细节)。 + +## 接口设计 +- API 端点 / 交互。 + +## 状态与降级 +- 边界情况、健壮降级(对齐 NFR-10)。 + +## 变更影响 +- 对既有 DV/ADR 的影响。 + diff --git a/docs/sdd/specs/_template/spec.md b/docs/sdd/specs/_template/spec.md new file mode 100644 index 0000000..8eb941c --- /dev/null +++ b/docs/sdd/specs/_template/spec.md @@ -0,0 +1,31 @@ +# DV-NNNN:<功能名> – 规格(Spec) + +- **状态**:Draft | Review | Approved | Implemented | Verified +- **关联 ADR**:ADR-NNNN + +## 目标(为什么做) +一段话说明该功能要解决的业务问题或带来的价值(对齐 PO)。 + +## 范围 +- **In**:…… +- **Out**:…… + +## 用户故事 +> 作为 <角色>,我希望 <能力>,以便 <收益>。 + +## 功能需求(FR) +| ID | 需求描述 | 验收要点 | +| --- | --- | --- | +| FR-N | … | … | + +## 非功能需求(NFR) +| ID | 需求 | +| --- | --- | +| NFR-N | … | + +## 边界与约束 +- 约束(技术/数据/权限)。 + +## 开放问题 +- 占位。 + diff --git a/docs/sdd/specs/_template/tasks.md b/docs/sdd/specs/_template/tasks.md new file mode 100644 index 0000000..1010493 --- /dev/null +++ b/docs/sdd/specs/_template/tasks.md @@ -0,0 +1,10 @@ +# DV-NNNN:<功能名> – 任务(Tasks) + +| TS | 切片 | 关联规格 | 依赖 | 状态 | +| --- | --- | --- | --- | --- | +| TS-N | … | FR-N | … | 未开始 | + +## 任务规则 +- 每个切片可独立评审/合并。 +- 完成勾选并同步更新 verification。 + diff --git a/docs/sdd/specs/_template/verification.md b/docs/sdd/specs/_template/verification.md new file mode 100644 index 0000000..756fd46 --- /dev/null +++ b/docs/sdd/specs/_template/verification.md @@ -0,0 +1,17 @@ +# DV-NNNN:<功能名> – 验证(Verification) + +## 自动化测试 +| VER | 测试 | 证明规格/任务 | 结果 | +| --- | --- | --- | --- | +| VER-N | … | FR-N / TS-N | 通过/未跑 | + +## 手工验收清单 +- [ ] 场景 1 +- [ ] 场景 2 + +## 结构性证据 +- 涉及文件/模块。 + +## 已知缺口 +- 说明未覆盖项(可引用 OI-3)。 + diff --git a/frontend/package-lock.json b/frontend/package-lock.json index 166db26..c42b635 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -1,12 +1,12 @@ { "name": "nex-docus-frontend", - "version": "1.0.0", + "version": "0.9.9", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "nex-docus-frontend", - "version": "1.0.0", + "version": "0.9.9", "dependencies": { "@ant-design/icons": "^5.2.6", "@bytemd/plugin-breaks": "^1.22.0", diff --git a/frontend/package.json b/frontend/package.json index 70ee76d..51c3d87 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -1,7 +1,7 @@ { "name": "nex-docus-frontend", "private": true, - "version": "1.0.0", + "version": "0.9.9", "type": "module", "scripts": { "dev": "vite",