nex_docus/backend
mula.liu 6831bd4831 解决编辑模式的问题 2026-10-01 15:21:38 +08:00
..
app 解决编辑模式的问题 2026-10-01 15:21:38 +08:00
scripts 解决编辑模式的问题 2026-10-01 15:21:38 +08:00
tests 解决编辑模式的问题 2026-10-01 15:21:38 +08:00
.dockerignore v0.9.9 2026-08-04 16:40:13 +08:00
.gitignore 0.9.1 2025-12-20 19:18:59 +08:00
Dockerfile 解决环境中的git调用 2026-08-25 18:50:47 +08:00
README.md 解决编辑模式的问题 2026-10-01 15:21:38 +08:00
main.py 解决编辑模式的问题 2026-10-01 15:21:38 +08:00
pytest.ini 解决编辑模式的问题 2026-10-01 15:21:38 +08:00
requirements-dev.txt 解决编辑模式的问题 2026-10-01 15:21:38 +08:00
requirements.txt 修改了mcp接口,增加了项目创建接口 2026-08-07 16:31:54 +08:00

README.md

NEX Docus 后端

FastAPI + SQLAlchemy 2.0(异步)+ MySQL + Redis 的文档管理后端,同时提供 RAG 知识库问答与 MCP 服务。

上手请先看 docs/quickstart.md(一键启动、环境变量、初始化、常见问题)。 部署/运维见 docs/deploy/README.md,表结构见 docs/database.md。 本文件只描述后端代码内部结构与开发约定。

技术栈

用途 选型
Web 框架 FastAPI + Uvicorn
ORM SQLAlchemy 2.0 异步(aiomysql),Alembic 迁移
数据库 / 缓存 MySQL 8(utf8mb4)/ Redis
认证 JWT(python-jose)+ bcrypt(passlib)
全文检索 Whoosh 3 + jieba 分词
向量检索 ZVec(远端 Embedding 或本地 Sentence-Transformers)
文件与导出 aiofiles、自研 Markdown/PDF 导出服务
Git 同步 通过命令行调用 git(主机需自行安装)
测试 pytest + pytest-asyncio

目录结构

backend/
├── app/
│   ├── api/v1/            # HTTP 路由(前缀 /api/v1),__init__.py 汇总注册
│   ├── core/              # config / database / deps / security / enums / migrations / redis_client
│   ├── mcp/               # MCP server 与请求上下文(挂载在 /mcp)
│   ├── models/            # SQLAlchemy 模型(__init__.py 必须导入全部模型,见下方陷阱)
│   ├── schemas/           # Pydantic Schema 与统一响应包装
│   └── services/          # 业务逻辑:project/file/search/rag/zvec/git/vectorization/notification/log/storage/llm…
├── scripts/               # init_db.py(建表+种子数据)、generate_password.py,详见 scripts/README.md
├── tests/                 # pytest 用例
├── models/                # 本地向量模型目录(gitignore,需自行放置 HF 模型,如 m3e-small)
├── main.py                # 应用入口:/api/v1 路由、/mcp 挂载、/ 与 /health
├── requirements.txt       # 运行依赖
├── requirements-dev.txt   # 开发/测试依赖(含 pytest)
├── pytest.ini             # testpaths=tests, pythonpath=.
└── .env                   # 本地配置(不入库;键名见下表)

路由一览

main.py 暴露:GET /(名称/版本/状态)、GET /health({"status":"healthy"})、/docs、/openapi.json、/mcp(MCP Streamable HTTP,需 X-Bot-Id / X-Bot-Secret)。

app/api/v1/__init__.py 注册的子路由前缀:

前缀 模块 说明
/auth auth 登录、当前用户、资料/密码/头像、MCP 凭证签发与轮换
/projects projects 项目 CRUD、成员、所有权转移、分享开关、Git pull/push 与目录选择
(同 /projects/{id}/git-repos) git_repos 仓库配置的增删改查与连通性测试(路由内部自带前缀)
/files files 目录树、读写文件、文件操作、上传、导入导出、PDF 导出、文档与静态资源流式访问
/preview preview 项目预览
/shares shares 分享链接创建/校验/访问
/search search 全文 + 向量双引擎检索
/chat chat 会话管理、SSE 流式问答、引用与中断
/llm-model-configs llm_model_configs chat / embedding 模型配置与连通性测试
/dashboard dashboard 管理员统计
/users /roles /role-permissions /menu users/roles/role_permissions/menu 用户、角色、角色权限、菜单树
/notifications notifications 站内通知
/logs logs 系统日志查询

环境变量(backend/.env)

完整键表与说明见 docs/quickstart.md;此处只列必填项与常见坑:

  • 必填:DB_HOST DB_USER DB_PASSWORD DB_NAME、REDIS_HOST REDIS_PASSWORD、SECRET_KEY。
  • 文件存储:STORAGE_ROOT / PROJECTS_PATH / USERS_PATH / TEMP_PATH(本地开发用这组绝对路径;Docker 部署用根 .env 的 STORAGE_PATH,两套体系不同,别混用)。
  • DEBUG=True 时 SQLAlchemy 会打印全量 SQL,生产必须 false。
  • DB_PASSWORD 含特殊字符无需手动转义(连接串构造时已 quote_plus)。

⚠️ 不要在代码、文档或提交里写真实环境的账号密码。 需要示例时用占位值(如 password_change_me)。

开发命令

cd backend
python3 -m venv venv
./venv/bin/pip install -r requirements-dev.txt   # 含运行依赖 + pytest
cp .env.example .env                             # 若无,按 docs/quickstart.md 的键表创建

./venv/bin/python scripts/init_db.py             # 建表 + 种子数据(幂等)
./venv/bin/python scripts/generate_password.py   # 生成 bcrypt 哈希
./venv/bin/python -m pytest                      # 单元测试
./venv/bin/uvicorn main:app --reload --port 8000 # 单独起服务(推荐用仓库根 ./scripts/start.sh)

必须知道的实现约定

  1. 新增模型要在 app/models/__init__.py 里导入。 只建表逻辑而不导入,Base.metadata 就看不到该表,init_db.py 会静默漏建表,线上表现为 Table ... doesn't exist。
  2. 项目权限只走 app/services/project_service.py(require_project_read_access / require_project_write_access / normalize_project_role)。不要在路由里手写角色判断:历史数据里 project_members.role 存在大写(ADMIN/EDITOR/VIEWER),直接 == "admin" 比较会静默失效。返回给前端的角色必须先 normalize_project_role。
  3. 异步 Session 配了 expire_on_commit=False,但 onupdate=func.now() 的列(如 updated_at)在 UPDATE 提交后仍会被标记过期;提交后若还要序列化整个 ORM 对象,必须 await db.refresh(obj),否则会在异步上下文触发同步 IO 抛 MissingGreenlet(HTTP 500)。
  4. 统一响应用 app/schemas/response.py 的 success_response();业务错误抛 HTTPException 并用 4xx 表达(不要用 500 表达"参数/状态不合法")。
  5. SSE 接口(/chat)要求网关关闭响应缓冲,见 docs/deploy/README.md 的 nginx 示例。
  6. 本地向量模型放在 backend/models/<模型名>/(含 config.json、1_Pooling/config.json、model.safetensors 或 pytorch_model.bin),由 LocalEmbeddingService 扫描列出;该目录已 gitignore,不要提交。

测试

cd backend && ./venv/bin/python -m pytest

覆盖范围(v1.0.0):项目权限与角色归一化、Git 服务命令构造、搜索服务、模型与向量配置、RAG 引用解析。前端目前没有自动化测试,界面回归需手工验证,重点清单见 docs/sdd/releases/v1.0.0.md。