|
|
||
|---|---|---|
| .. | ||
| app | ||
| scripts | ||
| tests | ||
| .dockerignore | ||
| .gitignore | ||
| Dockerfile | ||
| README.md | ||
| main.py | ||
| pytest.ini | ||
| requirements-dev.txt | ||
| requirements.txt | ||
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_HOSTDB_USERDB_PASSWORDDB_NAME、REDIS_HOSTREDIS_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)
必须知道的实现约定
- 新增模型要在
app/models/__init__.py里导入。 只建表逻辑而不导入,Base.metadata就看不到该表,init_db.py会静默漏建表,线上表现为Table ... doesn't exist。 - 项目权限只走
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。 - 异步 Session 配了
expire_on_commit=False,但onupdate=func.now()的列(如updated_at)在 UPDATE 提交后仍会被标记过期;提交后若还要序列化整个 ORM 对象,必须await db.refresh(obj),否则会在异步上下文触发同步 IO 抛MissingGreenlet(HTTP 500)。 - 统一响应用
app/schemas/response.py的success_response();业务错误抛HTTPException并用 4xx 表达(不要用 500 表达"参数/状态不合法")。 - SSE 接口(
/chat)要求网关关闭响应缓冲,见docs/deploy/README.md的 nginx 示例。 - 本地向量模型放在
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。