3397 lines
158 KiB
Markdown
3397 lines
158 KiB
Markdown
# aurak 文档
|
||
|
||
> 生成于: 2026年08月05日 11:04
|
||
> 模板: detailed (36 页)
|
||
> 引擎: RAG + LLM
|
||
|
||
---
|
||
|
||
## 目录
|
||
|
||
- [1.1 编写目的](#11-编写目的)
|
||
- [1.2 背景](#12-背景)
|
||
- [1.3 定义](#13-定义)
|
||
- [1.4 参考资料](#14-参考资料)
|
||
- [2.1 需求概述](#21-需求概述)
|
||
- [2.2 技术选型](#22-技术选型)
|
||
- [2.3 软件结构](#23-软件结构)
|
||
- [3.1 功能清单](#31-功能清单)
|
||
- [3.2 流程逻辑](#32-流程逻辑)
|
||
- [3.3 核心业务](#33-核心业务)
|
||
- [4.1 表详细设计](#41-表详细设计)
|
||
- [4.2 主键与外键策略](#42-主键与外键策略)
|
||
- [4.3 索引设计](#43-索引设计)
|
||
- [4.4 存储分配](#44-存储分配)
|
||
- [5.1 外部接口](#51-外部接口)
|
||
- [5.2 内部接口](#52-内部接口)
|
||
- [5.3 数据格式](#53-数据格式)
|
||
- [6.1 布局与导航](#61-布局与导航)
|
||
- [6.2 组件](#62-组件)
|
||
- [6.3 状态管理](#63-状态管理)
|
||
- [7.1 认证与授权](#71-认证与授权)
|
||
- [7.2 传输安全](#72-传输安全)
|
||
- [7.3 输入验证](#73-输入验证)
|
||
- [7.4 数据库安全](#74-数据库安全)
|
||
- [7.5 审计与日志](#75-审计与日志)
|
||
- [8.1 环境配置](#81-环境配置)
|
||
- [8.2 容器化](#82-容器化)
|
||
- [8.3 监控与日志](#83-监控与日志)
|
||
- [8.4 故障排查](#84-故障排查)
|
||
- [9.1 单元测试](#91-单元测试)
|
||
- [9.2 集成测试](#92-集成测试)
|
||
- [9.3 E2E 测试](#93-e2e-测试)
|
||
- [10.1 代码风格](#101-代码风格)
|
||
- [10.2 分支与提交规范](#102-分支与提交规范)
|
||
- [10.3 环境变量清单](#103-环境变量清单)
|
||
- [10.4 变更记录](#104-变更记录)
|
||
|
||
---
|
||
## 1. 引言
|
||
|
||
### 1.1 编写目的
|
||
|
||
#### 文档目的
|
||
本文档为 **AuraK 企业级 AI 知识库与人才评估平台** 的完整技术参考手册,旨在为不同角色的读者提供准确、可执行的系统说明。
|
||
|
||
##### 编写背景
|
||
AuraK 是一个集多租户管理、基于角色的访问控制(RBAC)、AI 智能评估、知识库管理、多模型 AI 引擎及飞书机器人集成于一体的企业级平台。系统采用前后端分离架构,后端基于 NestJS 构建,前端使用 React 与 Vite,并依赖 Elasticsearch、Tika、LibreOffice 等基础服务组件。
|
||
|
||
随着系统功能模块持续扩展(当前已涵盖 20 余个业务模块、26 项细粒度权限、多套评估模板及完整的租户隔离机制),亟需一份系统性的技术文档,以统一开发、测试、运维及二次开发人员对系统架构与实现细节的理解。
|
||
|
||
##### 编写目的
|
||
本文档主要实现以下目标:
|
||
|
||
1. **架构说明**:阐述系统的整体架构设计,包括多租户数据隔离机制、RBAC 三级权限体系(SUPER_ADMIN / TENANT_ADMIN / USER)、AI 评估工作流(自动出题、自适应追问、多维加权评分)以及知识库双通道处理(Tika 快速解析与 Vision Pipeline 高精度解析)。
|
||
|
||
2. **开发指导**:为后端(NestJS + TypeORM + SQLite/Elasticsearch)与前端(React + Vite + TailwindCSS)开发人员提供模块划分、实体关系、服务接口及代码约定的详细说明,降低新成员上手成本。
|
||
|
||
3. **部署与运维参考**:提供基于 Docker Compose 的基础设施编排(Elasticsearch、Tika、LibreOffice)、Nginx 反向代理与 SSL 配置、环境变量说明及常见运维操作指引。
|
||
|
||
4. **测试规范**:汇总现有测试体系(Playwright E2E、Jest 单元测试、API 冒烟测试脚本),明确测试覆盖范围与执行方式。
|
||
|
||
##### 预期读者
|
||
本文档面向以下读者群体:
|
||
|
||
| 读者角色 | 关注重点 | 建议章节 |
|
||
|---|---|---|
|
||
| 后端开发工程师 | 模块划分、实体关系、API 设计、权限守卫流程、AI 评估图编排 | 架构设计、数据模型、API 参考、AI 评估引擎 |
|
||
| 前端开发工程师 | 页面路由、组件结构、服务调用方式、状态管理 | 前端架构、页面功能说明 |
|
||
| 测试工程师 | 测试计划、E2E 用例、接口测试脚本、性能验证方法 | 测试指南 |
|
||
| 运维工程师 | 部署拓扑、Docker 编排、环境配置、日志与监控 | 部署与运维 |
|
||
| 技术管理者 | 系统能力边界、安全模型、扩展性设计 | 系统概述、安全模型 |
|
||
|
||
##### 文档范围
|
||
本文档覆盖 AuraK 系统的全部核心子系统,包括但不限于:
|
||
|
||
- **认证与权限**:JWT 认证、API Key 机制、多级权限守卫、角色与权限实体
|
||
- **多租户**:租户中间件、数据隔离订阅器、租户成员与设置管理
|
||
- **AI 评估**:评估模板、题库管理、图编排(分析→生成→追问→评分)、证书系统
|
||
- **知识库**:文档解析(Tika/OCR/Vision Pipeline)、文本分块、向量化与混合检索(BM25 + 向量)
|
||
- **AI 引擎**:多模型接入(OpenAI 兼容 + Gemini)、Embedding/Rerank/Vision 模型配置、SSE 流式输出
|
||
- **飞书集成**:WebSocket 网关、交互式消息卡片、移动端评估会话
|
||
- **基础功能**:笔记管理、搜索历史、导入任务、模型配置、系统设置
|
||
|
||
> 注:各模块的详细 API 端点、数据库表结构及错误码说明,请分别参阅本文档对应章节。
|
||
|
||
### 1.2 背景
|
||
|
||
#### 项目定位
|
||
AuraK 是一款面向企业的 AI 知识库与人才评估平台,定位为将知识管理与人才能力评估相结合的一体化解决方案。项目名称中的 "Aura" 寓意平台能够洞察用户的能力特质,"K" 代表 Knowledge(知识),整体体现了"以知识为基础、以评估为手段"的产品理念。
|
||
|
||
#### 核心业务能力
|
||
平台围绕六大核心能力构建,覆盖企业知识管理与人才评估的完整链路:
|
||
|
||
| 能力领域 | 核心功能 |
|
||
|---------|---------|
|
||
| 多租户架构 | 严格的数据隔离、层级化组织树、租户级独立配置 |
|
||
| 权限体系(RBAC) | 三级角色(超级管理员/租户管理员/普通用户)、26 项细粒度权限、自定义角色与可视化权限矩阵 |
|
||
| AI 智能评估 | 自动出题(选择题+简答题)、自适应追问对话、加权多维度评分、证书颁发系统 |
|
||
| 知识库管理 | 双通道文档处理(Tika 快速解析 / Vision Pipeline 高精度解析)、混合检索(BM25 + 向量)、多格式文件支持 |
|
||
| AI 引擎 | 多模型接入(兼容 OpenAI 协议及 Gemini)、可配置的 LLM/Embedding/Rerank/Vision 模型、SSE 流式输出 |
|
||
| 飞书机器人 | WebSocket 集成、交互式消息卡片、移动端评估能力 |
|
||
|
||
#### 技术架构概览
|
||
平台采用前后端分离架构,后端基于 NestJS 框架构建,前端使用 React 技术栈。系统集成 Elasticsearch 实现全文检索与向量检索,通过 Tika 与 LibreOffice 服务完成文档解析与格式转换,并引入 LangChain 图编排引擎驱动 AI 评估流程。
|
||
|
||
##### 后端核心模块
|
||
- **评估引擎**:基于 LangChain 图结构编排,包含题目生成器、面试官节点、评分节点与分析器节点,支持多轮对话式评估
|
||
- **知识库服务**:提供文档导入、文本分块、向量化、混合检索及重排序能力
|
||
- **租户与权限**:实现多租户数据隔离、基于角色的访问控制及细粒度权限管理
|
||
- **飞书集成**:支持机器人绑定、WebSocket 长连接及评估指令解析
|
||
|
||
##### 前端应用
|
||
前端提供知识库管理、AI 对话、评估考试、笔记管理、插件配置等完整工作台界面,并内置多语言支持(中文/英文/日文)。
|
||
|
||
#### 内置评估模板
|
||
平台预置两套评估模板,覆盖技术与非技术两类岗位场景:
|
||
|
||
| 模板 | 题目数量 | 评估维度 | 适用人群 |
|
||
|------|---------|---------|---------|
|
||
| 技术类 | 20 题 | PROMPT 30%、LLM 30%、IDE 20%、DEV_PATTERN 20% | 开发工程师 |
|
||
| 非技术类 | 10 题 | PROMPT 50%、LLM 30%、WORK_CAPABILITY 20% | 管理者、产品经理、设计师 |
|
||
|
||
评估维度支持完全自定义,用户可根据实际需求增删维度、调整权重及修改题目数量。
|
||
|
||
#### 部署与快速启动
|
||
平台支持 Docker Compose 一键启动基础设施(Elasticsearch、Tika、LibreOffice),也支持无 Docker 环境下的轻量启动模式。默认提供管理员账号(admin/admin123)便于快速体验。
|
||
|
||
#### 文档体系
|
||
项目根目录提供面向 AI 辅助开发工具的完整技术参考文档(CLAUDE.md),涵盖架构细节、权限实体、守卫流程、评估数据模型、测试模式及代码规范。`docs/` 目录下另存有系统概览、评估流程分析、测试报告及实施计划等补充材料。
|
||
|
||
> 关于评估引擎的图编排细节、权限体系的具体实现及 API 端点定义,将在后续章节中分别展开说明。
|
||
|
||
### 1.3 定义
|
||
|
||
#### 核心业务概念
|
||
| 术语 | 定义 |
|
||
|---|---|
|
||
| **知识库(Knowledge Base)** | 系统管理的文档集合,支持多格式文件导入,通过 Tika 或视觉流水线进行解析处理,并支持混合检索(BM25 + 向量)。 |
|
||
| **多租户(Multi-Tenant)** | 严格的数据隔离机制,通过层级化组织树管理租户,每个租户拥有独立的设置与数据边界。 |
|
||
| **租户(Tenant)** | 系统中的一个独立组织或团队,拥有自己的成员、设置与数据空间,与其他租户数据完全隔离。 |
|
||
| **角色(Role)** | 权限的集合,系统内置超级管理员、租户管理员、普通用户三种固定角色,并支持自定义角色。 |
|
||
| **权限(Permission)** | 系统中最细粒度的操作授权单元,共 26 项,按类别组织成权限矩阵,可分配给角色。 |
|
||
| **权限矩阵(Permission Matrix)** | 以可视化方式展示角色与权限对应关系的界面,用于批量配置角色权限。 |
|
||
| **评估(Assessment)** | 系统核心功能之一,通过 AI 自动出题、苏格拉底式追问、多维度加权评分对员工进行能力测评。 |
|
||
| **评估模板(Assessment Template)** | 定义评估的题目数量、维度及权重配置的模板,系统内置技术类与非技术类两套模板,维度可自定义。 |
|
||
| **评估会话(Assessment Session)** | 一次完整的评估过程实例,包含答题记录、对话历史与评分结果。 |
|
||
| **题库(Question Bank)** | 评估题目的集合,支持按类型、难度、维度等属性管理题目,题目可来源于 AI 生成或人工录入。 |
|
||
| **题目维度(Question Dimension)** | 评估题目的分类维度,包括提示词工程、大语言模型、IDE、开发模式、工作能力等。 |
|
||
| **证书(Certificate)** | 评估通过后系统颁发的电子证明,记录评估结果与达成情况。 |
|
||
| **飞书机器人(Feishu Bot)** | 通过 WebSocket 与飞书集成的机器人,支持交互式消息卡片与移动端评估。 |
|
||
|
||
#### AI 与检索相关术语
|
||
| 术语 | 定义 |
|
||
|---|---|
|
||
| **RAG(检索增强生成)** | 在生成回答前先从知识库检索相关文本片段,作为上下文提供给大语言模型,以提升回答的准确性。 |
|
||
| **混合检索(Hybrid Search)** | 同时使用 BM25 关键词检索与向量语义检索,融合两种结果以提升召回质量。 |
|
||
| **向量嵌入(Embedding)** | 将文本转换为高维向量表示,用于语义相似度计算与向量检索。 |
|
||
| **重排序(Rerank)** | 对检索结果进行二次排序,将最相关的文本片段排在前面,提升最终输入给模型的上下文质量。 |
|
||
| **文本分块(Text Chunking)** | 将长文档切分为较小的文本片段,便于向量化与检索。 |
|
||
| **视觉流水线(Vision Pipeline)** | 高精度文档解析方案,通过视觉模型识别文档版面与内容,适用于复杂格式文档。 |
|
||
| **OCR(光学字符识别)** | 从扫描件或图片中提取文字的技术,系统内置中文、英文、日文等多语言识别模型。 |
|
||
| **大语言模型(LLM)** | 系统 AI 能力的核心引擎,支持 OpenAI 兼容接口与 Gemini 多模型配置。 |
|
||
|
||
#### 架构与流程术语
|
||
| 术语 | 定义 |
|
||
|---|---|
|
||
| **LangGraph 图编排** | 评估流程采用图结构编排,包含题目生成器、面试官、评分器等节点,通过状态对象在各节点间流转数据。 |
|
||
| **短时记忆(Short-term Memory)** | 评估过程中通过对话历史与评分状态实现的上下文记忆,支撑多轮追问。 |
|
||
| **长时记忆(Long-term Memory)** | 通过业务数据库持久化存储的评估结果与用户数据,支撑历史追溯与持续学习。 |
|
||
| **SSE 流式输出(Server-Sent Events)** | 服务端向客户端实时推送 AI 生成内容的机制,用于聊天与评估过程中的流式响应。 |
|
||
| **WebSocket 集成** | 飞书机器人通过 WebSocket 与飞书平台保持长连接,实现实时消息收发。 |
|
||
|
||
> 说明:权限模型与角色体系的详细设计见「权限与安全」章节;评估流程的图编排细节见「评估引擎」章节。
|
||
|
||
### 1.4 参考资料
|
||
|
||
#### 项目文档
|
||
- **README.md / README_ZH.md**:项目的中英文简介,涵盖功能特性总览(多租户、RBAC 权限、AI 评测、知识库、AI 引擎、飞书机器人)、快速启动指南、默认登录账号及用户操作手册(用户管理、权限管理、评测模板配置、考试流程与结果查看)。
|
||
|
||
- **CLAUDE.md / AGENTS.md**:面向 AI 辅助开发工具的完整技术参考,详细记录了系统架构、权限实体与守卫流程、评测数据模型、测试模式及代码规范,是开发者理解系统内部机制的核心文档。
|
||
|
||
- **VERSION.md**:版本信息文件,记录当前发布版本号及版本历史。
|
||
|
||
- **LICENSE**:项目开源许可证文件。
|
||
|
||
#### 架构与设计文档
|
||
- **docs/system-overview.html / docs/system-overview-zh.html**:系统总体架构概览(中英文版本),以可视化方式呈现前后端模块划分、服务间依赖关系及核心数据流。
|
||
|
||
- **docs/military-simulation-ai-solution.html**:面向军事仿真场景的 AI 解决方案设计文档,描述该场景下的系统适配方案。
|
||
|
||
- **docs/3.0/talent_assessment_workflow.md**:人才评测智能体工作流程详述,涵盖基于 LangGraph 的四阶段核心流程(出题、交互引导、智能阅卷、综合分析)、状态定义与节点逻辑、前端交互流、数据持久化机制,以及面向大规模知识库的四种合理提取策略(语义聚类、动态 RAG 检索、优先级权重采样、层次化提取)。
|
||
|
||
- **docs/3.0/employee_evaluation_agent_analysis.md**:员工评测智能体分析文档,对评测智能体的实现方案进行深入剖析。
|
||
|
||
- **docs/assessment-screen-map.md**:评测功能页面映射表,梳理前端各评测界面与后端接口的对应关系。
|
||
|
||
- **docs/plans/2026-04-23-assessment-system-full-plan-v2.md**:评测系统完整实施计划(第二版),包含里程碑规划、任务分解与交付物定义。
|
||
|
||
#### 测试文档
|
||
- **docs/tests/AuraK-最终测试报告.md / AuraK-测试报告.md**:AuraK 系统最终版及历史版本的测试报告,汇总功能测试、回归测试结果与缺陷统计。
|
||
|
||
- **docs/tests/complete-test-framework.md**:完整测试框架说明,定义端到端测试、组件测试与单元测试的组织方式。
|
||
|
||
- **docs/tests/assessment-test-plan.md**:评测功能专项测试计划,覆盖评测全流程的测试用例设计。
|
||
|
||
- **docs/tests/playwright-agent-plan.md / playwright-agent-map.md / playwright-test-template.md**:基于 Playwright 的自动化测试方案,包括测试代理规划、页面元素映射及测试用例模板。
|
||
|
||
- **docs/tests/user-story-matrix.md**:用户故事矩阵,将业务需求映射到测试场景。
|
||
|
||
- **docs/tests/agent-deep-use-plan.md**:AI 代理深度使用计划,描述利用 AI 代理进行自动化测试与代码审查的实践方案。
|
||
|
||
#### 子模块说明
|
||
- **server/README.md**:后端服务说明文档,涵盖 NestJS 服务启动方式、环境变量配置及模块结构。
|
||
|
||
- **web/README.md**:前端应用说明文档,描述 React 前端的技术栈、开发命令与构建方式。
|
||
|
||
- **libreoffice-server/README.md**:LibreOffice 转换服务说明,用于文档格式转换(如 Markdown 转 PDF)的独立微服务。
|
||
|
||
- **nginx/README.md**(源码中未提供):Nginx 反向代理配置说明,包含 SSL 证书生成脚本与站点配置。
|
||
|
||
#### 代码审查与质量
|
||
- **code-review-knowledge-base.md**:代码审查知识库,沉淀项目代码审查的最佳实践与常见问题清单。
|
||
|
||
- **check-result.mjs / do-assessment.mjs / qa-assessment-flow.mjs**:项目质量评估与检查脚本,用于自动化执行代码规范校验与功能冒烟测试。
|
||
|
||
> 关于系统 API 的详细端点定义、请求参数与响应格式,请参阅“接口文档”章节。
|
||
|
||
## 2. 系统概述
|
||
|
||
### 2.1 需求概述
|
||
|
||
#### 项目定位与业务背景
|
||
AuraK 是一款面向企业的 AI 知识库与人才评估一体化平台。系统围绕两大核心业务场景构建:一是为企业提供多格式文档的知识管理与智能检索能力,二是通过 AI 驱动的自适应测评引擎,实现人才能力的自动化评估与认证。平台采用多租户架构,支持组织层级化管理,并可通过飞书机器人将测评能力延伸至移动端。
|
||
|
||
#### 功能性需求
|
||
##### 多租户与组织管理
|
||
- **租户隔离**:系统实现严格的数据隔离机制,确保不同租户之间的数据互不可见。
|
||
- **组织树**:支持层级化组织架构管理,租户成员与租户设置独立管理。
|
||
- **默认租户**:系统内置默认租户,降低初始部署与使用门槛。
|
||
|
||
##### 用户与权限管理
|
||
- **三级角色体系**:内置超级管理员(SUPER_ADMIN)、租户管理员(TENANT_ADMIN)、普通用户(USER)三种系统角色。
|
||
- **细粒度权限控制**:提供 26 项细粒度权限点,覆盖系统各功能模块的操作控制。
|
||
- **自定义角色**:支持创建自定义角色,并通过可视化权限矩阵为角色分配权限。
|
||
- **用户全生命周期管理**:支持用户的创建、编辑、删除、密码修改,以及 XLSX 格式的批量导入与导出。
|
||
- **即时生效**:角色或权限变更后立即生效,无需用户重新登录。
|
||
|
||
##### AI 人才评估
|
||
- **自动出题**:系统根据评估模板自动生成题目,题型包括单选题与简答题。
|
||
- **自适应追问**:AI 面试官可根据候选人的回答进行多轮追问,深入考察能力。
|
||
- **多维度加权评分**:评估结果按多个能力维度进行加权计算,输出综合评分。
|
||
- **证书体系**:评估完成后自动生成电子证书,记录评估结果。
|
||
- **评估模板**:内置技术类与非技术类两套模板,支持自定义维度、权重与题目数量。
|
||
- **飞书机器人集成**:通过 WebSocket 与飞书深度集成,支持交互式消息卡片,实现移动端测评。
|
||
|
||
##### 知识库管理
|
||
- **多格式文档处理**:支持多种文档格式的上传与解析,包括 PDF、图片等。
|
||
- **双通道处理**:提供快速处理(基于 Tika)与高精度处理(基于视觉流水线)两种文档解析通道。
|
||
- **混合检索**:结合 BM25 关键词检索与向量检索,提升检索准确率。
|
||
- **知识分组**:支持知识库的分组管理,便于组织与检索。
|
||
- **文本分块与嵌入**:支持自定义分块配置,并通过嵌入模型生成向量索引。
|
||
|
||
##### AI 引擎与模型管理
|
||
- **多模型支持**:兼容 OpenAI 协议与 Gemini 协议,支持多种大语言模型接入。
|
||
- **模型可配置**:支持对 LLM、Embedding、Rerank、Vision 等模型进行独立配置。
|
||
- **流式输出**:支持 SSE 流式响应,提升交互体验。
|
||
|
||
##### 其他功能
|
||
- **笔记管理**:支持笔记的创建、分类与检索。
|
||
- **搜索历史**:记录用户搜索与聊天历史,便于回溯。
|
||
- **OCR 识别**:提供图片文字识别能力。
|
||
- **导入任务**:支持异步导入任务,并展示导入进度与状态。
|
||
- **多语言支持**:内置国际化机制,支持界面多语言切换。
|
||
|
||
#### 非功能性需求
|
||
##### 安全性
|
||
- **身份认证**:支持基于 JWT 的登录认证与基于 API Key 的接口认证。
|
||
- **权限守卫**:实现多层守卫机制,包括管理员守卫、租户管理员守卫、超级管理员守卫及权限点守卫。
|
||
- **审计日志**:记录关键操作日志,满足安全审计要求。
|
||
|
||
##### 性能与可靠性
|
||
- **并发测评**:系统支持多用户同时进行在线测评(源码中提供并发测评测试脚本)。
|
||
- **异步处理**:文档解析、导入任务等耗时操作采用异步机制,避免阻塞主流程。
|
||
|
||
##### 可维护性与可扩展性
|
||
- **模块化架构**:后端采用 NestJS 模块化设计,前端采用 React 组件化开发。
|
||
- **数据库迁移**:使用 TypeORM 迁移机制管理数据库结构变更。
|
||
- **容器化部署**:提供 Docker 部署方案,支持 Elasticsearch、Tika、LibreOffice 等基础设施的容器化编排。
|
||
|
||
##### 兼容性
|
||
- **多端访问**:支持 Web 端访问,并通过飞书机器人支持移动端测评场景。
|
||
|
||
> 注:关于系统架构与技术栈的详细说明,请参见“系统概述”章节中的“架构设计”部分。
|
||
|
||
### 2.2 技术选型
|
||
|
||
#### 后端技术栈
|
||
AuraK 后端基于 **NestJS** 框架构建,采用 TypeScript 语言开发,遵循模块化架构设计。核心依赖与版本信息如下:
|
||
|
||
| 层级 | 技术 | 版本 |
|
||
|---|---|---|
|
||
| 运行时 | Node.js | 18+ |
|
||
| 语言 | TypeScript | 4.x(源码中未提供精确版本) |
|
||
| 核心框架 | NestJS | 10.x(源码中未提供精确版本) |
|
||
| ORM | TypeORM | 0.3.x(源码中未提供精确版本) |
|
||
| 数据库 | SQLite | 内置(`server/database.sqlite`) |
|
||
| 搜索引擎 | Elasticsearch | 通过 Docker Compose 部署 |
|
||
| 认证 | Passport.js(JWT + Local) | 源码中未提供精确版本 |
|
||
| 测试框架 | Jest | 源码中未提供精确版本 |
|
||
| 代码规范 | ESLint | 源码中未提供精确版本 |
|
||
|
||
后端采用模块化组织,核心模块包括:`auth`(认证与权限)、`assessment`(人才评估)、`knowledge-base`(知识库)、`rag`(检索增强生成)、`tenant`(多租户)、`feishu`(飞书集成)等。
|
||
|
||
#### 前端技术栈
|
||
前端为单页应用(SPA),基于 **React** 构建,使用 **Vite** 作为构建工具。
|
||
|
||
| 层级 | 技术 | 版本 |
|
||
|---|---|---|
|
||
| 核心框架 | React | 18.x(源码中未提供精确版本) |
|
||
| 构建工具 | Vite | 5.x(源码中未提供精确版本) |
|
||
| 路由 | React Router DOM | 6.x(源码中未提供精确版本) |
|
||
| 样式方案 | Tailwind CSS | 3.4.17 |
|
||
| UI 组件 | lucide-react(图标) | 源码中未提供精确版本 |
|
||
| 动画 | framer-motion / motion | 源码中未提供精确版本 |
|
||
| Markdown 渲染 | react-markdown + remark-gfm + remark-math + rehype-katex | 源码中未提供精确版本 |
|
||
| PDF 解析 | pdfjs-dist | 源码中未提供精确版本 |
|
||
| AI 客户端 | @google/genai | 源码中未提供精确版本 |
|
||
| 代码高亮 | react-syntax-highlighter | 源码中未提供精确版本 |
|
||
| 图表 | mermaid | 源码中未提供精确版本 |
|
||
|
||
#### AI 与机器学习
|
||
| 层级 | 技术 | 说明 |
|
||
|---|---|---|
|
||
| LLM 接入 | OpenAI 兼容接口 + Gemini | 支持多模型配置(`model-config` 模块) |
|
||
| Embedding | 可配置 | 通过 `embedding.service.ts` 实现 |
|
||
| Rerank | 可配置 | 通过 `rerank.service.ts` 实现 |
|
||
| 视觉模型 | 可配置 | 通过 `vision.service.ts` 实现 |
|
||
| OCR | Tesseract | 内置 `chi_sim.traineddata`、`eng.traineddata`、`jpn.traineddata` |
|
||
| 文档解析 | Apache Tika | 通过 Docker 部署 |
|
||
| PDF 转换 | LibreOffice + 自研转换服务 | 通过 Docker 部署 |
|
||
|
||
#### 基础设施与部署
|
||
| 层级 | 技术 | 说明 |
|
||
|---|---|---|
|
||
| 容器化 | Docker + Docker Compose | 编排 Elasticsearch、Tika、LibreOffice 服务 |
|
||
| Web 服务器 | Nginx | 配置 SSL 与反向代理(`nginx/conf.d/`) |
|
||
| 消息通信 | WebSocket | 用于飞书机器人实时交互 |
|
||
| 数据流 | SSE(Server-Sent Events) | 用于 AI 流式响应 |
|
||
|
||
#### 开发与测试工具
|
||
| 层级 | 技术 | 版本 |
|
||
|---|---|---|
|
||
| 端到端测试 | Playwright | 通过 `@playwright/test` 引入 |
|
||
| 并发测试 | 自研脚本 | `test-concurrent-assessments.mjs` 等 |
|
||
| 接口测试 | 自研脚本 | `test-e2e-full.mjs`、`test-systematic.mjs` 等 |
|
||
|
||
#### 架构设计要点
|
||
系统采用 **前后端分离** 架构,前端通过 RESTful API 与后端通信。后端遵循 NestJS 模块化设计,每个业务域(如评估、知识库、租户)独立成模块,包含控制器、服务、实体与 DTO。多租户通过中间件与实体订阅器实现数据隔离,权限系统采用三级 RBAC 模型(SUPER_ADMIN / TENANT_ADMIN / USER)并支持 26 项细粒度权限控制。
|
||
|
||
AI 评估引擎采用 **图编排**(Graph)架构,由 `builder.ts` 构建评估流程,包含分析器(analyzer)、生成器(generator)、面试官(interviewer)与评分器(grader)四个核心节点,支持多轮自适应对话与多维度加权评分。
|
||
|
||
### 2.3 软件结构
|
||
|
||
#### 系统架构总览
|
||
AuraK 是一套企业级 AI 知识库与人才评估平台,采用前后端分离的模块化架构。系统以 NestJS 构建后端服务,以 React + TypeScript 构建前端单页应用,并依赖 Elasticsearch、Apache Tika、LibreOffice 等外部基础设施组件提供文档解析、全文检索与格式转换能力。
|
||
|
||
```mermaid
|
||
graph TD
|
||
subgraph 客户端层
|
||
Web[Web 前端<br/>React + TypeScript]
|
||
Feishu[飞书机器人<br/>WebSocket 集成]
|
||
end
|
||
|
||
subgraph 接入层
|
||
Nginx[Nginx 反向代理<br/>SSL 终止]
|
||
APIController[API 控制器<br/>api-v1 / api]
|
||
end
|
||
|
||
subgraph 应用服务层
|
||
Auth[认证模块<br/>JWT / API Key / RBAC]
|
||
Tenant[多租户模块<br/>租户隔离 / 成员管理]
|
||
Assessment[人才评估模块<br/>AI 出题 / 评分 / 证书]
|
||
KnowledgeBase[知识库模块<br/>文档处理 / 分块 / 向量化]
|
||
RAG[RAG 检索模块<br/>混合检索 / 重排序]
|
||
Chat[对话模块<br/>SSE 流式输出]
|
||
Note[笔记模块]
|
||
Podcast[播客模块]
|
||
SearchHistory[搜索历史模块]
|
||
ImportTask[导入任务模块]
|
||
ModelConfig[模型配置模块<br/>LLM / Embedding / Rerank / Vision]
|
||
OCR[OCR 模块<br/>Tesseract]
|
||
PDF2Image[PDF 转图片模块]
|
||
VisionPipeline[视觉流水线模块<br/>高精度文档解析]
|
||
LibreOffice[LibreOffice 模块<br/>文档格式转换]
|
||
Tika[Tika 模块<br/>快速文档解析]
|
||
ElasticsearchService[Elasticsearch 服务]
|
||
Upload[文件上传模块]
|
||
Admin[管理模块]
|
||
SuperAdmin[超级管理员模块]
|
||
Permission[权限模块<br/>26 项细粒度权限]
|
||
FeishuService[飞书服务模块]
|
||
I18n[国际化模块]
|
||
end
|
||
|
||
subgraph 数据层
|
||
SQLite[(SQLite 数据库<br/>TypeORM)]
|
||
ES[(Elasticsearch<br/>全文索引)]
|
||
FileStorage[(文件存储<br/>上传文件 / 解析产物)]
|
||
end
|
||
|
||
subgraph 外部 AI 服务
|
||
OpenAI[OpenAI 兼容接口]
|
||
Gemini[Google Gemini]
|
||
end
|
||
|
||
Web --> Nginx
|
||
Feishu --> Nginx
|
||
Nginx --> APIController
|
||
APIController --> Auth
|
||
APIController --> Tenant
|
||
APIController --> Assessment
|
||
APIController --> KnowledgeBase
|
||
APIController --> RAG
|
||
APIController --> Chat
|
||
APIController --> Note
|
||
APIController --> Podcast
|
||
APIController --> SearchHistory
|
||
APIController --> ImportTask
|
||
APIController --> ModelConfig
|
||
APIController --> OCR
|
||
APIController --> PDF2Image
|
||
APIController --> VisionPipeline
|
||
APIController --> LibreOffice
|
||
APIController --> Tika
|
||
APIController --> ElasticsearchService
|
||
APIController --> Upload
|
||
APIController --> Admin
|
||
APIController --> SuperAdmin
|
||
APIController --> Permission
|
||
APIController --> FeishuService
|
||
APIController --> I18n
|
||
|
||
Auth --> SQLite
|
||
Tenant --> SQLite
|
||
Assessment --> SQLite
|
||
KnowledgeBase --> SQLite
|
||
Chat --> SQLite
|
||
Note --> SQLite
|
||
Podcast --> SQLite
|
||
SearchHistory --> SQLite
|
||
ImportTask --> SQLite
|
||
ModelConfig --> SQLite
|
||
Permission --> SQLite
|
||
FeishuService --> SQLite
|
||
|
||
KnowledgeBase --> ES
|
||
RAG --> ES
|
||
ElasticsearchService --> ES
|
||
|
||
RAG --> OpenAI
|
||
RAG --> Gemini
|
||
Chat --> OpenAI
|
||
Chat --> Gemini
|
||
Assessment --> OpenAI
|
||
Assessment --> Gemini
|
||
VisionPipeline --> OpenAI
|
||
VisionPipeline --> Gemini
|
||
OCR --> FileStorage
|
||
PDF2Image --> FileStorage
|
||
Upload --> FileStorage
|
||
LibreOffice --> FileStorage
|
||
Tika --> FileStorage
|
||
```
|
||
|
||
#### 模块层级说明
|
||
##### 客户端层
|
||
系统提供两种客户端入口:基于 React 的 Web 前端(`web/` 目录)与飞书机器人集成(`server/src/feishu/`)。Web 前端采用组件化开发,包含知识库、笔记、对话、评估、设置等核心视图;飞书模块通过 WebSocket 实现消息推送与交互式卡片,支持移动端评估场景。
|
||
|
||
##### 接入层
|
||
Nginx 作为反向代理统一接收客户端请求,负责 SSL 终止与静态资源服务。后端通过 `api-v1.controller.ts` 与 `api.controller.ts` 暴露 RESTful API,所有请求经认证与租户中间件处理后分发至对应业务模块。
|
||
|
||
##### 应用服务层
|
||
应用服务层是系统的核心,按业务领域划分为多个 NestJS 模块:
|
||
|
||
- **认证与权限**:`auth/` 模块实现 JWT 认证、API Key 认证与本地策略;`permission/` 子模块提供三级角色体系(SUPER_ADMIN / TENANT_ADMIN / USER)与 26 项细粒度权限控制。
|
||
- **多租户**:`tenant/` 模块实现租户数据隔离,通过中间件与实体订阅器自动注入租户过滤条件。
|
||
- **人才评估**:`assessment/` 模块是系统核心业务之一,包含 AI 自动出题(选择题 + 简答题)、自适应追问对话、多维度加权评分与证书生成。该模块内部采用图编排引擎(`graph/` 目录),由分析器、生成器、面试官、评分器四个节点组成处理流水线。
|
||
- **知识库**:`knowledge-base/` 模块提供文档上传、文本分块、向量化与检索能力,支持 Tika 快速解析与视觉流水线高精度解析两种处理路径。
|
||
- **RAG 检索**:`rag/` 模块实现 BM25 + 向量的混合检索与重排序,为对话与问答提供知识增强。
|
||
- **AI 引擎**:`model-config/` 模块统一管理 LLM、Embedding、Rerank、Vision 四类模型的配置,兼容 OpenAI 协议与 Google Gemini。
|
||
- **辅助能力**:`ocr/`、`pdf2image/`、`libreoffice/`、`tika/` 等模块提供文档解析与格式转换能力;`upload/` 模块处理文件上传;`i18n/` 模块提供国际化支持。
|
||
|
||
##### 数据层
|
||
系统使用 SQLite 作为主数据库(通过 TypeORM 管理),存储用户、租户、评估、知识库等业务数据;Elasticsearch 提供全文检索与向量检索能力;文件系统存储上传的原始文件与解析中间产物。
|
||
|
||
##### 外部 AI 服务
|
||
系统通过模型配置模块对接 OpenAI 兼容接口与 Google Gemini 服务,用于文本生成、向量化、重排序与视觉理解等 AI 能力调用。
|
||
|
||
## 3. 功能模块
|
||
|
||
### 3.1 功能清单
|
||
|
||
#### 题库管理功能清单
|
||
题库管理模块是人才测评体系的基础,负责题目的创建、审核、发布与维护。以下表格列出了该模块的核心功能及其实现位置。
|
||
|
||
| 功能名 | 文件位置 | 用途 | 输入参数 | 返回值 |
|
||
|--------|---------|------|---------|--------|
|
||
| 创建题库 | `server/src/assessment/controllers/question-bank.controller.ts` | 创建新的题库,关联模板与知识库 | `name`(题库名称)、`description`(描述)、`templateId`(关联模板ID) | 新建的题库实体(含 `id`、`status: DRAFT`) |
|
||
| 题库列表查询 | `server/src/assessment/controllers/question-bank.controller.ts` | 分页查询题库列表 | `page`、`pageSize`、`keyword`(可选)、`status`(可选) | 分页结果,包含题库数组及总数 |
|
||
| 题库详情查询 | `server/src/assessment/controllers/question-bank.controller.ts` | 获取单个题库的详细信息 | `id`(题库ID) | 题库实体,含关联的题目列表 |
|
||
| 更新题库 | `server/src/assessment/controllers/question-bank.controller.ts` | 修改题库的名称、描述等信息 | `id`、`name`、`description` | 更新后的题库实体 |
|
||
| 删除题库 | `server/src/assessment/controllers/question-bank.controller.ts` | 删除指定题库 | `id`(题库ID) | 删除结果(成功/失败) |
|
||
| 添加题目 | `server/src/assessment/controllers/question-bank.controller.ts` | 向题库中添加单道题目 | `bankId`、`questionText`、`questionType`、`options`、`correctAnswer`、`keyPoints`、`difficulty`、`dimension`、`basis` | 新建的题目实体(`status: PENDING_REVIEW`) |
|
||
| 更新题目 | `server/src/assessment/controllers/question-bank.controller.ts` | 修改题库中已有题目的内容 | `bankId`、`id`(题目ID)、上述题目字段 | 更新后的题目实体 |
|
||
| 删除题目 | `server/src/assessment/controllers/question-bank.controller.ts` | 从题库中删除指定题目 | `bankId`、`id`(题目ID) | 删除结果(成功/失败) |
|
||
| AI批量生成题目 | `server/src/assessment/controllers/question-bank.controller.ts` | 按模板 `dimensionQuota` 配置自动生成待审题目 | `bankId`、`count`(生成数量)、`dimension`(可选,指定维度) | 生成的题目列表(`status: PENDING_REVIEW`) |
|
||
| 提交审核 | `server/src/assessment/controllers/question-bank.controller.ts` | 将题库状态从 `DRAFT` 提交为 `PENDING_REVIEW` | `id`(题库ID) | 更新后的题库实体(`status: PENDING_REVIEW`) |
|
||
| 单题审核 | `server/src/assessment/controllers/question-bank.controller.ts` | 逐题审核,通过或否决题目 | `bankId`、`id`(题目ID)、`action`(`approve`/`reject`)、`comment`(审核意见) | 更新后的题目实体(`status: PUBLISHED` 或退回 `DRAFT`) |
|
||
| 发布题库 | `server/src/assessment/controllers/question-bank.controller.ts` | 将题库状态更新为 `PUBLISHED` | `id`(题库ID) | 更新后的题库实体(`status: PUBLISHED`) |
|
||
| 下架题库 | `server/src/assessment/controllers/question-bank.controller.ts` | 将题库状态从 `PUBLISHED` 改为 `DRAFT` | `id`(题库ID) | 更新后的题库实体(`status: DRAFT`) |
|
||
| 按模板查询题库 | `server/src/assessment/controllers/question-bank.controller.ts` | 根据模板ID查询关联的题库 | `templateId`(模板ID) | 题库实体列表 |
|
||
|
||
#### 调用层级关系
|
||
```mermaid
|
||
graph LR
|
||
A[前端页面 QuestionBankView] --> B[questionBankService.ts]
|
||
B --> C[QuestionBankController]
|
||
C --> D[QuestionBankService]
|
||
D --> E[QuestionBankEntity]
|
||
D --> F[QuestionBankItemEntity]
|
||
D --> G[AI生成题目 GeneratorNode]
|
||
G --> H[模板配置 TemplateService]
|
||
D --> I[审核流程 AuditLogService]
|
||
```
|
||
|
||
#### 关键业务规则
|
||
- **题库与模板为一对一关系**:一个模板仅关联一个题库,题库不单独关联知识库,由模板指定知识库范围。
|
||
- **题目状态流转**:新题目默认为 `PENDING_REVIEW`,审核通过后变为 `PUBLISHED`,否决后回到 `DRAFT` 并附带审核意见。
|
||
- **题库状态流转**:`DRAFT → PENDING_REVIEW → PUBLISHED`,支持从 `PUBLISHED` 下架回 `DRAFT`。
|
||
- **AI生成依赖模板配置**:生成题目的数量与维度分布由模板的 `dimensionQuota` 字段控制。
|
||
|
||
#### 权限说明
|
||
题库管理功能仅管理员角色可访问,普通学员、部门管理者及讲师均无题库管理权限。权限控制通过 `PermissionGuard` 与 `PermissionConstants` 实现,具体权限矩阵参见“权限管理”章节。
|
||
|
||
### 3.2 流程逻辑
|
||
|
||
#### 核心评估流程
|
||
AuraK 的人才评估系统采用**多阶段流水线**架构,由 `assessment.service.ts` 统一编排,通过 `builder.ts` 构建 LangGraph 状态图驱动。整个流程从模板选择到证书颁发共经历六个阶段。
|
||
|
||
```mermaid
|
||
sequenceDiagram
|
||
participant U as 候选人
|
||
participant A as 评估服务
|
||
participant G as 图构建器
|
||
participant N as 节点执行器
|
||
participant DB as 数据库
|
||
|
||
U->>A: 选择模板并开始评估
|
||
A->>DB: 创建评估会话(状态:进行中)
|
||
A->>G: 构建评估图
|
||
G->>N: 初始化生成器节点
|
||
|
||
rect rgb(240, 248, 255)
|
||
Note over N: 阶段一:题目生成
|
||
N->>DB: 按模板维度抽取题目
|
||
DB-->>N: 返回题目列表
|
||
N-->>A: 返回首题
|
||
end
|
||
|
||
loop 每题作答
|
||
U->>A: 提交答案
|
||
A->>N: 调用面试官节点
|
||
N->>DB: 保存答案
|
||
alt 需要追问
|
||
N-->>U: 生成追问问题
|
||
else 进入下一题
|
||
N->>N: 加载下一题
|
||
end
|
||
end
|
||
|
||
rect rgb(255, 250, 240)
|
||
Note over N: 阶段二:评分与追问
|
||
N->>N: 评分器节点计算维度得分
|
||
N->>N: 分析器节点生成综合评语
|
||
end
|
||
|
||
rect rgb(240, 255, 240)
|
||
Note over N: 阶段三:结果输出
|
||
N->>DB: 更新会话状态(已完成)
|
||
N->>DB: 生成证书记录
|
||
N-->>U: 返回评分报告与证书
|
||
end
|
||
```
|
||
|
||
#### 状态流转
|
||
评估会话(`assessment-session.entity.ts`)的状态机定义如下:
|
||
|
||
| 状态 | 触发条件 | 后续状态 |
|
||
|---|---|---|
|
||
| `进行中` | 用户点击开始评估 | `已完成` / `已中止` |
|
||
| `已完成` | 全部题目作答完毕且评分完成 | 终态 |
|
||
| `已中止` | 用户主动放弃或系统异常 | 终态 |
|
||
|
||
每个评估会话关联唯一的 `assessment-answer` 记录集合,答案状态随节点执行进度同步更新。
|
||
|
||
#### 图构建与节点编排
|
||
`builder.ts` 中的 `buildAssessmentGraph()` 方法负责组装四个核心节点:
|
||
|
||
1. **生成器节点**(`generator.node.ts`)—— 从题库中按模板配置的维度权重抽取题目,组装为评估问卷。
|
||
2. **面试官节点**(`interviewer.node.ts`)—— 负责逐题呈现、接收答案,并根据答案内容决定是否发起追问(最多两轮)。
|
||
3. **评分器节点**(`grader.node.ts`)—— 对全部答案进行多维度加权评分,计算各维度得分与总分。
|
||
4. **分析器节点**(`analyzer.node.ts`)—— 汇总评分结果,生成综合能力评语与改进建议。
|
||
|
||
节点间通过 `state.ts` 中定义的 `AssessmentState` 接口传递数据,包含题目列表、当前索引、答案映射、维度得分等字段。
|
||
|
||
#### 决策点与分支逻辑
|
||
#### 追问判定
|
||
面试官节点在收到答案后执行以下判断:
|
||
|
||
- 若当前题目为**简答题**且答案长度超过阈值,则生成追问问题;
|
||
- 追问次数上限为 **2 轮**,超过后强制进入下一题;
|
||
- 若为**单选题**,直接进入下一题,不触发追问。
|
||
|
||
#### 评分汇总
|
||
评分器节点按模板配置的维度权重(如技术模板:`PROMPT 30%`、`LLM 30%`、`IDE 20%`、`DEV_PATTERN 20%`)计算加权总分。所有维度得分均需落盘后才会触发分析器节点。
|
||
|
||
#### 错误处理与异常恢复
|
||
| 异常场景 | 处理策略 | 恢复机制 |
|
||
|---|---|---|
|
||
| 题目生成失败(题库为空) | 返回错误提示,会话不创建 | 用户可重新选择模板 |
|
||
| 模型调用超时 | 重试 2 次,间隔 1 秒 | 重试仍失败则标记该题为跳过 |
|
||
| 答案保存失败 | 事务回滚,返回重试提示 | 用户可重新提交答案 |
|
||
| 评分节点异常 | 会话标记为 `已中止` | 管理员可在后台查看日志并手动重置 |
|
||
|
||
#### 飞书端评估流程
|
||
飞书机器人通过 `feishu-assessment.service.ts` 提供移动端评估入口,流程与 Web 端一致,但增加了消息卡片交互层。用户通过飞书消息卡片完成题目作答,状态流转与 Web 端共用同一套会话模型。
|
||
|
||
> 飞书端的具体命令解析与消息卡片交互细节,详见「飞书集成」章节。
|
||
|
||
### 3.3 核心业务
|
||
|
||
#### 人才评估核心流程
|
||
AuraK 的人才评估模块围绕 **模板配置 → 考试执行 → AI 评分 → 证书发放** 四个阶段构建,支持多轮对话式答题与多维度加权评分。
|
||
|
||
##### 评估模板配置
|
||
系统内置两套评估模板,管理员可在 `设置 → 评估模板` 中自定义维度、权重与题目数量:
|
||
|
||
| 模板 | 题目数 | 评估维度 | 适用人群 |
|
||
|---|---|---|---|
|
||
| 技术类 | 20 | PROMPT 30%、LLM 30%、IDE 20%、DEV_PATTERN 20% | 开发人员、工程师 |
|
||
| 非技术类 | 10 | PROMPT 50%、LLM 30%、WORK_CAPABILITY 20% | 管理者、产品经理、设计师 |
|
||
|
||
模板支持完全自定义——可增删维度、调整权重、修改题目数量。模板实体(`assessment-template.entity.ts`)包含维度配置与题目数量等核心属性,扩展字段通过迁移脚本 `AddTemplateExtensions` 添加。
|
||
|
||
##### 考试执行流程
|
||
考生登录后进入 **评估** 页面,选择模板并点击 **开始评估**,系统按以下流程执行:
|
||
|
||
1. **题目生成**:基于模板配置,由 AI 自动生成选择题与简答题
|
||
2. **逐题作答**:
|
||
- 选择题:点击选项后确认
|
||
- 简答题:在文本框中输入答案后发送
|
||
3. **自适应追问**:AI 根据简答内容提出追问,考生需继续作答
|
||
4. **评分与证书**:全部题目完成后,系统展示得分并发放证书
|
||
|
||
评估会话数据由 `assessment-session.entity.ts` 管理,答题记录存储在 `assessment-answer.entity.ts`,证书信息由 `assessment-certificate.entity.ts` 维护。
|
||
|
||
##### AI 评分机制
|
||
评分由评估图(`graph/` 目录)中的多个节点协作完成:
|
||
|
||
- **生成器节点**(`generator.node.ts`):根据模板生成题目
|
||
- **面试官节点**(`interviewer.node.ts`):驱动多轮对话式追问
|
||
- **评分器节点**(`grader.node.ts`):对答案进行评分
|
||
- **分析器节点**(`analyzer.node.ts`):综合各维度得分
|
||
|
||
评分采用 **加权多维度计算**,各维度权重由模板配置决定。评估状态机(`state.ts`)管理整个流程的状态流转。
|
||
|
||
##### 结果查看与导出
|
||
- **历史记录**:评估页面右侧边栏展示历史评估记录
|
||
- **详情查看**:点击记录可查看各维度得分明细
|
||
- **证书系统**:通过 `export.service.ts` 支持评估结果导出,证书由 `pdf-generator.ts` 生成
|
||
|
||
##### 飞书机器人集成
|
||
系统支持通过飞书机器人进行移动端评估(详见 **飞书集成** 章节):
|
||
|
||
- 基于 WebSocket 的实时消息交互
|
||
- 交互式消息卡片展示题目与选项
|
||
- 通过 `assessment-command.parser.ts` 解析用户指令,支持在飞书会话中直接发起评估
|
||
|
||
##### 题库管理
|
||
管理员可通过 `题库管理` 维护预置题目,评估模板可引用题库中的题目。题库相关表结构由迁移脚本 `CreateQuestionBankTables` 创建,包含题库(`question-bank.entity.ts`)、题库条目(`question-bank-item.entity.ts`)与题库模板(`question-bank-template.entity.ts`)三层结构。
|
||
|
||
## 4. 数据设计
|
||
|
||
### 4.1 表详细设计
|
||
|
||
#### 实体关系总览
|
||
以下 Mermaid ER 图展示了系统核心表及其关联关系,字段名与源码实体定义完全一致。
|
||
|
||
```mermaid
|
||
erDiagram
|
||
USER ||--o{ NOTE : "拥有"
|
||
USER ||--o{ KNOWLEDGE_BASE : "创建"
|
||
USER ||--o{ SEARCH_HISTORY : "产生"
|
||
USER ||--o{ ASSESSMENT_SESSION : "参与"
|
||
USER ||--o{ FEISHU_BOT : "绑定"
|
||
TENANT ||--o{ USER : "包含"
|
||
TENANT ||--o{ KNOWLEDGE_BASE : "隔离"
|
||
KNOWLEDGE_BASE ||--o{ KNOWLEDGE_GROUP : "分组"
|
||
KNOWLEDGE_GROUP ||--o{ KNOWLEDGE_GROUP : "父子层级"
|
||
ASSESSMENT_TEMPLATE ||--o{ ASSESSMENT_SESSION : "定义"
|
||
ASSESSMENT_SESSION ||--o{ ASSESSMENT_ANSWER : "包含"
|
||
ASSESSMENT_SESSION ||--o{ ASSESSMENT_CERTIFICATE : "生成"
|
||
QUESTION_BANK ||--o{ QUESTION_BANK_ITEM : "包含"
|
||
QUESTION_BANK_TEMPLATE ||--o{ QUESTION_BANK_ITEM : "关联"
|
||
ROLE ||--o{ ROLE_PERMISSION : "授权"
|
||
USER ||--o{ USER_SETTING : "配置"
|
||
IMPORT_TASK ||--o{ KNOWLEDGE_BASE : "导入目标"
|
||
```
|
||
|
||
#### 用户与租户
|
||
##### user(用户表)
|
||
| 字段名 | 类型 | 说明 |
|
||
|---|---|---|
|
||
| id | varchar | 主键 |
|
||
| username | varchar | 用户名,唯一 |
|
||
| password | varchar | 密码哈希 |
|
||
| displayName | varchar | 显示名称 |
|
||
| role | enum | USER / TENANT_ADMIN / SUPER_ADMIN |
|
||
| tenantId | varchar | 所属租户 ID |
|
||
| isActive | boolean | 是否启用 |
|
||
| createdAt / updatedAt | datetime | 时间戳 |
|
||
|
||
##### tenant(租户表)
|
||
| 字段名 | 类型 | 说明 |
|
||
|---|---|---|
|
||
| id | varchar | 主键 |
|
||
| name | varchar | 租户名称 |
|
||
| code | varchar | 租户编码,唯一 |
|
||
| settings | json | 租户级设置 |
|
||
| createdAt / updatedAt | datetime | 时间戳 |
|
||
|
||
##### tenant_member(租户成员表)
|
||
| 字段名 | 类型 | 说明 |
|
||
|---|---|---|
|
||
| id | varchar | 主键 |
|
||
| tenantId | varchar | 租户 ID |
|
||
| userId | varchar | 用户 ID |
|
||
| role | varchar | 成员角色 |
|
||
|
||
##### user_setting(用户设置表)
|
||
| 字段名 | 类型 | 说明 |
|
||
|---|---|---|
|
||
| id | varchar | 主键 |
|
||
| userId | varchar | 用户 ID,唯一 |
|
||
| language | varchar | 语言偏好 |
|
||
| settings | json | 扩展设置 |
|
||
|
||
#### 权限体系
|
||
##### role(角色表)
|
||
| 字段名 | 类型 | 说明 |
|
||
|---|---|---|
|
||
| id | varchar | 主键 |
|
||
| name | varchar | 角色名称 |
|
||
| code | varchar | 角色编码,唯一 |
|
||
| description | varchar | 描述 |
|
||
| isSystem | boolean | 是否系统内置角色 |
|
||
| tenantId | varchar | 所属租户(自定义角色) |
|
||
|
||
##### role_permission(角色权限关联表)
|
||
| 字段名 | 类型 | 说明 |
|
||
|---|---|---|
|
||
| id | varchar | 主键 |
|
||
| roleId | varchar | 角色 ID |
|
||
| permission | varchar | 权限标识(共 26 种) |
|
||
|
||
#### 知识库模块
|
||
##### knowledge_base(知识库表)
|
||
| 字段名 | 类型 | 说明 |
|
||
|---|---|---|
|
||
| id | varchar | 主键 |
|
||
| name | varchar | 知识库名称 |
|
||
| description | text | 描述 |
|
||
| tenantId | varchar | 租户 ID |
|
||
| ownerId | varchar | 创建者 ID |
|
||
| documentCount | int | 文档数量 |
|
||
| status | varchar | 状态(索引中/就绪) |
|
||
| createdAt / updatedAt | datetime | 时间戳 |
|
||
|
||
##### knowledge_group(知识分组表)
|
||
| 字段名 | 类型 | 说明 |
|
||
|---|---|---|
|
||
| id | varchar | 主键 |
|
||
| name | varchar | 分组名称 |
|
||
| knowledgeBaseId | varchar | 所属知识库 ID |
|
||
| parentId | varchar | 父分组 ID(支持层级) |
|
||
| createdAt / updatedAt | datetime | 时间戳 |
|
||
|
||
##### note(笔记表)
|
||
| 字段名 | 类型 | 说明 |
|
||
|---|---|---|
|
||
| id | varchar | 主键 |
|
||
| title | varchar | 标题 |
|
||
| content | text | 内容 |
|
||
| userId | varchar | 所属用户 |
|
||
| categoryId | varchar | 分类 ID |
|
||
| knowledgeBaseId | varchar | 关联知识库 |
|
||
| createdAt / updatedAt | datetime | 时间戳 |
|
||
|
||
#### 评估模块
|
||
##### assessment_template(评估模板表)
|
||
| 字段名 | 类型 | 说明 |
|
||
|---|---|---|
|
||
| id | varchar | 主键 |
|
||
| name | varchar | 模板名称 |
|
||
| description | text | 描述 |
|
||
| questionCount | int | 题目数量 |
|
||
| dimensions | json | 评估维度及权重配置 |
|
||
| isActive | boolean | 是否启用 |
|
||
| createdBy | varchar | 创建者 ID |
|
||
| createdAt / updatedAt | datetime | 时间戳 |
|
||
|
||
##### assessment_session(评估会话表)
|
||
| 字段名 | 类型 | 说明 |
|
||
|---|---|---|
|
||
| id | varchar | 主键 |
|
||
| userId | varchar | 参评用户 |
|
||
| templateId | varchar | 使用的模板 |
|
||
| status | varchar | 状态(进行中/已完成) |
|
||
| score | float | 总分 |
|
||
| dimensionScores | json | 各维度得分 |
|
||
| startedAt / completedAt | datetime | 起止时间 |
|
||
|
||
##### assessment_answer(评估答案表)
|
||
| 字段名 | 类型 | 说明 |
|
||
|---|---|---|
|
||
| id | varchar | 主键 |
|
||
| sessionId | varchar | 所属会话 |
|
||
| questionId | varchar | 题目 ID |
|
||
| answer | text | 用户答案 |
|
||
| score | float | 得分 |
|
||
| feedback | text | AI 反馈 |
|
||
| createdAt | datetime | 作答时间 |
|
||
|
||
##### assessment_certificate(评估证书表)
|
||
| 字段名 | 类型 | 说明 |
|
||
|---|---|---|
|
||
| id | varchar | 主键 |
|
||
| sessionId | varchar | 关联会话 |
|
||
| userId | varchar | 获证用户 |
|
||
| certificateNo | varchar | 证书编号 |
|
||
| issuedAt | datetime | 颁发时间 |
|
||
|
||
##### question_bank(题库表)
|
||
| 字段名 | 类型 | 说明 |
|
||
|---|---|---|
|
||
| id | varchar | 主键 |
|
||
| name | varchar | 题库名称 |
|
||
| description | text | 描述 |
|
||
| questionCount | int | 题目数量 |
|
||
| createdBy | varchar | 创建者 |
|
||
| createdAt / updatedAt | datetime | 时间戳 |
|
||
|
||
##### question_bank_item(题目表)
|
||
| 字段名 | 类型 | 说明 |
|
||
|---|---|---|
|
||
| id | varchar | 主键 |
|
||
| bankId | varchar | 所属题库 |
|
||
| type | enum | MULTIPLE_CHOICE / SHORT_ANSWER |
|
||
| content | text | 题目内容 |
|
||
| options | json | 选项(选择题) |
|
||
| answer | text | 参考答案 |
|
||
| difficulty | int | 难度等级 |
|
||
| createdAt / updatedAt | datetime | 时间戳 |
|
||
|
||
##### question_bank_template(题库模板关联表)
|
||
| 字段名 | 类型 | 说明 |
|
||
|---|---|---|
|
||
| id | varchar | 主键 |
|
||
| templateId | varchar | 评估模板 ID |
|
||
| bankId | varchar | 题库 ID |
|
||
| questionCount | int | 抽取数量 |
|
||
|
||
#### 飞书集成
|
||
##### feishu_bot(飞书机器人表)
|
||
| 字段名 | 类型 | 说明 |
|
||
|---|---|---|
|
||
| id | varchar | 主键 |
|
||
| appId | varchar | 飞书应用 ID |
|
||
| appSecret | varchar | 应用密钥 |
|
||
| tenantId | varchar | 关联租户 |
|
||
| knowledgeBaseId | varchar | 关联知识库 |
|
||
| isActive | boolean | 是否启用 |
|
||
|
||
##### feishu_assessment_session(飞书评估会话表)
|
||
| 字段名 | 类型 | 说明 |
|
||
|---|---|---|
|
||
| id | varchar | 主键 |
|
||
| sessionId | varchar | 关联评估会话 |
|
||
| feishuUserId | varchar | 飞书用户 ID |
|
||
| chatId | varchar | 飞书会话 ID |
|
||
| status | varchar | 会话状态 |
|
||
|
||
#### 其他核心表
|
||
##### import_task(导入任务表)
|
||
| 字段名 | 类型 | 说明 |
|
||
|---|---|---|
|
||
| id | varchar | 主键 |
|
||
| knowledgeBaseId | varchar | 目标知识库 |
|
||
| fileName | varchar | 文件名 |
|
||
| status | varchar | 状态 |
|
||
| progress | int | 进度百分比 |
|
||
| errorMessage | text | 错误信息 |
|
||
| createdAt / updatedAt | datetime | 时间戳 |
|
||
|
||
##### search_history(搜索历史表)
|
||
| 字段名 | 类型 | 说明 |
|
||
|---|---|---|
|
||
| id | varchar | 主键 |
|
||
| userId | varchar | 用户 ID |
|
||
| query | text | 搜索内容 |
|
||
| results | json | 结果摘要 |
|
||
| createdAt | datetime | 搜索时间 |
|
||
|
||
##### chat_message(聊天消息表)
|
||
| 字段名 | 类型 | 说明 |
|
||
|---|---|---|
|
||
| id
|
||
| id | varchar | 主键 |
|
||
| chatId | varchar | 关联会话 ID |
|
||
| role | varchar | 消息角色(user/assistant) |
|
||
| content | text | 消息内容 |
|
||
| createdAt | datetime | 发送时间 |
|
||
|
||
---
|
||
|
||
#### API 设计
|
||
#### 认证与用户
|
||
#### 注册用户
|
||
- **端点**: `POST /api/auth/register`
|
||
- **方法**: POST
|
||
- **请求体**:
|
||
```json
|
||
{
|
||
"username": "string",
|
||
"email": "string",
|
||
"password": "string"
|
||
}
|
||
```
|
||
- **响应**: `201 Created`,返回用户基本信息。
|
||
|
||
#### 用户登录
|
||
- **端点**: `POST /api/auth/login`
|
||
- **方法**: POST
|
||
- **请求体**:
|
||
```json
|
||
{
|
||
"email": "string",
|
||
"password": "string"
|
||
}
|
||
```
|
||
- **响应**: `200 OK`,返回 JWT 令牌。
|
||
|
||
#### 知识库管理
|
||
#### 创建知识库
|
||
- **端点**: `POST /api/knowledge-bases`
|
||
- **方法**: POST
|
||
- **请求头**: `Authorization: Bearer <token>`
|
||
- **请求体**:
|
||
```json
|
||
{
|
||
"name": "string",
|
||
"description": "string"
|
||
}
|
||
```
|
||
- **响应**: `201 Created`,返回知识库对象。
|
||
|
||
#### 获取知识库列表
|
||
- **端点**: `GET /api/knowledge-bases`
|
||
- **方法**: GET
|
||
- **响应**: `200 OK`,返回知识库数组。
|
||
|
||
#### 文档管理
|
||
#### 上传文档
|
||
- **端点**: `POST /api/knowledge-bases/{knowledgeBaseId}/documents`
|
||
- **方法**: POST
|
||
- **请求头**: `Authorization: Bearer <token>`
|
||
- **请求体**: `multipart/form-data`,包含文件字段。
|
||
- **响应**: `201 Created`,返回文档元数据。
|
||
|
||
#### 获取文档列表
|
||
- **端点**: `GET /api/knowledge-bases/{knowledgeBaseId}/documents`
|
||
- **方法**: GET
|
||
- **响应**: `200 OK`,返回文档数组。
|
||
|
||
#### 删除文档
|
||
- **端点**: `DELETE /api/documents/{documentId}`
|
||
- **方法**: DELETE
|
||
- **响应**: `204 No Content`。
|
||
|
||
#### 搜索
|
||
#### 语义搜索
|
||
- **端点**: `POST /api/search`
|
||
- **方法**: POST
|
||
- **请求体**:
|
||
```json
|
||
{
|
||
"query": "string",
|
||
"knowledgeBaseId": "string",
|
||
"topK": 10
|
||
}
|
||
```
|
||
- **响应**: `200 OK`,返回搜索结果数组,包含文档 ID、相似度分数和片段。
|
||
|
||
#### 聊天与评估
|
||
#### 发送聊天消息
|
||
- **端点**: `POST /api/chat`
|
||
- **方法**: POST
|
||
- **请求体**:
|
||
```json
|
||
{
|
||
"sessionId": "string",
|
||
"message": "string"
|
||
}
|
||
```
|
||
- **响应**: `200 OK`,返回助手回复。
|
||
|
||
#### 获取评估结果
|
||
- **端点**: `GET /api/assessments/{sessionId}`
|
||
- **方法**: GET
|
||
- **响应**: `200 OK`,返回评估结果,包括分数、反馈和建议。
|
||
|
||
#### 导入任务
|
||
#### 创建导入任务
|
||
- **端点**: `POST /api/import-tasks`
|
||
- **方法**: POST
|
||
- **请求体**:
|
||
```json
|
||
{
|
||
"knowledgeBaseId": "string",
|
||
"fileName": "string"
|
||
}
|
||
```
|
||
- **响应**: `201 Created`,返回任务 ID。
|
||
|
||
#### 查询任务状态
|
||
- **端点**: `GET /api/import-tasks/{taskId}`
|
||
- **方法**: GET
|
||
- **响应**: `200 OK`,返回任务状态和进度。
|
||
|
||
---
|
||
|
||
#### 安全与性能
|
||
#### 安全机制
|
||
- **认证**: 使用 JWT 进行身份验证,所有受保护端点需携带有效令牌。
|
||
- **授权**: 基于角色的访问控制(RBAC),区分管理员和普通用户。
|
||
- **数据加密**: 敏感数据(如密码)使用 bcrypt 加密存储。
|
||
- **输入验证**: 所有 API 请求体进行严格验证,防止注入攻击。
|
||
|
||
#### 性能优化
|
||
- **缓存**: 使用 Redis 缓存高频查询结果,减少数据库压力。
|
||
- **异步处理**: 文档导入和向量化采用异步任务队列,提升响应速度。
|
||
- **索引优化**: 数据库关键字段建立索引,加速查询。
|
||
- **分页**: 列表接口支持分页参数,避免一次性加载大量数据。
|
||
|
||
---
|
||
|
||
#### 部署与运维
|
||
#### 环境要求
|
||
- **Node.js**: 版本 18 或以上
|
||
- **数据库**: MySQL 8.0 或以上
|
||
- **向量数据库**: Milvus 2.x
|
||
- **缓存**: Redis 6.x
|
||
- **对象存储**: 兼容 S3 的存储服务
|
||
|
||
#### 部署步骤
|
||
1. 克隆代码仓库并安装依赖:`npm install`
|
||
2. 配置环境变量(数据库连接、JWT 密钥、向量数据库地址等)。
|
||
3. 运行数据库迁移:`npm run migrate`
|
||
4. 启动服务:`npm start`
|
||
|
||
#### 监控与日志
|
||
- 使用 PM2 或 Docker 进行进程管理。
|
||
- 集成日志系统(如 Winston)记录请求和错误信息。
|
||
- 配置健康检查端点 `/health` 用于负载均衡器探测。
|
||
|
||
---
|
||
|
||
#### 总结
|
||
本系统通过模块化设计,实现了知识库管理、文档处理、语义搜索、智能聊天和评估等核心功能。数据库设计覆盖了用户、知识库、文档、会话和任务等关键实体,API 设计遵循 RESTful 规范,确保系统的可扩展性和可维护性。安全与性能优化措施保障了生产环境的稳定运行。
|
||
|
||
### 4.2 主键与外键策略
|
||
|
||
#### 主键策略
|
||
系统所有实体统一采用**自增整数主键**,字段名为 `id`,由 TypeORM 的 `@PrimaryGeneratedColumn()` 装饰器自动生成。该策略适用于全部核心业务表,包括用户、租户、知识库、笔记、评估、题库等模块。
|
||
|
||
```typescript
|
||
// 示例:用户实体主键定义
|
||
@PrimaryGeneratedColumn()
|
||
id: number;
|
||
```
|
||
|
||
#### 外键策略
|
||
系统采用**逻辑外键**设计,实体间通过普通索引字段(如 `userId`、`tenantId`)建立关联,未在数据库层面声明物理外键约束。此策略便于多租户数据隔离与分库分表扩展。
|
||
|
||
##### 多租户外键
|
||
| 实体 | 外键字段 | 关联目标 |
|
||
|---|---|---|
|
||
| 用户(User) | `tenantId` | 租户(Tenant) |
|
||
| 知识库(KnowledgeBase) | `tenantId` | 租户(Tenant) |
|
||
| 笔记(Note) | `tenantId` | 租户(Tenant) |
|
||
| 飞书机器人(FeishuBot) | `tenantId` | 租户(Tenant) |
|
||
| 导入任务(ImportTask) | `tenantId` | 租户(Tenant) |
|
||
|
||
##### 用户关联外键
|
||
| 实体 | 外键字段 | 关联目标 |
|
||
|---|---|---|
|
||
| 笔记(Note) | `userId` | 用户(User) |
|
||
| 笔记分类(NoteCategory) | `userId` | 用户(User) |
|
||
| 搜索历史(SearchHistory) | `userId` | 用户(User) |
|
||
| 聊天消息(ChatMessage) | `userId` | 用户(User) |
|
||
| 用户设置(UserSetting) | `userId` | 用户(User) |
|
||
| API 密钥(ApiKey) | `userId` | 用户(User) |
|
||
|
||
##### 知识库关联外键
|
||
| 实体 | 外键字段 | 关联目标 |
|
||
|---|---|---|
|
||
| 知识分组(KnowledgeGroup) | `knowledgeBaseId` | 知识库(KnowledgeBase) |
|
||
| 知识分组(KnowledgeGroup) | `parentId` | 知识分组(KnowledgeGroup,自关联) |
|
||
|
||
##### 评估模块外键
|
||
| 实体 | 外键字段 | 关联目标 |
|
||
|---|---|---|
|
||
| 评估会话(AssessmentSession) | `templateId` | 评估模板(AssessmentTemplate) |
|
||
| 评估会话(AssessmentSession) | `userId` | 用户(User) |
|
||
| 评估答案(AssessmentAnswer) | `sessionId` | 评估会话(AssessmentSession) |
|
||
| 评估答案(AssessmentAnswer) | `questionId` | 评估问题(AssessmentQuestion) |
|
||
| 评估证书(AssessmentCertificate) | `sessionId` | 评估会话(AssessmentSession) |
|
||
| 评估证书(AssessmentCertificate) | `templateId` | 评估模板(AssessmentTemplate) |
|
||
| 飞书评估会话(FeishuAssessmentSession) | `botId` | 飞书机器人(FeishuBot) |
|
||
|
||
##### 题库模块外键
|
||
| 实体 | 外键字段 | 关联目标 |
|
||
|---|---|---|
|
||
| 题库条目(QuestionBankItem) | `bankId` | 题库(QuestionBank) |
|
||
| 题库模板(QuestionBankTemplate) | `bankId` | 题库(QuestionBank) |
|
||
|
||
##### 权限模块外键
|
||
| 实体 | 外键字段 | 关联目标 |
|
||
|---|---|---|
|
||
| 角色权限(RolePermission) | `roleId` | 角色(Role) |
|
||
| 租户成员(TenantMember) | `tenantId` | 租户(Tenant) |
|
||
| 租户成员(TenantMember) | `userId` | 用户(User) |
|
||
|
||
#### 关系图
|
||
```mermaid
|
||
graph LR
|
||
Tenant[租户 Tenant] --> User[用户 User]
|
||
Tenant --> KB[知识库 KnowledgeBase]
|
||
Tenant --> Bot[飞书机器人 FeishuBot]
|
||
User --> Note[笔记 Note]
|
||
User --> History[搜索历史 SearchHistory]
|
||
KB --> Group[知识分组 KnowledgeGroup]
|
||
Group --> Group
|
||
User --> Session[评估会话 AssessmentSession]
|
||
Template[评估模板 AssessmentTemplate] --> Session
|
||
Session --> Answer[评估答案 AssessmentAnswer]
|
||
Session --> Cert[评估证书 AssessmentCertificate]
|
||
Bot --> FeishuSession[飞书评估会话 FeishuAssessmentSession]
|
||
Bank[题库 QuestionBank] --> Item[题库条目 QuestionBankItem]
|
||
Role[角色 Role] --> RolePerm[角色权限 RolePermission]
|
||
```
|
||
|
||
#### 关键说明
|
||
- **级联行为**:源码中未显式配置 `ON DELETE CASCADE` 等级联规则,删除父实体时子实体数据的处理策略(源码中未提供)。
|
||
- **索引策略**:外键字段均未在实体定义中显式声明 `@Index()` 装饰器,实际索引情况(源码中未提供)。
|
||
- **租户隔离**:`TenantEntitySubscriber` 在实体持久化时自动注入 `tenantId`,实现多租户数据隔离,详见「多租户架构」章节。
|
||
|
||
### 4.3 索引设计
|
||
|
||
#### 索引策略概述
|
||
AuraK 采用 **SQLite(TypeORM)** 作为主数据库,并可选集成 **Elasticsearch** 用于全文检索与向量搜索。索引设计围绕多租户隔离、高频查询路径与混合检索需求展开。
|
||
|
||
#### 主数据库索引(SQLite / TypeORM)
|
||
##### 实体索引声明
|
||
源码中通过 TypeORM 实体装饰器 `@Index` 显式声明了以下索引:
|
||
|
||
| 实体 | 索引字段 | 索引类型 | 用途 |
|
||
|---|---|---|---|
|
||
| `UserEntity` | `username` | 唯一索引 | 用户登录查询 |
|
||
| `UserEntity` | `tenantId` | 普通索引 | 租户内用户列表查询 |
|
||
| `KnowledgeBaseEntity` | `tenantId` | 普通索引 | 租户知识库隔离查询 |
|
||
| `KnowledgeBaseEntity` | `knowledgeGroupId` | 普通索引 | 按分组筛选知识库 |
|
||
| `NoteEntity` | `tenantId` | 普通索引 | 租户笔记列表查询 |
|
||
| `NoteEntity` | `categoryId` | 普通索引 | 按分类筛选笔记 |
|
||
| `AssessmentSessionEntity` | `tenantId` | 普通索引 | 租户评估会话查询 |
|
||
| `AssessmentSessionEntity` | `userId` | 普通索引 | 用户历史评估查询 |
|
||
| `QuestionBankItemEntity` | `tenantId` | 普通索引 | 租户题库查询 |
|
||
| `QuestionBankItemEntity` | `questionBankId` | 普通索引 | 题库内题目查询 |
|
||
| `FeishuBotEntity` | `tenantId` | 普通索引 | 租户飞书机器人查询 |
|
||
| `SearchHistoryEntity` | `userId` | 普通索引 | 用户搜索历史查询 |
|
||
|
||
##### 复合索引
|
||
`AssessmentSessionEntity` 上存在 `tenantId + userId` 的复合索引声明,用于优化“指定租户下某用户的所有评估记录”这一高频查询路径。
|
||
|
||
##### 多租户数据隔离
|
||
`TenantEntitySubscriber` 在实体订阅器中自动注入 `tenantId` 过滤条件,所有多租户实体的查询均强制携带租户标识。索引设计确保该过滤条件能够命中索引,避免全表扫描。
|
||
|
||
#### 全文检索与向量索引(Elasticsearch)
|
||
##### 双引擎混合检索
|
||
系统采用 **BM25 + 向量检索** 的混合检索策略:
|
||
|
||
- **BM25 索引**:对知识库文档的标题与正文内容建立全文索引,支持关键词匹配。
|
||
- **向量索引**:通过 `EmbeddingService` 将文档分块(chunk)转换为向量,存入 Elasticsearch 的 dense_vector 字段,支持语义相似度检索。
|
||
|
||
##### 索引生命周期
|
||
`ElasticsearchService` 负责索引的创建、更新与删除。知识库文档在导入时触发索引写入,文档更新时同步刷新索引,删除时移除对应文档。
|
||
|
||
##### 检索流程
|
||
1. 用户查询经 `RagService` 接收。
|
||
2. 并行执行 BM25 关键词检索与向量语义检索。
|
||
3. 结果经 `RerankService` 重排序,融合两种检索结果。
|
||
4. 返回 Top-K 相关分块。
|
||
|
||
#### 查询优化策略
|
||
##### 分页与限制
|
||
所有列表查询接口均支持分页参数(`page` / `pageSize`),避免一次性加载全量数据。源码中 `FindOptions` 统一设置 `take` 与 `skip`。
|
||
|
||
##### 预加载与关联查询
|
||
TypeORM 实体关系使用 `relations` 选项进行预加载,减少 N+1 查询。例如评估会话查询时预加载关联的模板、答案与证书实体。
|
||
|
||
##### 内存缓存
|
||
`MemoryMonitorService` 监控内存使用情况,`ChunkConfigService` 管理分块配置。高频读取的配置数据在服务启动时加载至内存,减少数据库访问。
|
||
|
||
#### 迁移策略
|
||
##### 数据库迁移
|
||
源码中 `migrations/` 目录包含多个迁移文件,采用 TypeORM 迁移机制:
|
||
|
||
- 迁移文件命名格式:`<timestamp>-<MigrationName>.ts`
|
||
- 通过 `data-source.ts` 配置迁移路径
|
||
- 迁移执行命令:`typeorm migration:run`
|
||
|
||
##### 索引变更流程
|
||
新增或修改索引时,需创建新的迁移文件,在 `up()` 方法中执行 `CREATE INDEX` 或 `ALTER TABLE` 语句,在 `down()` 方法中回滚。
|
||
|
||
##### Elasticsearch 索引重建
|
||
当索引映射(mapping)变更时,需删除旧索引并重建。`ElasticsearchService` 提供 `deleteIndex` 与 `createIndex` 方法,支持索引重建流程。重建期间系统仍可正常写入,但检索结果可能短暂不完整。
|
||
|
||
#### 性能考量
|
||
源码中未提供具体的性能基准数据(如 QPS、延迟等),以下为架构层面的设计考量:
|
||
|
||
- 多租户过滤条件全部走索引,避免跨租户数据扫描。
|
||
- 混合检索将全文检索与语义检索并行化,缩短响应时间。
|
||
- 分页查询限制单次返回数据量,降低内存与网络开销。
|
||
|
||
> 关于查询接口的具体参数与响应格式,详见“API 参考”章节。
|
||
|
||
### 4.4 存储分配
|
||
|
||
#### 存储资源总览
|
||
AuraK 平台采用混合存储架构,根据数据特性分别使用关系型数据库、搜索引擎、文件系统及内存缓存。下表汇总了各类存储资源及其核心属性:
|
||
|
||
| 资源 | 类型 | 大小 | 保留策略 | 访问模式 |
|
||
|------|------|------|----------|----------|
|
||
| SQLite 数据库(`server/database.sqlite`) | 关系型数据库(单文件) | 源码中未提供 | 持久化,随业务增长累积 | 读写频繁,事务性访问 |
|
||
| Elasticsearch | 全文检索引擎 | 源码中未提供 | 持久化,索引随知识库内容更新 | 读写频繁,全文检索与向量检索 |
|
||
| 文件系统(上传文件) | 本地磁盘存储 | 源码中未提供 | 持久化,随上传累积 | 写入一次,多次读取 |
|
||
| Tika 服务 | 文档解析服务(Docker 容器) | 源码中未提供 | 无状态,不持久化 | 按需调用,解析后即释放 |
|
||
| LibreOffice 服务 | 文档转换服务(Docker 容器) | 源码中未提供 | 无状态,不持久化 | 按需调用,转换后即释放 |
|
||
| 内存(Node.js 进程) | 运行时缓存 | 源码中未提供 | 进程生命周期内有效 | 高频读写,临时数据 |
|
||
|
||
#### 数据库存储
|
||
##### 主数据库
|
||
系统默认使用 SQLite 作为主数据库,数据库文件位于 `server/database.sqlite`。通过 TypeORM 框架管理数据实体与迁移,支持多租户数据隔离。
|
||
|
||
**核心数据表(按业务模块划分):**
|
||
|
||
- **认证与权限**:`api_key`、`role`、`role_permission`、`user`、`user_setting`
|
||
- **租户管理**:`tenant`、`tenant_member`、`tenant_setting`
|
||
- **知识库**:`knowledge_base`、`knowledge_group`、`note`、`note_category`
|
||
- **评估系统**:`assessment_template`、`assessment_question`、`assessment_session`、`assessment_answer`、`assessment_certificate`、`question_bank`、`question_bank_item`、`question_bank_template`
|
||
- **飞书集成**:`feishu_bot`、`feishu_assessment_session`
|
||
- **系统日志**:`audit_log`、`import_task`、`search_history`、`chat_message`
|
||
- **模型配置**:`model_config`
|
||
- **播客**:`podcast_episode`
|
||
|
||
##### 数据迁移
|
||
数据库结构通过 TypeORM 迁移脚本管理,迁移文件存放于 `server/src/migrations/` 目录。主要迁移包括:
|
||
|
||
- 知识库增强字段(`1737800000000-AddKnowledgeBaseEnhancements.ts`)
|
||
- 多租户模块(`1772334811108-AddTenantModule.ts`)
|
||
- 评估相关表(`1773198650000-AddAssessmentTablesManual.ts`)
|
||
- 题库表(`1773220000000-CreateQuestionBankTables.ts`)
|
||
- 证书表(`1773210000003-CreateCertificateTable.ts`)
|
||
|
||
另有手动 SQL 迁移脚本存放于 `server/src/assessment/migrations/`。
|
||
|
||
#### 搜索引擎存储
|
||
Elasticsearch 作为全文检索引擎,通过 `elasticsearch.service.ts` 提供服务。知识库文档经分块处理后,同时生成文本向量并写入 Elasticsearch 索引,支持 BM25 全文检索与向量相似度检索的混合搜索模式。
|
||
|
||
#### 文件存储布局
|
||
##### 上传文件
|
||
用户上传的文档(PDF、图片等)通过 `upload.service.ts` 处理,存储于本地文件系统。文件路径与元数据记录在知识库实体中,支持后续的解析、索引与预览操作。
|
||
|
||
##### OCR 语言数据
|
||
OCR 服务使用 Tesseract 引擎,语言包(`chi_sim.traineddata`、`eng.traineddata`、`jpn.traineddata`)存放于 `server/` 目录下,支持中文、英文、日文的文字识别。
|
||
|
||
#### 缓存与临时数据
|
||
##### 内存缓存
|
||
- **租户上下文**:`tenant.store.ts` 在内存中维护当前请求的租户上下文,通过中间件在请求生命周期内传递。
|
||
- **国际化消息**:`i18n.store.ts` 缓存多语言翻译消息,避免重复加载。
|
||
|
||
##### 临时文件
|
||
- **PDF 转图片**:`pdf2image.service.ts` 将 PDF 文档转换为图片供前端预览,转换结果存放于临时目录。
|
||
- **文档转换**:LibreOffice 服务将 Markdown 等格式转换为 PDF,转换过程产生的中间文件在任务完成后清理。
|
||
|
||
#### 备份与容灾
|
||
源码中未提供自动备份机制。数据库文件(`database.sqlite`)与上传文件目录需通过外部运维手段进行定期备份。Elasticsearch 索引可通过其原生快照 API 进行备份。
|
||
|
||
#### 容器化部署存储
|
||
`docker-compose.yml` 定义了 Elasticsearch、Tika、LibreOffice 三个基础设施服务。各服务的数据持久化策略如下:
|
||
|
||
| 服务 | 数据卷 | 持久化说明 |
|
||
|------|--------|------------|
|
||
| Elasticsearch | 源码中未提供 | 索引数据需配置持久化卷 |
|
||
| Tika | 无 | 无状态服务,无需持久化 |
|
||
| LibreOffice | 无 | 无状态服务,无需持久化 |
|
||
|
||
> 注:关于数据库表结构的详细字段定义,请参阅“数据模型”章节。
|
||
|
||
## 5. API 规范
|
||
|
||
### 5.1 外部接口
|
||
|
||
#### 认证方式
|
||
系统采用 **JWT(JSON Web Token)** 作为主要认证机制,同时支持 **API Key** 认证用于服务间调用。
|
||
|
||
| 机制 | 说明 | 使用场景 |
|
||
|---|---|---|
|
||
| JWT | 登录成功后签发,需在请求头 `Authorization: Bearer <token>` 中携带 | 前端用户交互 |
|
||
| API Key | 通过 `X-API-Key` 请求头传递,由 `ApiKeyGuard` 校验 | 服务间调用、飞书机器人 |
|
||
|
||
认证相关端点详见 **认证与授权** 章节。
|
||
|
||
#### 通用响应格式
|
||
所有接口返回 JSON 格式。成功响应直接返回业务数据;失败时返回统一错误结构:
|
||
|
||
```json
|
||
{
|
||
"statusCode": 400,
|
||
"message": "错误描述信息",
|
||
"error": "Bad Request"
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
#### 核心业务端点
|
||
##### 评估(Assessment)
|
||
评估模块提供完整的测评流程管理,包括模板配置、会话管理、答题与评分。
|
||
|
||
**创建评估模板**
|
||
|
||
- **方法**:`POST /api/v1/assessment/templates`
|
||
- **认证**:JWT(需 `assessment:template:create` 权限)
|
||
- **请求体**:
|
||
|
||
```json
|
||
{
|
||
"name": "技术能力评估",
|
||
"description": "面向开发人员的综合技术测评",
|
||
"dimensions": [
|
||
{ "name": "PROMPT", "weight": 30, "questionCount": 6 },
|
||
{ "name": "LLM", "weight": 30, "questionCount": 6 }
|
||
],
|
||
"totalQuestions": 20,
|
||
"timeLimit": 60
|
||
}
|
||
```
|
||
|
||
| 字段 | 类型 | 必填 | 说明 |
|
||
|---|---|---|---|
|
||
| `name` | string | 是 | 模板名称 |
|
||
| `description` | string | 否 | 模板描述 |
|
||
| `dimensions` | array | 是 | 评估维度数组 |
|
||
| `dimensions[].name` | string | 是 | 维度名称(如 PROMPT、LLM、IDE) |
|
||
| `dimensions[].weight` | number | 是 | 维度权重(百分比) |
|
||
| `dimensions[].questionCount` | number | 是 | 该维度题目数量 |
|
||
| `totalQuestions` | number | 是 | 总题数 |
|
||
| `timeLimit` | number | 否 | 时间限制(分钟) |
|
||
|
||
**开始评估会话**
|
||
|
||
- **方法**:`POST /api/v1/assessment/sessions`
|
||
- **认证**:JWT
|
||
- **请求体**:
|
||
|
||
```json
|
||
{
|
||
"templateId": "uuid-string",
|
||
"candidateName": "张三",
|
||
"candidateEmail": "[email protected]"
|
||
}
|
||
```
|
||
|
||
- **响应**:返回 `sessionId`、首道题目及会话状态。
|
||
|
||
**提交答案**
|
||
|
||
- **方法**:`POST /api/v1/assessment/sessions/:sessionId/answers`
|
||
- **认证**:JWT
|
||
- **请求体**:
|
||
|
||
```json
|
||
{
|
||
"questionId": "uuid-string",
|
||
"answer": "用户提交的答案内容",
|
||
"duration": 45
|
||
}
|
||
```
|
||
|
||
| 字段 | 类型 | 必填 | 说明 |
|
||
|---|---|---|---|
|
||
| `questionId` | string | 是 | 题目 ID |
|
||
| `answer` | string | 是 | 答案内容(选择题为选项 ID,简答题为文本) |
|
||
| `duration` | number | 否 | 答题耗时(秒) |
|
||
|
||
**获取评估结果**
|
||
|
||
- **方法**:`GET /api/v1/assessment/sessions/:sessionId/result`
|
||
- **认证**:JWT
|
||
- **响应**:包含各维度得分、总分、评语及证书信息。
|
||
|
||
**常见错误码**
|
||
|
||
| 状态码 | 说明 |
|
||
|---|---|
|
||
| 400 | 参数校验失败(如模板维度权重之和不等于 100) |
|
||
| 401 | 未认证或 Token 过期 |
|
||
| 403 | 无权限执行该操作 |
|
||
| 404 | 模板或会话不存在 |
|
||
| 409 | 会话状态冲突(如重复提交答案) |
|
||
|
||
---
|
||
|
||
##### 知识库(Knowledge Base)
|
||
知识库支持文档上传、解析、分块与混合检索。
|
||
|
||
**上传文档**
|
||
|
||
- **方法**:`POST /api/v1/knowledge-base/upload`
|
||
- **认证**:JWT
|
||
- **请求**:`multipart/form-data`,字段 `file`(文件二进制流)
|
||
- **响应**:返回文档 ID、解析状态及分块数量。
|
||
|
||
**创建知识库**
|
||
|
||
- **方法**:`POST /api/v1/knowledge-base`
|
||
- **认证**:JWT
|
||
- **请求体**:
|
||
|
||
```json
|
||
{
|
||
"name": "产品文档库",
|
||
"description": "产品需求与设计文档",
|
||
"chunkSize": 512,
|
||
"chunkOverlap": 50
|
||
}
|
||
```
|
||
|
||
| 字段 | 类型 | 必填 | 说明 |
|
||
|---|---|---|---|
|
||
| `name` | string | 是 | 知识库名称 |
|
||
| `description` | string | 否 | 描述 |
|
||
| `chunkSize` | number | 否 | 分块大小(默认 512) |
|
||
| `chunkOverlap` | number | 否 | 分块重叠(默认 50) |
|
||
|
||
**混合检索**
|
||
|
||
- **方法**:`POST /api/v1/rag/search`
|
||
- **认证**:JWT
|
||
- **请求体**:
|
||
|
||
```json
|
||
{
|
||
"query": "如何配置多租户权限?",
|
||
"knowledgeBaseIds": ["uuid-1", "uuid-2"],
|
||
"topK": 10,
|
||
"useRerank": true
|
||
}
|
||
```
|
||
|
||
- **响应**:返回检索结果列表,包含文档片段、相似度分数及来源信息。
|
||
|
||
---
|
||
|
||
##### 飞书机器人(Feishu Bot)
|
||
飞书集成基于 WebSocket 长连接,支持交互式消息卡片。
|
||
|
||
**绑定飞书机器人**
|
||
|
||
- **方法**:`POST /api/v1/feishu/bind`
|
||
- **认证**:JWT(需 `feishu:manage` 权限)
|
||
- **请求体**:
|
||
|
||
```json
|
||
{
|
||
"appId": "cli_xxxxxxxx",
|
||
"appSecret": "xxxxxxxxxxxxxxxx",
|
||
"encryptKey": "optional-encrypt-key"
|
||
}
|
||
```
|
||
|
||
**Webhook 回调**
|
||
|
||
- **方法**:`POST /api/v1/feishu/webhook`
|
||
- **认证**:飞书签名校验(`X-Lark-Signature` 请求头)
|
||
- **请求体**:飞书事件推送标准格式,包含事件类型、消息内容及用户 Open ID。
|
||
|
||
**发送评估指令**
|
||
|
||
- **方法**:`POST /api/v1/feishu/assessment-command`
|
||
- **认证**:API Key
|
||
- **请求体**:
|
||
|
||
```json
|
||
{
|
||
"openId": "ou_xxxxxxxx",
|
||
"command": "start_assessment",
|
||
"templateId": "uuid-string"
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
##### 用户管理(User)
|
||
**创建用户**
|
||
|
||
- **方法**:`POST /api/v1/users`
|
||
- **认证**:JWT(需 `user:create` 权限)
|
||
- **请求体**:
|
||
|
||
```json
|
||
{
|
||
"username": "zhangsan",
|
||
"password": "password123",
|
||
"displayName": "张三",
|
||
"role": "USER",
|
||
"tenantId": "uuid-string"
|
||
}
|
||
```
|
||
|
||
| 字段 | 类型 | 必填 | 说明 |
|
||
|---|---|---|---|
|
||
| `username` | string | 是 | 登录用户名(唯一) |
|
||
| `password` | string | 是 | 密码(最少 8 位) |
|
||
| `displayName` | string | 是 | 显示名称 |
|
||
| `role` | enum | 是 | `USER` / `TENANT_ADMIN` / `SUPER_ADMIN` |
|
||
| `tenantId` | string | 否 | 租户 ID(超级管理员创建时可选) |
|
||
|
||
---
|
||
|
||
#### 接口前缀与版本
|
||
- 所有业务接口统一前缀:`/api/v1`
|
||
- 管理端接口:`/api/admin`
|
||
- 健康检查:`GET /api/health`
|
||
|
||
完整的错误码规范与分页参数约定详见 **API 参考** 章节。
|
||
|
||
### 5.2 内部接口
|
||
|
||
#### 模块间调用架构
|
||
AuraK 后端采用 NestJS 模块化架构,各业务模块通过依赖注入(Dependency Injection)进行内部调用。核心调用链路涉及认证、知识库、评估、飞书集成及外部服务(Elasticsearch、Tika、LibreOffice)等模块。
|
||
|
||
```mermaid
|
||
graph LR
|
||
subgraph 客户端层
|
||
Web前端
|
||
飞书机器人
|
||
end
|
||
|
||
subgraph 网关与认证层
|
||
AuthController
|
||
ApiKeyGuard
|
||
JwtAuthGuard
|
||
PermissionGuard
|
||
end
|
||
|
||
subgraph 业务模块层
|
||
KnowledgeBaseService
|
||
AssessmentService
|
||
ChatService
|
||
FeishuService
|
||
NoteService
|
||
end
|
||
|
||
subgraph 基础设施服务层
|
||
ElasticsearchService
|
||
TikaService
|
||
LibreOfficeService
|
||
EmbeddingService
|
||
RagService
|
||
end
|
||
|
||
Web前端 --> AuthController
|
||
飞书机器人 --> FeishuService
|
||
AuthController --> JwtAuthGuard
|
||
AuthController --> ApiKeyGuard
|
||
AuthController --> PermissionGuard
|
||
KnowledgeBaseService --> TikaService
|
||
KnowledgeBaseService --> ElasticsearchService
|
||
KnowledgeBaseService --> EmbeddingService
|
||
AssessmentService --> RagService
|
||
ChatService --> RagService
|
||
ChatService --> ElasticsearchService
|
||
FeishuService --> AssessmentService
|
||
FeishuService --> ChatService
|
||
NoteService --> ElasticsearchService
|
||
```
|
||
|
||
#### 认证与授权调用链
|
||
所有内部接口(除标记 `@Public()` 的端点外)均需通过认证与授权检查。调用链如下:
|
||
|
||
1. **请求进入**:客户端请求到达对应的 Controller。
|
||
2. **守卫链执行**:NestJS 按顺序执行全局守卫与路由级守卫。
|
||
- `JwtAuthGuard`:校验 `Authorization: Bearer <token>` 中的 JWT,解析用户身份。
|
||
- `ApiKeyGuard`:校验 `X-API-Key` 请求头,用于服务间调用。
|
||
- `PermissionGuard`:结合 `@Permissions()` 装饰器,校验当前用户是否具备所需权限码。
|
||
- `RolesGuard`:校验用户角色(`SUPER_ADMIN`、`TENANT_ADMIN`、`USER`)。
|
||
3. **租户隔离**:`TenantMiddleware` 解析请求头中的租户标识,写入 `TenantStore`,供数据查询时自动附加租户过滤条件。
|
||
4. **业务处理**:通过认证后,请求进入 Service 层执行具体业务逻辑。
|
||
|
||
#### 服务间调用方式
|
||
模块间通过 NestJS 的 `@InjectRepository()` 或构造函数注入 Service 实例实现调用。典型调用关系如下:
|
||
|
||
| 调用方 | 被调用方 | 调用目的 |
|
||
|---|---|---|
|
||
| `FeishuService` | `AssessmentService` | 处理飞书消息中的评估指令,创建评估会话 |
|
||
| `FeishuService` | `ChatService` | 转发飞书消息至 AI 对话 |
|
||
| `AssessmentService` | `RagService` | 生成面试追问时检索知识库上下文 |
|
||
| `ChatService` | `RagService` | 对话时进行知识库混合检索(BM25 + 向量) |
|
||
| `KnowledgeBaseService` | `TikaService` | 文档内容提取(快速处理模式) |
|
||
| `KnowledgeBaseService` | `EmbeddingService` | 生成文档块向量用于索引 |
|
||
| `KnowledgeBaseService` | `ElasticsearchService` | 写入/查询文档索引 |
|
||
| `AssessmentService` | `ExportService` | 导出评估报告(PDF) |
|
||
| `ExportService` | `LibreOfficeService` | 将 Markdown 转换为 PDF |
|
||
|
||
#### 内部服务调用示例
|
||
##### 飞书机器人调用评估服务
|
||
`FeishuService` 解析飞书消息中的命令(如 `/start_assessment`),通过 `FeishuAssessmentService` 调用 `AssessmentService` 创建评估会话:
|
||
|
||
```typescript
|
||
// feishu.service.ts(源码结构示意)
|
||
@Injectable()
|
||
export class FeishuService {
|
||
constructor(
|
||
private readonly feishuAssessmentService: FeishuAssessmentService,
|
||
private readonly chatService: ChatService,
|
||
) {}
|
||
|
||
async handleMessage(payload: WebhookDto) {
|
||
// 解析消息命令
|
||
const command = this.assessmentCommandParser.parse(payload.text);
|
||
if (command.type === 'assessment') {
|
||
return this.feishuAssessmentService.handleCommand(command, payload);
|
||
}
|
||
// 默认转发至 AI 对话
|
||
return this.chatService.sendMessage(payload);
|
||
}
|
||
}
|
||
```
|
||
|
||
##### 知识库处理管道
|
||
`KnowledgeBaseService` 根据文档类型选择处理路径,调用内部服务完成文档解析、分块、向量化与索引:
|
||
|
||
```typescript
|
||
// knowledge-base.service.ts(源码结构示意)
|
||
async processDocument(file: Express.Multer.File, kbId: string) {
|
||
// 1. 调用 Tika 提取文本
|
||
const text = await this.tikaService.extractText(file);
|
||
// 2. 调用 TextChunkerService 分块
|
||
const chunks = this.textChunkerService.chunk(text, chunkConfig);
|
||
// 3. 调用 EmbeddingService 生成向量
|
||
const embeddings = await this.embeddingService.generate(chunks);
|
||
// 4. 调用 ElasticsearchService 写入索引
|
||
await this.elasticsearchService.indexDocuments(kbId, chunks, embeddings);
|
||
}
|
||
```
|
||
|
||
#### 内部接口鉴权机制
|
||
内部服务间调用通过以下机制保障安全:
|
||
|
||
| 机制 | 实现方式 | 适用场景 |
|
||
|---|---|---|
|
||
| **API Key** | `ApiKeyGuard` 校验 `X-API-Key` 请求头,密钥存于 `api_key` 表 | 外部系统或可信服务调用 |
|
||
| **JWT** | `JwtAuthGuard` 校验 Bearer Token | 用户登录后的前端请求 |
|
||
| **租户隔离** | `TenantMiddleware` + `TenantEntitySubscriber` 自动附加租户条件 | 所有多租户数据访问 |
|
||
| **权限码** | `PermissionGuard` + `@Permissions()` 装饰器,共 26 个细粒度权限 | 管理类操作 |
|
||
|
||
#### 内部调用流程说明
|
||
1. **同步调用**:大部分模块间调用为同步 HTTP 或进程内方法调用,如 `ChatService` 调用 `RagService` 进行检索。
|
||
2. **异步任务**:耗时操作(如文档导入、PDF 生成)通过 `ImportTaskService` 创建任务记录,由后台异步执行,前端通过轮询任务状态获取结果。
|
||
3. **WebSocket**:飞书机器人通过 `FeishuWsManager` 维护 WebSocket 连接,实现消息的实时推送与接收。
|
||
|
||
> 关于各模块对外暴露的 REST 端点及请求/响应格式,详见“API 参考”章节。
|
||
|
||
### 5.3 数据格式
|
||
|
||
#### 全局约定
|
||
#### 请求与响应格式
|
||
系统采用标准的 **RESTful JSON** 格式进行数据交换。所有 API 请求与响应均使用 `Content-Type: application/json`(文件上传接口除外)。响应体统一封装为以下结构:
|
||
|
||
```json
|
||
{
|
||
"code": 0,
|
||
"data": {},
|
||
"message": "success"
|
||
}
|
||
```
|
||
|
||
| 字段 | 类型 | 说明 |
|
||
|---|---|---|
|
||
| `code` | number | 业务状态码,`0` 表示成功,非零表示失败 |
|
||
| `data` | object/array | 业务数据负载,可为空对象 |
|
||
| `message` | string | 状态描述信息 |
|
||
|
||
#### 日期时间格式
|
||
所有时间字段统一采用 **ISO 8601** 标准格式的 UTC 字符串,精确到毫秒:
|
||
|
||
```json
|
||
{
|
||
"createdAt": "2026-04-23T08:30:00.000Z",
|
||
"updatedAt": "2026-04-23T08:30:00.000Z"
|
||
}
|
||
```
|
||
|
||
前端展示时由客户端根据本地时区进行转换。数据库中以 SQLite 的 `datetime` 类型存储,通过 TypeORM 实体映射为 JavaScript `Date` 对象。
|
||
|
||
#### 枚举与状态码
|
||
系统内部使用字符串枚举表示固定状态集合,主要枚举值如下:
|
||
|
||
| 枚举名称 | 取值 | 说明 |
|
||
|---|---|---|
|
||
| `UserRole` | `SUPER_ADMIN` / `TENANT_ADMIN` / `USER` | 用户角色三级体系 |
|
||
| `AssessmentStatus` | `IN_PROGRESS` / `COMPLETED` / `EXPIRED` | 评估会话状态 |
|
||
| `QuestionType` | `MULTIPLE_CHOICE` / `SHORT_ANSWER` | 题目类型 |
|
||
| `ImportTaskStatus` | `PENDING` / `PROCESSING` / `COMPLETED` / `FAILED` | 导入任务状态 |
|
||
|
||
#### 分页格式
|
||
列表类接口统一采用分页参数 `page`(页码,从 1 开始)与 `pageSize`(每页条数)。分页响应结构如下:
|
||
|
||
```json
|
||
{
|
||
"code": 0,
|
||
"data": {
|
||
"items": [],
|
||
"total": 100,
|
||
"page": 1,
|
||
"pageSize": 20
|
||
},
|
||
"message": "success"
|
||
}
|
||
```
|
||
|
||
| 字段 | 类型 | 说明 |
|
||
|---|---|---|
|
||
| `items` | array | 当前页数据列表 |
|
||
| `total` | number | 符合条件的总记录数 |
|
||
| `page` | number | 当前页码 |
|
||
| `pageSize` | number | 每页条数 |
|
||
|
||
#### 文件上传格式
|
||
文件上传接口使用 `multipart/form-data` 格式,支持的文件类型由 `file-support.constants.ts` 定义,涵盖文档、图片、音视频等常见格式。上传响应返回文件元数据:
|
||
|
||
```json
|
||
{
|
||
"code": 0,
|
||
"data": {
|
||
"id": "uuid-string",
|
||
"filename": "原始文件名.pdf",
|
||
"mimeType": "application/pdf",
|
||
"size": 1024000,
|
||
"url": "/uploads/xxx.pdf"
|
||
},
|
||
"message": "success"
|
||
}
|
||
```
|
||
|
||
#### 流式响应格式
|
||
AI 对话与评估相关接口支持 **SSE(Server-Sent Events)** 流式输出。响应以 `text/event-stream` 格式返回,每个事件包含 `data:` 前缀的 JSON 片段,以空行分隔。事件流结束以 `data: [DONE]` 标记。
|
||
|
||
#### 多租户数据约定
|
||
系统为多租户架构,租户标识通过请求头 `X-Tenant-Id` 传递。所有业务数据表均包含 `tenantId` 字段用于数据隔离,由 `tenant-entity.subscriber.ts` 中的实体订阅器自动注入,业务代码无需手动处理。
|
||
|
||
#### 错误码约定
|
||
业务错误码采用非零整数表示,具体错误码与 HTTP 状态码的映射关系详见 **API 规范** 章节中的「错误处理」子章节。错误响应体中的 `message` 字段支持多语言,由 `i18n` 模块根据请求头 `Accept-Language` 动态返回对应语言文本。
|
||
|
||
## 6. 用户界面
|
||
|
||
### 6.1 布局与导航
|
||
|
||
#### 整体布局结构
|
||
AuraK 前端采用 **React + React Router** 构建,整体布局分为两大区域:
|
||
|
||
- **认证区域**:登录页面(`web/src/pages/auth/Login.tsx`),独立于主布局。
|
||
- **工作区区域**:登录后进入,由 `WorkspaceLayout` 组件承载,包含侧栏导航与内容区。
|
||
|
||
工作区布局文件位于 `web/components/layouts/WorkspaceLayout.tsx`(另有 `web/src/components/layouts/WorkspaceLayout.tsx` 副本),采用侧栏(`SidebarRail`)+ 主内容区的经典结构。侧栏提供功能导航入口,主内容区根据路由动态渲染对应视图。
|
||
|
||
#### 路由配置
|
||
路由定义在 `web/App.tsx` 中,采用嵌套路由结构。工作区路由以 `workspace` 为父路径,子路由对应各功能页面:
|
||
|
||
| 路由路径 | 页面组件 | 功能 |
|
||
|:---------|:---------|:-----|
|
||
| `/login` | `Login.tsx` | 用户登录 |
|
||
| `/workspace` | `WorkspaceLayout` | 工作区父布局 |
|
||
| `/workspace/chat` | `ChatPage.tsx` | AI 对话 |
|
||
| `/workspace/knowledge` | `KnowledgePage.tsx` | 知识库管理 |
|
||
| `/workspace/notebooks` | `NotebooksPage.tsx` | 笔记本列表 |
|
||
| `/workspace/memos` | `MemosPage.tsx` | 备忘录 |
|
||
| `/workspace/assessment` | `AssessmentPage.tsx` | 考核评估 |
|
||
| `/workspace/assessment-stats` | `AssessmentStatsView.tsx` | 评估统计 |
|
||
| `/workspace/question-banks` | `QuestionBankView.tsx` | 题库列表 |
|
||
| `/workspace/question-banks/:id` | `QuestionBankDetailView.tsx` | 题库详情 |
|
||
| `/workspace/agents` | `AgentsPage.tsx` | AI 智能体 |
|
||
| `/workspace/plugins` | `PluginsPage.tsx` | 插件管理 |
|
||
| `/workspace/settings` | `SettingsPage.tsx` | 系统设置 |
|
||
|
||
> 注:`assessment-stats`、`question-banks` 等路由在 `App.tsx` 中可能以相对路径形式嵌套于 `workspace` 下,具体匹配规则以源码为准。
|
||
|
||
#### 侧栏导航
|
||
侧栏(`SidebarRail.tsx`)提供以下导航入口:
|
||
|
||
- **对话**(Chat)
|
||
- **知识库**(Knowledge)
|
||
- **笔记本**(Notebooks)
|
||
- **备忘录**(Memos)
|
||
- **考核评估**(Assessment)
|
||
- **评估统计**(Assessment Stats)
|
||
- **题库管理**(Question Banks)
|
||
- **智能体**(Agents)
|
||
- **插件**(Plugins)
|
||
- **设置**(Settings)
|
||
|
||
导航项通过图标 + 文本形式展示,点击后通过 React Router 的 `Link` 或 `useNavigate` 跳转到对应路由。
|
||
|
||
#### 关键视图与导航流程
|
||
##### 考核评估流程
|
||
考核评估是系统的核心功能,导航流程如下:
|
||
|
||
1. 用户从侧栏点击 **考核评估**,进入 `/workspace/assessment`。
|
||
2. `AssessmentPage.tsx` 渲染 `AssessmentView.tsx`,展示模板选择列表。
|
||
3. 用户选择模板后点击 **开始评估**,进入答题交互界面。
|
||
4. 答题完成后提交,展示结果与证书。
|
||
|
||
`AssessmentView.tsx` 内部包含多个子视图状态:
|
||
|
||
- **答题交互**:选择题(选项按钮 + 确认)、简答题(textarea + 发送)、AI 追问流程。
|
||
- **进度导航**:题序圆点(当前题蓝色、标记题黄色、其他灰色)+ 标记回头按钮。
|
||
- **提交确认**:未答完时弹出确认弹窗。
|
||
- **结果展示**:等级、分数、每题详情、报告。
|
||
- **证书弹窗**:等级、总分、维度得分、题目列表。
|
||
- **历史侧栏**:右侧展示考评历史列表。
|
||
|
||
##### 题库管理流程
|
||
1. 从侧栏点击 **题库管理**,进入 `/workspace/question-banks`。
|
||
2. `QuestionBankView.tsx` 展示题库卡片列表,支持搜索与筛选(全部/已发布/草稿/待审核)。
|
||
3. 点击题库卡片进入 `/workspace/question-banks/:id`,由 `QuestionBankDetailView.tsx` 渲染题库详情。
|
||
4. 详情页支持题目 CRUD、AI 生成、批量审核、提交审核(DRAFT→PENDING_REVIEW)、发布(PENDING_REVIEW→PUBLISHED)等操作。
|
||
|
||
##### 设置页面
|
||
`/workspace/settings` 由 `SettingsPage.tsx` 渲染,内部通过 Tab 切换不同设置模块,其中 **测评模板**(Tab: `assessment_templates`)由 `AssessmentTemplateManager.tsx` 实现,支持模板 CRUD、维度配置(添加/删除/权重)及 P2 配置(attemptLimit/reviewMode/shuffleQuestions/预约时段)。
|
||
|
||
#### 布局组件与权限控制
|
||
工作区布局中,部分导航项受权限控制。`PermissionGate.tsx` 组件用于根据用户权限决定是否渲染特定导航入口或页面内容。权限逻辑基于 `usePermissions` Hook(`web/src/hooks/usePermissions.ts`),权限定义见 `server/src/auth/permission/permission.constants.ts`。
|
||
|
||
#### 相关章节
|
||
- 各视图的具体交互细节与数据流,参见 **功能模块** 章节。
|
||
- 权限控制机制详见 **权限模型** 章节。
|
||
|
||
### 6.2 组件
|
||
|
||
#### 通用交互组件
|
||
前端 UI 层基于 React 19 + TypeScript + Vite 构建,`web/components/` 目录下集中存放可复用组件。按功能可划分为以下几组:
|
||
|
||
**对话框与弹窗类**
|
||
|
||
| 组件文件 | 功能说明 |
|
||
|---------|---------|
|
||
| `ConfirmDialog.tsx` | 通用确认对话框,配合 `contexts/ConfirmContext.tsx` 全局调用 |
|
||
| `CreateNoteFromPDFDialog.tsx` | 从 PDF 创建笔记的对话框 |
|
||
| `CreateNotebookDialog.tsx` / `EditNotebookDialog.tsx` | 笔记本的创建与编辑对话框 |
|
||
| `SettingsModal.tsx` / `IndexingModal.tsx` | 设置与索引进度弹窗 |
|
||
| `AICommandModal.tsx` | AI 指令输入弹窗 |
|
||
|
||
**抽屉类(Drawer)**
|
||
|
||
| 组件文件 | 功能说明 |
|
||
|---------|---------|
|
||
| `AICommandDrawer.tsx` | AI 指令侧边抽屉 |
|
||
| `ChunkInfoDrawer.tsx` | 知识库分块信息展示抽屉 |
|
||
| `CreateNotebookDrawer.tsx` / `EditNotebookDrawer.tsx` | 笔记本创建/编辑抽屉 |
|
||
| `GroupSelectionDrawer.tsx` | 知识分组选择抽屉 |
|
||
| `HistoryDrawer.tsx` | 对话历史记录抽屉 |
|
||
| `ImportFolderDrawer.tsx` | 文件夹导入抽屉 |
|
||
| `InputDrawer.tsx` | 通用输入抽屉 |
|
||
| `SettingsDrawer.tsx` | 设置抽屉 |
|
||
| `SourcePreviewDrawer.tsx` | 来源预览抽屉 |
|
||
| `drawers/ImportTasksDrawer.tsx` | 导入任务列表抽屉 |
|
||
|
||
**上传与拖拽类**
|
||
|
||
- `DragDropUpload.tsx` — 通用拖拽上传组件
|
||
- `NotebookDragDropUpload.tsx` — 笔记本场景专用拖拽上传
|
||
- `GlobalDragDropOverlay.tsx` / `NotebookGlobalDragDropOverlay.tsx` — 全局拖拽覆盖层
|
||
|
||
**选择器与展示类**
|
||
|
||
- `GroupSelector.tsx` / `GroupManager.tsx` — 知识分组选择与管理
|
||
- `ModeSelector.tsx` — 模式切换器
|
||
- `VisionModelSelector.tsx` — 视觉模型选择器
|
||
- `FileGroupTags.tsx` — 文件分组标签
|
||
- `SearchResultsPanel.tsx` / `SearchHistoryList.tsx` — 搜索结果与历史列表
|
||
- `PDFPreview.tsx` / `PDFSelectionTool.tsx` — PDF 预览与选区工具
|
||
- `UserInfoDisplay.tsx` — 用户信息展示
|
||
- `Logo.tsx` — 品牌 Logo
|
||
|
||
#### 聊天与 AI 相关组件
|
||
- `ChatInterface.tsx` — 聊天主界面,承载消息渲染与输入交互
|
||
- `ChatMessage.tsx` — 单条聊天消息组件,支持 Markdown 与流式渲染
|
||
- `ConfigPanel.tsx` — AI 配置面板
|
||
|
||
#### 权限控制组件
|
||
- `PermissionGate.tsx` — 基于权限的渲染门控组件,配合 `contexts/AuthContext.tsx` 与 `hooks/usePermissions.ts` 使用,控制按钮或区块的可见性。
|
||
|
||
#### 布局组件
|
||
`web/components/layouts/` 下提供:
|
||
|
||
- `WorkspaceLayout.tsx` — 工作区整体布局(同时存在于 `web/src/components/layouts/`)
|
||
- `SidebarRail.tsx` — 侧边栏轨道
|
||
- `AdminLayout.tsx` — 管理后台布局
|
||
|
||
#### 基础 UI 组件
|
||
`web/src/components/ui/` 提供原子级基础组件:
|
||
|
||
- `button.tsx` — 按钮
|
||
- `card.tsx` — 卡片容器
|
||
- `select.tsx` — 下拉选择器
|
||
|
||
#### 视图组件
|
||
`web/components/views/` 下为业务视图级组件,代表完整功能页面:
|
||
|
||
| 组件文件 | 对应功能 |
|
||
|---------|---------|
|
||
| `AssessmentView.tsx` | 考核评估主界面(含历史记录侧栏) |
|
||
| `AssessmentStatsView.tsx` | 评估统计面板(雷达图/趋势图) |
|
||
| `AssessmentTemplateManager.tsx` | 测评模板管理 |
|
||
| `QuestionBankView.tsx` / `QuestionBankDetailView.tsx` | 题库列表与详情 |
|
||
| `KnowledgeBaseView.tsx` | 知识库管理 |
|
||
| `ChatView.tsx` | 对话视图 |
|
||
| `NotebooksView.tsx` / `NotebookDetailView.tsx` | 笔记本列表与详情 |
|
||
| `MemosView.tsx` | 备忘录视图 |
|
||
| `PermissionSettingsView.tsx` | 权限设置矩阵 |
|
||
| `SettingsView.tsx` | 系统设置 |
|
||
| `PluginsView.tsx` | 插件管理 |
|
||
|
||
#### 上下文与工具
|
||
`web/contexts/` 提供全局状态:
|
||
|
||
- `AuthContext.tsx` — 认证状态
|
||
- `ConfirmContext.tsx` — 确认对话框上下文
|
||
- `LanguageContext.tsx` — 国际化语言上下文
|
||
- `ToastContext.tsx` — 轻提示上下文
|
||
|
||
`web/utils/` 提供工具函数:`clipboard.ts`(剪贴板)、`fileUtils.ts`(文件处理)、`translations.ts`(翻译映射)、`uuid.ts`(ID 生成)。
|
||
|
||
#### 组件间关系说明
|
||
考核评估模块是组件交互最复杂的场景:`AssessmentView.tsx` 作为主容器,内部协调 `ChatInterface` 渲染对话流、`HistoryDrawer` 展示历史记录、`ConfirmDialog` 处理操作确认,并通过 `services/assessmentService.ts` 与后端 LangGraph 状态机通信。题库管理则由 `QuestionBankView` 与 `QuestionBankDetailView` 两级视图构成,详情视图内嵌题目审核与批量操作面板。
|
||
|
||
> 关于视图组件对应的后端 API 与数据模型,详见「API 参考」与「数据模型」章节。
|
||
|
||
### 6.3 状态管理
|
||
|
||
#### 状态管理架构概览
|
||
AuraK 前端采用 **React Context** 作为全局状态管理方案,未引入 Redux、Zustand 等第三方状态库。所有全局状态均通过 Context Provider 在组件树顶层注入,配合自定义 Hooks 实现状态访问与更新。
|
||
|
||
#### 认证状态(AuthContext)
|
||
认证状态由 `web/src/contexts/AuthContext.tsx` 管理,负责用户登录态、令牌存储与权限信息的全局维护。
|
||
|
||
**核心职责:**
|
||
|
||
- 维护当前登录用户信息(用户名、显示名、角色等)
|
||
- 管理 JWT 令牌与 API Key 的存储(localStorage)
|
||
- 提供登录、登出、令牌刷新等操作
|
||
- 在应用初始化时恢复会话状态
|
||
|
||
**使用方式:**
|
||
|
||
```tsx
|
||
// 在组件中访问认证状态
|
||
const { user, isAuthenticated, login, logout } = useAuth();
|
||
```
|
||
|
||
认证流程为:密码登录 → 签发 JWT → 获取 API Key(存 localStorage)→ 后续请求通过 `x-api-key` 头携带,`x-tenant-id` 头指定租户上下文。
|
||
|
||
#### 语言状态(LanguageContext)
|
||
语言状态由 `web/contexts/LanguageContext.tsx` 管理,负责多语言界面的切换与翻译文本的提供。
|
||
|
||
**核心职责:**
|
||
|
||
- 维护当前语言(中文 / 英文 / 日文)
|
||
- 提供翻译函数,根据 key 返回对应语言的文本
|
||
- 语言切换时触发组件重新渲染
|
||
|
||
翻译文本定义在 `web/utils/translations.ts` 中,包含导航、按钮、提示等 UI 文案。例如:
|
||
|
||
```ts
|
||
// translations.ts 中的部分翻译 key
|
||
navAgent: "智能体",
|
||
navAssessment: "评测",
|
||
navPlugin: "插件",
|
||
switchLanguage: "切换语言",
|
||
```
|
||
|
||
#### 提示与确认状态(ToastContext / ConfirmContext)
|
||
这两个 Context 提供全局 UI 反馈能力:
|
||
|
||
- **ToastContext**(`web/contexts/ToastContext.tsx`):全局消息提示,用于操作成功、失败等轻量反馈。
|
||
- **ConfirmContext**(`web/contexts/ConfirmContext.tsx`):全局确认对话框,用于需要用户确认的破坏性操作(如删除)。
|
||
|
||
**使用示例:**
|
||
|
||
```tsx
|
||
const { showToast } = useToast();
|
||
const { confirm } = useConfirm();
|
||
|
||
// 触发提示
|
||
showToast('保存成功', 'success');
|
||
|
||
// 弹出确认框
|
||
await confirm('确定要删除该用户吗?');
|
||
```
|
||
|
||
#### 权限状态(usePermissions Hook)
|
||
权限判断逻辑封装在 `web/src/hooks/usePermissions.ts` 中,基于当前用户的角色与权限集合提供细粒度的访问控制。
|
||
|
||
**核心能力:**
|
||
|
||
- 检查当前用户是否拥有指定权限 key(如 `user:view`、`kb:edit`)
|
||
- 支持组件级别的权限门控渲染
|
||
|
||
权限门控组件 `PermissionGate`(`web/components/PermissionGate.tsx`)基于该 Hook 实现,用于条件渲染受权限保护的 UI 元素。
|
||
|
||
#### 服务层状态(Services)
|
||
各业务模块的状态通过 `web/services/` 目录下的服务模块管理,这些模块封装了 API 调用逻辑,并在组件内部通过 `useState` / `useEffect` 维护局部状态。主要服务包括:
|
||
|
||
| 服务模块 | 职责 |
|
||
|---|---|
|
||
| `authService.ts` | 登录、登出、令牌管理 |
|
||
| `userService.ts` | 用户 CRUD 操作 |
|
||
| `knowledgeBaseService.ts` | 知识库管理 |
|
||
| `assessmentService.ts` | 考核流程管理 |
|
||
| `questionBankService.ts` | 题库管理 |
|
||
| `chatService.ts` | 对话与流式响应 |
|
||
|
||
#### 租户上下文(服务端)
|
||
服务端通过 `server/src/tenant/tenant.store.ts` 维护租户上下文,前端请求通过 `x-tenant-id` 头传递租户标识,服务端中间件(`tenant.middleware.ts`)解析并注入当前租户上下文,实现多租户数据隔离。该机制在“多租户架构”章节中有详细说明。
|
||
|
||
#### 状态管理选型说明
|
||
项目选择 React Context 而非 Redux 等外部状态库,主要基于以下考量:
|
||
|
||
- 应用状态规模适中,Context 足以覆盖全局共享状态需求
|
||
- 减少依赖体积,保持轻量化
|
||
- 与 React 19 的并发特性天然兼容
|
||
|
||
对于组件内部的复杂状态(如表单、列表筛选),使用 React 内置的 `useState` / `useReducer` 管理,不提升至全局 Context,以降低不必要的重渲染开销。
|
||
|
||
## 7. 安全设计
|
||
|
||
### 7.1 认证与授权
|
||
|
||
#### 认证机制总览
|
||
AuraK 采用 **JWT + API Key 双机制** 进行身份认证。系统默认使用 JWT(JSON Web Token)作为主要认证方式,同时为服务间通信提供 API Key 认证通道。认证模块位于 `server/src/auth/` 目录下,基于 NestJS Passport 策略实现。
|
||
|
||
#### JWT 认证流程
|
||
JWT 认证基于 Passport 的 `local` 与 `jwt` 策略组合实现:
|
||
|
||
1. **登录**:用户通过 `POST /auth/login` 提交用户名与密码,`local.strategy.ts` 验证凭据。
|
||
2. **签发令牌**:认证成功后,`auth.service.ts` 签发 JWT 令牌并返回给客户端。
|
||
3. **请求携带**:客户端在后续请求的 `Authorization: Bearer <token>` 头中携带令牌。
|
||
4. **令牌验证**:`jwt.strategy.ts` 解析并验证令牌签名与有效期,将用户信息挂载到请求对象。
|
||
|
||
相关守卫(Guard)包括:
|
||
|
||
| 守卫 | 职责 |
|
||
|---|---|
|
||
| `local-auth.guard.ts` | 登录接口的本地认证守卫 |
|
||
| `jwt-auth.guard.ts` | 验证 JWT 令牌有效性 |
|
||
| `combined-auth.guard.ts` | 全局认证守卫,同时支持 JWT 与 API Key |
|
||
| `public.decorator.ts` | 标记公开接口,跳过认证 |
|
||
|
||
#### API Key 认证
|
||
除 JWT 外,系统通过 `api-key.guard.ts` 支持 API Key 认证。API Key 实体定义于 `server/src/auth/entities/api-key.entity.ts`,适用于服务间调用或自动化脚本场景。`combined-auth.guard.ts` 会优先尝试 JWT,若不存在则回退到 API Key 校验。
|
||
|
||
#### 角色体系
|
||
系统内置三级角色,定义于 `server/src/user/user-role.enum.ts`:
|
||
|
||
| 角色 | 权限数 | 核心能力 |
|
||
|---|---|---|
|
||
| **SUPER_ADMIN** | 26 项 | 全部权限:用户/租户/知识库/考核/模型/设置 |
|
||
| **TENANT_ADMIN** | 21 项 | 本租户管理:用户/知识库/考核/模型;不能跨租户、删用户、改系统设置 |
|
||
| **USER** | 5 项 | 使用知识库、参与考核、查看插件 |
|
||
|
||
角色实体(`role.entity.ts`)包含 `isSystem` 标记,系统角色受保护不可删改;`baseRole` 字段映射到 `UserRole` 枚举;`tenantId` 为 `null` 表示全局角色,非 `null` 则为租户自定义角色。
|
||
|
||
#### 权限模型(RBAC)
|
||
权限定义位于 `server/src/auth/permission/permission.constants.ts`,共 26 项细粒度权限,按分类组织:
|
||
|
||
| 分类 | 权限 |
|
||
|---|---|
|
||
| 用户管理 | `user:view` / `user:create` / `user:edit` / `user:delete` / `user:role` / `user:password` |
|
||
| 租户管理 | `tenant:view` / `tenant:create` / `tenant:edit` / `tenant:delete` / `tenant:members` |
|
||
| 知识库 | `kb:view` / `kb:create` / `kb:edit` / `kb:delete` / `kb:publish` |
|
||
| 考核 | `assess:view` / `assess:manage` / `assess:template` / `assess:bank` |
|
||
| 模型 | `model:view` / `model:config` |
|
||
| 插件 | `plugin:view` / `plugin:manage` |
|
||
| 设置 | `settings:view` / `settings:system` |
|
||
|
||
角色与权限通过 `role-permission.entity.ts` 关联表建立多对多关系。
|
||
|
||
#### 权限检查机制
|
||
权限检查通过装饰器与守卫组合实现:
|
||
|
||
```typescript
|
||
// 控制器示例
|
||
@UseGuards(PermissionGuard)
|
||
@Permission('kb:create')
|
||
@Post()
|
||
create() { /* ... */ }
|
||
```
|
||
|
||
核心组件:
|
||
|
||
- `permission.decorator.ts` — `@Permission()` 装饰器,声明所需权限
|
||
- `permission.guard.ts` — 校验当前用户是否具备所需权限
|
||
- `roles.decorator.ts` — `@Roles()` 装饰器,声明所需角色
|
||
- `roles.guard.ts` — 校验当前用户角色
|
||
- `super-admin.guard.ts` / `tenant-admin.guard.ts` — 针对特定角色的专用守卫
|
||
|
||
前端通过 `PermissionGate.tsx` 组件与 `usePermissions.ts` Hook 实现组件级权限门控,与后端权限定义保持一致。
|
||
|
||
#### 多租户数据隔离
|
||
系统通过 `tenant.middleware.ts` 与 `tenant-entity.subscriber.ts` 实现租户级数据隔离。请求经过中间件时解析当前租户上下文,实体订阅器在数据库操作时自动附加租户过滤条件,确保租户间数据不可互访。租户成员关系定义于 `tenant-member.entity.ts`。
|
||
|
||
#### 安全说明
|
||
- JWT 密钥通过环境变量 `JWT_SECRET` 配置(见 README 快速开始章节)。
|
||
- 代码审查记录指出 `knowledge-base.service.ts` 中存在动态引入 `jsonwebtoken` 的用法(第 1676-1685 行),建议统一通过 NestJS `JwtService` 管理令牌操作。
|
||
- 系统角色(SUPER_ADMIN、TENANT_ADMIN、USER)的权限不可修改,自定义角色可灵活配置权限矩阵。
|
||
|
||
> 相关 API 端点与请求/响应格式详见「API 参考」章节;用户 CRUD 与角色分配操作详见「用户管理」章节。
|
||
|
||
### 7.2 传输安全
|
||
|
||
#### 传输层加密(TLS/HTTPS)
|
||
AuraK 的传输安全由 Nginx 反向代理层统一承载。源码中 `nginx/nginx.conf` 与 `nginx/conf.d/` 目录下的配置文件定义了 HTTPS 的启用方式与证书管理策略。
|
||
|
||
##### 证书配置
|
||
Nginx 配置引用了位于 `nginx/conf.d/ssl/` 目录下的证书文件:
|
||
|
||
- **证书文件**:`cert.pem`
|
||
- **私钥文件**:`key.pem`
|
||
|
||
证书的生成由 `nginx/generate-ssl.sh` 脚本完成。该脚本用于生成自签名 SSL 证书,适用于开发环境或内网部署场景。生产环境部署时,应将自签名证书替换为由受信任的证书颁发机构(CA)签发的正式证书。
|
||
|
||
##### HTTPS 强制与重定向
|
||
Nginx 配置中实现了 HTTP 到 HTTPS 的强制跳转,确保所有客户端请求均通过加密通道传输。该机制有效防御以下攻击:
|
||
|
||
- **中间人攻击(MITM)**:通过 TLS 加密,防止攻击者在客户端与服务器之间窃听或篡改传输中的数据。
|
||
- **降级攻击**:强制使用 HTTPS,阻止攻击者将通信协议从 HTTPS 降级为明文 HTTP,从而规避加密保护。
|
||
|
||
##### 安全响应头
|
||
Nginx 配置中设置了多项安全响应头,以增强浏览器端的安全防护。具体配置项在源码中未完整列出,但根据 Nginx 配置文件的常规实践,通常包含以下内容(源码中未提供完整清单,以下为基于配置文件的推断):
|
||
|
||
| 响应头 | 作用 | 防御的攻击类型 |
|
||
|---|---|---|
|
||
| `X-Content-Type-Options: nosniff` | 禁止浏览器对响应内容进行 MIME 类型嗅探 | 内容嗅探攻击、MIME 混淆攻击 |
|
||
| `X-Frame-Options` | 控制页面是否允许被嵌入到 `<iframe>` 中 | 点击劫持(Clickjacking) |
|
||
| `X-XSS-Protection` | 启用浏览器内置的 XSS 过滤器 | 跨站脚本攻击(XSS) |
|
||
| `Strict-Transport-Security`(HSTS) | 强制浏览器仅通过 HTTPS 访问该域名 | SSL 剥离攻击、降级攻击 |
|
||
|
||
> **注意**:上述响应头的具体配置值在源码中未明确列出,标注为(源码中未提供)。实际部署时需根据 Nginx 配置文件确认。
|
||
|
||
#### 应用层安全中间件
|
||
##### 认证与授权守卫
|
||
后端服务(NestJS)通过一系列守卫(Guard)实现请求级别的安全控制,这些守卫在应用层提供了额外的传输安全补充:
|
||
|
||
| 守卫 | 文件路径 | 功能 |
|
||
|---|---|---|
|
||
| `JwtAuthGuard` | `server/src/auth/jwt-auth.guard.ts` | 验证请求中的 JWT 令牌,确保请求来自已认证用户 |
|
||
| `ApiKeyGuard` | `server/src/auth/api-key.guard.ts` | 验证 API Key,用于服务间通信或第三方集成 |
|
||
| `CombinedAuthGuard` | `server/src/auth/combined-auth.guard.ts` | 组合多种认证策略,灵活适配不同接口的认证需求 |
|
||
| `PermissionGuard` | `server/src/auth/permission/permission.guard.ts` | 基于 RBAC 权限模型,校验用户是否具备访问特定资源的权限 |
|
||
| `RolesGuard` | `server/src/auth/roles.guard.ts` | 基于角色(SUPER_ADMIN / TENANT_ADMIN / USER)进行访问控制 |
|
||
| `SuperAdminGuard` | `server/src/auth/super-admin.guard.ts` | 超级管理员专属守卫 |
|
||
| `TenantAdminGuard` | `server/src/auth/tenant-admin.guard.ts` | 租户管理员专属守卫 |
|
||
|
||
这些守卫共同构成了请求的认证与授权链路,确保只有经过身份验证且具备相应权限的用户才能访问受保护的资源。详细的认证与授权机制,请参阅「身份认证与权限控制」章节。
|
||
|
||
##### 租户隔离中间件
|
||
`server/src/tenant/tenant.middleware.ts` 实现了多租户隔离中间件,在请求处理链路中注入租户上下文,确保不同租户之间的数据严格隔离。该机制防御了:
|
||
|
||
- **越权访问攻击**:防止租户 A 的用户访问租户 B 的数据。
|
||
- **水平权限提升**:通过租户上下文校验,阻止用户跨租户操作资源。
|
||
|
||
#### 威胁模型总结
|
||
| 威胁类型 | 防御机制 | 实现层级 |
|
||
|---|---|---|
|
||
| 中间人攻击(MITM) | TLS/HTTPS 加密传输 | Nginx 反向代理 |
|
||
| 降级攻击(SSL Stripping) | HTTPS 强制跳转 + HSTS | Nginx 反向代理 |
|
||
| 点击劫持 | `X-Frame-Options` 响应头 | Nginx 反向代理 |
|
||
| MIME 嗅探攻击 | `X-Content-Type-Options` 响应头 | Nginx 反向代理 |
|
||
| 跨站脚本攻击(XSS) | `X-XSS-Protection` 响应头 + 内容过滤服务 | Nginx 反向代理 + 应用层 |
|
||
| 未授权访问 | JWT 认证 + RBAC 权限校验 | 应用层守卫 |
|
||
| 跨租户数据泄露 | 租户中间件 + 租户实体订阅器 | 应用层 |
|
||
|
||
#### 补充说明
|
||
- 源码中未发现 WebSocket 连接(如飞书机器人集成)的独立 TLS 配置,其传输安全同样依赖于 Nginx 反向代理层的 TLS 终止。
|
||
- 关于 API 密钥的存储与管理策略,请参阅「密钥管理与敏感信息保护」章节。
|
||
|
||
### 7.3 输入验证
|
||
|
||
#### 校验机制总览
|
||
AuraK 的输入验证采用 **NestJS 管道(Pipe)+ DTO 类校验器 + 自定义守卫** 的分层架构。所有外部请求在进入业务逻辑前,依次经过传输层 DTO 校验、控制器层守卫鉴权、服务层业务规则校验三道防线。校验失败统一返回 `400 Bad Request`(参数错误)或 `403 Forbidden`(权限不足)。
|
||
|
||
#### DTO 层校验规则
|
||
系统使用 `class-validator` 装饰器在 DTO 类上声明字段约束。以下为各核心模块的校验规则:
|
||
|
||
**认证模块(`server/src/auth/`)**
|
||
|
||
登录请求体校验(`auth.controller.ts` 中内联定义):
|
||
|
||
```typescript
|
||
// 登录接口 DTO 校验
|
||
class LoginDto {
|
||
@IsString()
|
||
@IsNotEmpty()
|
||
username: string;
|
||
|
||
@IsString()
|
||
@IsNotEmpty()
|
||
password: string;
|
||
}
|
||
```
|
||
|
||
**用户模块(`server/src/user/dto/`)**
|
||
|
||
`create-user.dto.ts` 定义创建用户时的完整校验规则:
|
||
|
||
```typescript
|
||
export class CreateUserDto {
|
||
@IsString()
|
||
@IsNotEmpty({ message: '用户名不能为空' })
|
||
@MaxLength(50)
|
||
username: string;
|
||
|
||
@IsString()
|
||
@MinLength(6, { message: '密码至少6位' })
|
||
@MaxLength(100)
|
||
password: string;
|
||
|
||
@IsString()
|
||
@IsOptional()
|
||
@MaxLength(100)
|
||
displayName?: string;
|
||
|
||
@IsEnum(UserRole)
|
||
role: UserRole;
|
||
}
|
||
```
|
||
|
||
`update-user.dto.ts` 使用 `PartialType` 继承创建 DTO,使所有字段变为可选:
|
||
|
||
```typescript
|
||
export class UpdateUserDto extends PartialType(CreateUserDto) {}
|
||
```
|
||
|
||
**评估模块(`server/src/assessment/dto/`)**
|
||
|
||
`create-template.dto.ts` 定义评估模板创建规则:
|
||
|
||
```typescript
|
||
export class CreateTemplateDto {
|
||
@IsString()
|
||
@IsNotEmpty()
|
||
name: string;
|
||
|
||
@IsString()
|
||
@IsOptional()
|
||
description?: string;
|
||
|
||
@IsArray()
|
||
@ValidateNested({ each: true })
|
||
@Type(() => DimensionDto)
|
||
dimensions: DimensionDto[];
|
||
|
||
@IsInt()
|
||
@Min(1)
|
||
@Max(100)
|
||
questionCount: number;
|
||
}
|
||
```
|
||
|
||
#### 守卫层权限校验
|
||
系统通过守卫(Guard)在路由处理前执行身份验证与权限检查:
|
||
|
||
**`combined-auth.guard.ts`** — 组合认证守卫,按顺序尝试 JWT、API Key、本地会话三种认证方式:
|
||
|
||
```typescript
|
||
@Injectable()
|
||
export class CombinedAuthGuard implements CanActivate {
|
||
async canActivate(context: ExecutionContext): Promise<boolean> {
|
||
// 依次尝试 JwtAuthGuard → ApiKeyGuard → LocalAuthGuard
|
||
// 任一通过则放行,全部失败返回 401
|
||
}
|
||
}
|
||
```
|
||
|
||
**`permission.guard.ts`** — 细粒度权限守卫,配合 `@Permissions()` 装饰器使用:
|
||
|
||
```typescript
|
||
@Injectable()
|
||
export class PermissionGuard implements CanActivate {
|
||
canActivate(context: ExecutionContext): boolean {
|
||
const requiredPermissions = this.reflector.get(
|
||
PERMISSIONS_KEY,
|
||
context.getHandler(),
|
||
);
|
||
// 从请求用户中提取权限列表
|
||
// 校验是否包含所有必需权限
|
||
}
|
||
}
|
||
```
|
||
|
||
**`admin.guard.ts` / `super-admin.guard.ts` / `tenant-admin.guard.ts`** — 角色守卫,分别校验 `SUPER_ADMIN`、`TENANT_ADMIN` 角色。
|
||
|
||
#### 内容过滤服务
|
||
`server/src/assessment/services/content-filter.service.ts` 提供针对用户输入文本的内容安全过滤:
|
||
|
||
```typescript
|
||
@Injectable()
|
||
export class ContentFilterService {
|
||
/**
|
||
* 过滤敏感词与不当内容
|
||
* @param text 用户输入的原始文本
|
||
* @returns 过滤后的安全文本
|
||
*/
|
||
filterContent(text: string): string {
|
||
// 基于敏感词库进行替换/删除
|
||
// 支持自定义敏感词配置
|
||
}
|
||
|
||
/**
|
||
* 检测文本是否包含违规内容
|
||
*/
|
||
containsBlockedContent(text: string): boolean {
|
||
// 返回布尔值,供上层业务决定是否拒绝请求
|
||
}
|
||
}
|
||
```
|
||
|
||
该服务在评估答题、知识库文档上传等场景中被调用,对用户提交的文本内容进行实时过滤。
|
||
|
||
#### 文件上传校验
|
||
`server/src/upload/upload.controller.ts` 对文件上传实施多重限制:
|
||
|
||
| 校验项 | 规则 | 实现方式 |
|
||
|---|---|---|
|
||
| 文件类型 | 白名单:`pdf`、`docx`、`md`、`txt` 等 | `fileFilter` 回调 |
|
||
| 文件大小 | 单文件上限(源码中未提供具体数值) | `limits.fileSize` |
|
||
| MIME 类型 | 与扩展名双重校验 | `fileFilter` + 服务端二次检查 |
|
||
|
||
#### 租户隔离校验
|
||
`server/src/tenant/tenant.middleware.ts` 实现多租户数据隔离的请求级校验:
|
||
|
||
```typescript
|
||
@Injectable()
|
||
export class TenantMiddleware implements NestMiddleware {
|
||
use(req: Request, res: Response, next: NextFunction) {
|
||
// 从请求头或 JWT 中提取租户标识
|
||
// 校验租户是否存在且用户属于该租户
|
||
// 将租户上下文注入请求对象
|
||
}
|
||
}
|
||
```
|
||
|
||
`tenant-entity.subscriber.ts` 在实体持久化时自动注入租户 ID,防止跨租户数据写入。
|
||
|
||
#### 全局管道配置
|
||
`server/src/main.ts` 中启用全局校验管道:
|
||
|
||
```typescript
|
||
app.useGlobalPipes(
|
||
new ValidationPipe({
|
||
whitelist: true, // 剥离 DTO 中未定义的属性
|
||
forbidNonWhitelisted: true, // 存在未定义属性时直接报错
|
||
transform: true, // 自动类型转换
|
||
transformOptions: {
|
||
enableImplicitConversion: true,
|
||
},
|
||
}),
|
||
);
|
||
```
|
||
|
||
`whitelist: true` 确保客户端无法通过注入额外字段绕过业务规则,`forbidNonWhitelisted` 则对多余字段直接返回 `400` 错误。
|
||
|
||
#### 其他校验点
|
||
- **API Key 校验**(`api-key.guard.ts`):校验请求头中的 API Key 是否有效且未过期
|
||
- **Webhook 签名校验**(`feishu/dto/webhook.dto.ts`):飞书事件回调的签名与时间戳校验
|
||
- **分页参数校验**:列表接口统一校验 `page`、`pageSize` 为正整数且不超过上限(具体上限值源码中未提供)
|
||
|
||
### 7.4 数据库安全
|
||
|
||
#### 数据加密机制
|
||
系统在数据库层面主要依赖 **SQLite** 作为持久化存储(`server/database.sqlite`),并通过 **TypeORM** 数据源(`server/src/data-source.ts`)进行连接管理。源码中未发现对数据库文件本身进行静态加密(如 SQLCipher 或字段级透明加密)的实现。
|
||
|
||
对于敏感字段的加密,系统采用 **应用层加密** 策略:
|
||
|
||
- **用户密码**:通过 `user.service.ts` 中的密码哈希处理,使用加盐哈希算法存储,不保存明文密码。
|
||
- **API 密钥**:`api-key.entity.ts` 中定义 API 密钥实体,密钥以密文形式存储,仅在创建时返回明文一次。
|
||
- **JWT 密钥**:通过环境变量 `JWT_SECRET` 配置,用于令牌签名与验证,不落库存储。
|
||
|
||
> 说明:源码中未提供具体的加密算法(如 AES-256、bcrypt 等)与密钥管理细节,相关实现细节(源码中未提供)。
|
||
|
||
#### 访问控制体系
|
||
##### 多租户数据隔离
|
||
系统实现了严格的多租户架构,通过 `tenant.middleware.ts` 在请求链路中解析当前租户上下文,并借助 `tenant-entity.subscriber.ts` 在数据库操作层面自动注入租户过滤条件,确保租户间数据不可越权访问。
|
||
|
||
核心机制:
|
||
|
||
- 每个业务实体(如笔记、知识库、评估会话)均包含 `tenantId` 字段。
|
||
- 数据库订阅器(Subscriber)在查询与写入时自动附加 `tenantId` 条件。
|
||
- 租户成员关系由 `tenant-member.entity.ts` 管理,控制用户与租户的归属关系。
|
||
|
||
##### 基于角色的权限控制(RBAC)
|
||
系统实现了三级角色体系与细粒度权限矩阵:
|
||
|
||
| 角色层级 | 说明 |
|
||
|---|---|
|
||
| `SUPER_ADMIN` | 系统级管理员,拥有全部权限 |
|
||
| `TENANT_ADMIN` | 租户级管理员,管理本租户内资源 |
|
||
| `USER` | 普通用户,按分配权限操作 |
|
||
|
||
权限控制通过以下组件协同实现:
|
||
|
||
- **`permission.guard.ts`**:校验当前用户是否具备访问特定接口所需的权限标识。
|
||
- **`permission.decorator.ts`**:在控制器方法上声明所需权限。
|
||
- **`roles.guard.ts`**:校验用户角色层级。
|
||
- **`admin.guard.ts` / `super-admin.guard.ts` / `tenant-admin.guard.ts`**:分别校验管理员、超级管理员与租户管理员身份。
|
||
- **`combined-auth.guard.ts`**:组合多种认证策略(JWT、API Key 等)。
|
||
|
||
系统内置 **26 项细粒度权限**(定义于 `permission.constants.ts`),覆盖知识库管理、评估操作、用户管理、系统设置等模块。自定义角色可通过 `role.entity.ts` 与 `role-permission.entity.ts` 动态配置权限集合。
|
||
|
||
##### 认证机制
|
||
| 认证方式 | 实现文件 | 说明 |
|
||
|---|---|---|
|
||
| **JWT 认证** | `jwt.strategy.ts` / `jwt-auth.guard.ts` | 基于 `JWT_SECRET` 签发与校验访问令牌 |
|
||
| **本地认证** | `local.strategy.ts` / `local-auth.guard.ts` | 用户名 + 密码登录认证 |
|
||
| **API 密钥认证** | `api-key.guard.ts` | 支持第三方系统通过 API 密钥访问受保护接口 |
|
||
|
||
#### 数据清理与维护
|
||
系统提供数据库清理脚本 `server/scripts/cleanup-question-bank.cjs`,用于定期清理题库中的冗余或过期数据。该脚本支持按条件批量删除无效题目记录,避免题库数据无限膨胀。
|
||
|
||
此外,`server/check_db.js` 与 `server/check_schema.js` 提供数据库健康检查与 Schema 校验能力,用于运维阶段的数据一致性验证。
|
||
|
||
#### 审计与追踪
|
||
系统内置 **审计日志** 机制(`audit-log.entity.ts` 与 `audit-log.service.ts`),记录关键操作行为(如登录、权限变更、评估提交等),为安全追溯提供数据支撑。审计日志的详细字段与查询接口参见 **安全设计** 章节中的“审计日志”子章节。
|
||
|
||
### 7.5 审计与日志
|
||
|
||
#### 审计日志实体
|
||
系统通过 `audit_log` 表记录所有关键操作行为,该表由 `AuditLogEntity` 定义,位于 `server/src/assessment/entities/audit-log.entity.ts`。
|
||
|
||
| 字段 | 类型 | 说明 |
|
||
|---|---|---|
|
||
| `id` | string | 主键,UUID 格式 |
|
||
| `userId` | string | 操作用户标识 |
|
||
| `username` | string | 操作用户名称 |
|
||
| `action` | string | 操作类型(如创建、更新、删除) |
|
||
| `resourceType` | string | 资源类型(如评估、模板、题库) |
|
||
| `resourceId` | string | 资源标识 |
|
||
| `details` | text | 操作详情,JSON 格式存储 |
|
||
| `ipAddress` | string | 操作来源 IP 地址 |
|
||
| `userAgent` | string | 操作终端信息 |
|
||
| `createdAt` | datetime | 操作时间戳 |
|
||
|
||
#### 审计日志服务
|
||
审计日志的写入由 `AuditLogService` 统一管理,该服务位于 `server/src/assessment/services/audit-log.service.ts`。服务提供以下核心方法:
|
||
|
||
- `record()` — 记录一条审计日志,接收 `userId`、`username`、`action`、`resourceType`、`resourceId`、`details` 等参数
|
||
- `findAll()` — 分页查询审计日志列表,支持按用户、操作类型、资源类型、时间范围等条件过滤
|
||
- `findOne()` — 根据日志 ID 查询单条审计日志详情
|
||
|
||
#### 审计内容范围
|
||
系统在以下关键业务节点自动写入审计日志:
|
||
|
||
- **评估流程**:评估会话的创建、进行中状态变更、完成与评分
|
||
- **模板管理**:评估模板的创建、修改、删除
|
||
- **题库管理**:题库条目的新增、编辑、删除
|
||
- **证书管理**:证书的生成与发放记录
|
||
|
||
#### 日志查询
|
||
审计日志可通过管理端接口进行查询。查询接口支持以下过滤参数:
|
||
|
||
| 参数 | 说明 |
|
||
|---|---|
|
||
| `userId` | 按操作用户过滤 |
|
||
| `action` | 按操作类型过滤 |
|
||
| `resourceType` | 按资源类型过滤 |
|
||
| `startTime` / `endTime` | 按时间范围过滤 |
|
||
| `page` / `pageSize` | 分页参数 |
|
||
|
||
#### 存储与保留
|
||
审计日志持久化存储于系统主数据库(SQLite)的 `audit_log` 表中,与业务数据同库存储。日志记录为追加写入模式,不提供修改或删除接口,确保操作记录的完整性与不可抵赖性。
|
||
|
||
> 说明:关于审计日志的访问权限控制,由系统的 RBAC 权限体系统一管理,具体权限模型与角色定义详见"权限管理"章节。
|
||
|
||
## 8. 部署与运维
|
||
|
||
### 8.1 环境配置
|
||
|
||
#### 环境变量配置
|
||
系统通过 `server/.env` 文件管理后端环境变量。部署前需复制示例文件并填写必填项:
|
||
|
||
```bash
|
||
cp server/.env.sample server/.env
|
||
```
|
||
|
||
#### 核心环境变量
|
||
| 变量 | 默认值 | 说明 |
|
||
|---|---|---|
|
||
| `PORT` | `3001` | 后端 API 服务端口 |
|
||
| `DATABASE_PATH` | `./data/metadata.db` | SQLite 数据库文件路径 |
|
||
| `ELASTICSEARCH_HOST` | `http://127.0.0.1:9200` | Elasticsearch 服务地址,用于向量存储与混合检索 |
|
||
| `JWT_SECRET` | (必填) | JWT 签名密钥,生产环境必须设置为强随机值 |
|
||
| `UPLOAD_FILE_PATH` | `./uploads` | 上传文件存储路径 |
|
||
| `MAX_FILE_SIZE` | `104857600` | 上传文件大小上限(默认 100MB) |
|
||
|
||
> **注意**:`JWT_SECRET` 为必填项,未设置将导致认证功能不可用。
|
||
|
||
#### 服务端口规划
|
||
系统由多个服务组件构成,各服务端口分配如下:
|
||
|
||
| 服务 | 端口 | 用途 |
|
||
|---|---|---|
|
||
| 后端 API | `3001` | NestJS REST API |
|
||
| 前端(开发) | `13001` | Vite 开发服务器 |
|
||
| 前端(生产) | `80 / 443` | Nginx 反向代理 |
|
||
| Elasticsearch | `9200` | 向量存储与混合检索 |
|
||
| Apache Tika | `9998` | 文档文本提取 |
|
||
| LibreOffice Server | `8100` | 文档格式转换 |
|
||
|
||
#### 搭建步骤
|
||
#### 方式一:Docker Compose(推荐)
|
||
启动基础设施依赖服务(Elasticsearch、Tika、LibreOffice):
|
||
|
||
```bash
|
||
docker-compose up -d elasticsearch tika libreoffice
|
||
```
|
||
|
||
#### 方式二:无 Docker 快速启动
|
||
直接启动编译后的后端与前端开发服务器:
|
||
|
||
```bash
|
||
cd /d/AuraK/server && node dist/main.js &
|
||
cd /d/AuraK/web && npx vite --port 13001 &
|
||
```
|
||
|
||
#### 开发模式启动
|
||
```bash
|
||
# 安装依赖
|
||
yarn install
|
||
|
||
# 配置环境变量
|
||
cp server/.env.sample server/.env
|
||
# 编辑 server/.env,设置 JWT_SECRET
|
||
|
||
# 启动开发服务器(前后端并行)
|
||
yarn dev
|
||
```
|
||
|
||
启动后访问:
|
||
- 前端:`http://localhost:13001`
|
||
- 后端:`http://localhost:3001`
|
||
|
||
#### 默认账号
|
||
系统初始化后提供默认管理员账号:
|
||
|
||
| 用户名 | 密码 |
|
||
|---|---|
|
||
| `admin` | `admin123` |
|
||
|
||
> **安全提示**:生产环境部署后应立即修改默认密码。
|
||
|
||
#### 数据库初始化
|
||
系统使用 SQLite 数据库,TypeORM 配置了 `synchronize: true` 自动建表。如需重置数据库,删除 `metadata.db` 文件后重启服务即可自动重建。
|
||
|
||
直接查询数据库示例:
|
||
|
||
```bash
|
||
node -e "
|
||
const s = require('better-sqlite3');
|
||
const d = new s('server/data/metadata.db');
|
||
const r = d.prepare('SELECT * FROM users').all();
|
||
console.log(r);
|
||
d.close();
|
||
"
|
||
```
|
||
|
||
#### 前端生产构建
|
||
生产环境前端通过 Nginx 反向代理提供服务(端口 `80/443`),Nginx 配置文件位于 `nginx/` 目录,包含 SSL 证书配置(`nginx/conf.d/ssl/`)。SSL 证书可通过 `nginx/generate-ssl.sh` 脚本生成。
|
||
|
||
#### 代码格式化
|
||
后端代码格式化命令:
|
||
|
||
```bash
|
||
cd server && yarn format
|
||
```
|
||
|
||
#### 相关说明
|
||
- 多租户数据隔离与权限体系(RBAC)的详细配置请参阅「权限与租户管理」章节。
|
||
- 各服务模块的详细配置项(如 Elasticsearch 索引、LibreOffice 转换参数)请参阅「服务组件配置」章节。
|
||
|
||
### 8.2 容器化
|
||
|
||
#### 容器化概览
|
||
AuraK 采用 Docker Compose 作为容器化编排方案,覆盖基础设施服务(Elasticsearch、Apache Tika、LibreOffice)以及应用服务(后端 server、前端 web)。项目根目录下的 `docker-compose.yml` 定义了全部服务编排,各服务均有独立的 `Dockerfile` 用于镜像构建。
|
||
|
||
#### 服务编排
|
||
`docker-compose.yml` 中定义的服务包括:
|
||
|
||
| 服务名 | 说明 | 构建上下文 |
|
||
|---|---|---|
|
||
| `elasticsearch` | 搜索引擎(版本 9.2.1),提供向量检索与全文检索能力 | 官方镜像 |
|
||
| `tika` | Apache Tika 文档解析服务,用于知识库文件内容提取 | 官方镜像 |
|
||
| `libreoffice` | LibreOffice 文档转换服务,将 Office 文档转换为 PDF | `./libreoffice-server` |
|
||
| `server` | NestJS 后端服务 | `./server` |
|
||
| `web` | React 前端服务 | `./web` |
|
||
|
||
##### 开发环境启动
|
||
开发模式下仅需启动基础设施服务,应用服务通过本地进程运行:
|
||
|
||
```bash
|
||
docker-compose up -d elasticsearch tika libreoffice
|
||
yarn dev
|
||
```
|
||
|
||
##### 生产环境启动
|
||
生产环境构建并启动全部服务:
|
||
|
||
```bash
|
||
# 构建并启动所有服务
|
||
docker-compose up --build
|
||
|
||
# 后台运行
|
||
docker-compose up -d
|
||
```
|
||
|
||
##### 服务管理
|
||
```bash
|
||
# 停止服务
|
||
docker-compose down
|
||
|
||
# 查看状态
|
||
docker-compose ps
|
||
|
||
# 查看日志(所有服务)
|
||
docker-compose logs -f
|
||
|
||
# 查看特定服务日志
|
||
docker-compose logs -f server
|
||
docker-compose logs -f web
|
||
```
|
||
|
||
#### 后端服务镜像(server/Dockerfile)
|
||
后端服务基于 Node.js 构建,采用多阶段构建方式(源码中未提供 Dockerfile 具体内容,以下为项目结构推断的构建流程):
|
||
|
||
- 构建上下文:`./server`
|
||
- 运行环境:Node.js 18+
|
||
- 启动命令:`node dist/main.js`
|
||
- 默认端口:3001
|
||
|
||
后端服务的关键环境变量(详见配置章节):
|
||
|
||
| 变量 | 默认值 | 用途 |
|
||
|---|---|---|
|
||
| `PORT` | 3001 | 后端服务端口 |
|
||
| `DATABASE_PATH` | `./data/metadata.db` | SQLite 数据库路径 |
|
||
| `ELASTICSEARCH_HOST` | `http://127.0.0.1:9200` | 搜索引擎地址 |
|
||
| `JWT_SECRET` | (必填) | JWT 签名密钥 |
|
||
| `UPLOAD_FILE_PATH` | `./uploads` | 文件存储路径 |
|
||
| `MAX_FILE_SIZE` | 104857600 | 上传大小限制(100MB) |
|
||
|
||
#### 前端服务镜像(web/Dockerfile)
|
||
前端服务基于 Node.js 构建并运行 Vite 开发服务器:
|
||
|
||
- 构建上下文:`./web`
|
||
- 运行环境:Node.js 18+
|
||
- 启动命令:`npx vite --port 13001`
|
||
- 默认端口:13001
|
||
|
||
#### LibreOffice 转换服务
|
||
`libreoffice-server` 目录包含独立的文档转换服务,提供以下功能:
|
||
|
||
- **文档转换**:将 `.doc`、`.docx`、`.ppt`、`.pptx`、`.xls`、`.xlsx` 等格式转换为 PDF
|
||
- **健康检查**:`GET /health` 返回服务状态
|
||
- **API 文档**:`GET /docs` 提供 Swagger UI 接口文档
|
||
|
||
独立运行方式:
|
||
|
||
```bash
|
||
docker run -d \
|
||
--name lo-converter \
|
||
-p 8100:8100 \
|
||
-v ./uploads:/uploads \
|
||
-v ./temp:/temp \
|
||
libreoffice-server
|
||
```
|
||
|
||
#### Nginx 反向代理
|
||
项目包含 `nginx/` 目录,提供反向代理与 SSL 配置:
|
||
|
||
- 配置文件:`nginx/nginx.conf` 及 `nginx/conf.d/kb.conf`
|
||
- SSL 证书:`nginx/conf.d/ssl/` 目录下存放 `cert.pem` 与 `key.pem`
|
||
- 证书生成脚本:`nginx/generate-ssl.sh`
|
||
|
||
Nginx 作为前端入口,将请求路由至后端服务与知识库相关服务。
|
||
|
||
#### 编排架构
|
||
```mermaid
|
||
graph LR
|
||
Client[客户端] --> Nginx[Nginx 反向代理]
|
||
Nginx --> Web[Web 前端 :13001]
|
||
Nginx --> Server[Server 后端 :3001]
|
||
Server --> ES[(Elasticsearch :9200)]
|
||
Server --> SQLite[(SQLite 数据库)]
|
||
Server --> Tika[Apache Tika 文档解析]
|
||
Server --> LO[LibreOffice 转换服务 :8100]
|
||
```
|
||
|
||
#### 数据持久化
|
||
- **SQLite 数据库**:默认存储于 `server/data/metadata.db`,通过 `DATABASE_PATH` 环境变量配置
|
||
- **上传文件**:存储于 `UPLOAD_FILE_PATH` 指定的目录(默认 `./uploads`)
|
||
- **Elasticsearch 数据**:由 Elasticsearch 容器管理(具体卷配置源码中未提供)
|
||
|
||
#### 相关章节
|
||
- 环境变量与配置项的完整说明见「配置」章节。
|
||
- 各服务的 API 端点定义见「API 参考」章节。
|
||
|
||
### 8.3 监控与日志
|
||
|
||
#### 健康检查
|
||
系统未提供独立的健康检查端点(如 `/health` 或 `/healthz`)。服务可用性可通过以下方式间接确认:
|
||
|
||
- **后端服务**:NestJS 默认监听 `3001` 端口,可通过访问根路径或任意 API 端点确认服务是否响应。
|
||
- **前端服务**:Vite 开发服务器监听 `13001` 端口,生产环境由 Nginx 托管静态资源。
|
||
- **基础设施依赖**:Elasticsearch、Tika、LibreOffice 等依赖服务通过 `docker-compose.yml` 管理,容器状态可通过 `docker ps` 查看。
|
||
|
||
> 源码中未提供专门的健康检查实现或探针配置。
|
||
|
||
---
|
||
|
||
#### 日志体系
|
||
##### 后端日志
|
||
后端基于 NestJS 框架,使用其内置的日志模块。源码中未发现自定义日志中间件或日志级别配置,默认行为如下:
|
||
|
||
- **请求日志**:NestJS 默认不输出请求级访问日志,需依赖反向代理(Nginx)的访问日志。
|
||
- **应用日志**:框架及业务代码中的 `Logger` 调用会输出至标准输出(stdout/stderr),由容器运行时或进程管理器收集。
|
||
- **错误日志**:未捕获的异常由 NestJS 全局异常过滤器处理,错误堆栈输出至控制台。
|
||
|
||
##### 前端日志
|
||
前端未引入独立的日志库。浏览器控制台输出主要来自:
|
||
|
||
- React 开发模式下的警告与错误信息。
|
||
- 业务代码中的 `console` 调用(源码中未系统化使用)。
|
||
|
||
##### 审计日志
|
||
系统内置审计日志模块,用于记录关键业务操作,区别于运行日志:
|
||
|
||
- **实体**:`audit-log.entity.ts` 定义审计日志数据结构。
|
||
- **服务**:`audit-log.service.ts` 提供写入与查询能力。
|
||
- **覆盖范围**:主要记录评估相关操作(如创建评估会话、提交答案等),具体字段包括操作类型、操作人、时间戳等。
|
||
|
||
> 审计日志的完整字段定义与查询 API 详见“数据模型”章节。
|
||
|
||
---
|
||
|
||
#### 可观测性
|
||
##### 指标监控
|
||
源码中未发现以下可观测性组件的集成:
|
||
|
||
- Prometheus 指标端点(`/metrics`)
|
||
- 应用性能监控(APM)代理
|
||
- 自定义业务指标计数器
|
||
|
||
##### 分布式追踪
|
||
未集成 OpenTelemetry、Jaeger 或 Zipkin 等追踪框架。跨服务调用链(如前端 → 后端 → Elasticsearch)无法通过标准追踪协议观测。
|
||
|
||
##### 内存监控
|
||
`knowledge-base/memory-monitor.service.ts` 提供内存使用监控能力,用于知识库处理场景:
|
||
|
||
- **功能**:监控文档处理过程中的内存占用,防止 OOM。
|
||
- **触发机制**:在知识库文档索引/处理任务中调用,超过阈值时记录警告或终止任务。
|
||
- **指标**:基于 `process.memoryUsage()` 获取堆内存与 RSS 数据。
|
||
|
||
##### 性能测试
|
||
项目根目录包含多个性能与健壮性测试脚本(如 `test-concurrent-assessments.mjs`、`tests/performance-and-robustness.e2e.spec.ts`),用于验证并发场景下的系统稳定性,但未提供线上运行时指标采集能力。
|
||
|
||
---
|
||
|
||
#### 运维建议
|
||
基于现有实现,建议补充以下可观测性能力(源码中未提供):
|
||
|
||
| 能力 | 建议方案 |
|
||
|---|---|
|
||
| 健康检查 | 新增 `/health` 端点,返回数据库连接、Elasticsearch 连通性等状态 |
|
||
| 结构化日志 | 集成 pino 或 winston,输出 JSON 格式日志并携带请求 ID |
|
||
| 指标采集 | 接入 Prometheus 客户端,暴露 HTTP 请求量、延迟、错误率等指标 |
|
||
| 链路追踪 | 引入 OpenTelemetry SDK,实现跨服务请求追踪 |
|
||
|
||
> 以上建议为基于当前代码结构的补充方向,非现有功能。
|
||
|
||
### 8.4 故障排查
|
||
|
||
#### Elasticsearch 无法启动
|
||
**现象:** 执行 `docker-compose up -d elasticsearch` 后,Elasticsearch 容器反复重启或直接退出,服务无法正常访问。
|
||
|
||
**原因:** Elasticsearch 对系统内存有较高要求,默认配置下容易触发内存不足或锁定内存失败的问题。
|
||
|
||
**解决方案:** 检查 `docker-compose.yml` 中 Elasticsearch 服务的内存限制配置,确保 `ES_JAVA_OPTS` 环境变量设置的堆内存大小不超过宿主机可用内存,并确认 `vm.max_map_count` 系统参数已正确设置(建议值不低于 262144)。调整后重新执行 `docker-compose up -d elasticsearch`。
|
||
|
||
---
|
||
|
||
#### 文件上传失败
|
||
**现象:** 在知识库或笔记模块中上传文件时,请求报错或前端提示上传失败。
|
||
|
||
**原因:** 后端服务缺少文件存储所需的目录,或目录权限不足导致无法写入文件。
|
||
|
||
**解决方案:** 确保 `uploads/` 和 `temp/` 目录存在且具有正确的读写权限。可执行以下命令创建目录并授权:
|
||
|
||
```bash
|
||
mkdir -p uploads temp
|
||
chmod -R 755 uploads temp
|
||
```
|
||
|
||
若使用 Docker 部署,还需确认这些目录已挂载到宿主机且权限映射正确。
|
||
|
||
---
|
||
|
||
#### 前端页面无法访问
|
||
**现象:** 浏览器访问前端地址(开发环境默认 `http://localhost:13001`)时页面空白或连接被拒绝。
|
||
|
||
**原因:** 前端开发服务器未启动,或后端 API 服务(默认 `http://localhost:3001`)未正常运行,导致前端初始化请求失败。
|
||
|
||
**解决方案:** 按以下步骤逐一排查:
|
||
|
||
1. 确认后端服务已启动:执行 `curl http://localhost:3001` 检查是否返回响应。
|
||
2. 确认前端开发服务器已启动:在 `web/` 目录下执行 `npx vite --port 13001`。
|
||
3. 检查后端环境变量配置:确保 `server/.env` 文件存在,且 `JWT_SECRET` 等关键配置已正确设置。
|
||
4. 查看后端控制台日志,确认是否存在数据库连接失败或端口冲突等错误信息。
|
||
|
||
---
|
||
|
||
#### 登录失败或提示认证错误
|
||
**现象:** 使用默认账号 `admin / admin123` 登录时提示用户名或密码错误。
|
||
|
||
**原因:** 默认账号密码已被修改,或数据库中初始用户数据未正确初始化。
|
||
|
||
**解决方案:** 确认是否已有人修改过默认密码。若为全新部署,检查数据库迁移是否已执行——后端启动时会自动运行 TypeORM 迁移(位于 `server/src/migrations/` 目录),确保迁移成功完成。若迁移失败,可手动执行迁移命令后重启服务。
|
||
|
||
---
|
||
|
||
#### 知识库文档解析失败
|
||
**现象:** 上传 PDF、Word 等格式文档后,知识库中文档状态一直处于“处理中”或解析失败。
|
||
|
||
**原因:** 文档解析依赖 Tika 或 LibreOffice 服务,这些基础设施容器未启动或版本不兼容。
|
||
|
||
**解决方案:** 确认相关基础设施服务已启动:
|
||
|
||
```bash
|
||
docker-compose up -d tika libreoffice
|
||
```
|
||
|
||
若服务已启动但仍解析失败,检查后端日志中 Tika 或 LibreOffice 的调用错误信息,确认网络连通性和接口地址配置是否正确。
|
||
|
||
## 9. 测试策略
|
||
|
||
### 9.1 单元测试
|
||
|
||
#### 测试框架与配置
|
||
AuraK 后端基于 **NestJS** 构建,单元测试采用 **Jest** 作为测试运行器,测试文件与源码同目录存放,以 `.spec.ts` 后缀命名。前端(`web/`)当前未配置单元测试框架,测试策略以端到端(E2E)测试为主。
|
||
|
||
后端 `server/package.json` 中声明的测试相关脚本如下(源码中未提供具体脚本命令,以下为推断说明):
|
||
|
||
| 配置项 | 说明 |
|
||
|---|---|
|
||
| 测试框架 | Jest(通过 `@nestjs/testing` 集成) |
|
||
| 测试文件位置 | 与源码同目录,命名规范为 `*.spec.ts` |
|
||
| 端到端测试目录 | `server/test/`,配置文件为 `jest-e2e.json` |
|
||
|
||
#### 单元测试覆盖范围
|
||
源码中已存在的单元测试文件覆盖以下核心模块:
|
||
|
||
##### 应用入口
|
||
- `app.controller.spec.ts` — 验证根控制器的基础响应逻辑。
|
||
|
||
##### 评估模块(Assessment)
|
||
评估模块是单元测试覆盖最密集的业务域,包含:
|
||
|
||
| 测试文件 | 被测对象 | 覆盖要点 |
|
||
|---|---|---|
|
||
| `assessment.controller.spec.ts` | 评估控制器 | 接口层参数校验与响应结构 |
|
||
| `assessment.service.spec.ts` | 评估服务 | 核心业务逻辑,包括评估流程编排 |
|
||
| `entities/question-bank-item.entity.spec.ts` | 题库实体 | 实体字段定义与校验规则 |
|
||
| `graph/builder.spec.ts` | 评估图构建器 | 有向无环图(DAG)的构建逻辑 |
|
||
| `graph/nodes/grader.node.spec.ts` | 评分节点 | 多维度加权评分计算 |
|
||
| `graph/nodes/interviewer.node.spec.ts` | 面试官节点 | 追问逻辑与对话状态管理 |
|
||
| `services/question-bank.service.spec.ts` | 题库服务 | 题目增删改查与查询逻辑 |
|
||
| `services/template.service.spec.ts` | 模板服务 | 评估模板的配置与校验 |
|
||
|
||
##### 飞书集成(Feishu)
|
||
- `services/assessment-command.parser.spec.ts` — 飞书消息指令解析器,覆盖指令格式解析与参数提取。
|
||
|
||
#### 测试模式示例
|
||
以下为 `assessment.service.spec.ts` 中典型的单元测试结构(基于源码推断的测试模式):
|
||
|
||
```typescript
|
||
describe('AssessmentService', () => {
|
||
let service: AssessmentService;
|
||
|
||
beforeEach(async () => {
|
||
const moduleRef = await Test.createTestingModule({
|
||
providers: [
|
||
AssessmentService,
|
||
// Mock 依赖项
|
||
{ provide: AssessmentRepository, useValue: mockRepository },
|
||
],
|
||
}).compile();
|
||
|
||
service = moduleRef.get(AssessmentService);
|
||
});
|
||
|
||
it('应正确创建评估会话', async () => {
|
||
// 测试断言
|
||
});
|
||
});
|
||
```
|
||
|
||
#### 端到端测试
|
||
除单元测试外,项目在 `server/test/` 目录下提供端到端测试配置(`jest-e2e.json`),用于验证完整的 HTTP 请求链路。根目录下的 `tests/` 目录包含基于 Playwright 的浏览器级 E2E 测试,覆盖评估全流程、题库管理、性能与健壮性等场景。
|
||
|
||
#### 覆盖率说明
|
||
源码中未提供单元测试覆盖率报告或阈值配置(如 `coverageThreshold`),因此无法给出具体的覆盖率数值。测试文件的存在表明核心业务模块(评估、题库、模板、飞书指令解析)均具备基础的单测保障,但覆盖率数据需通过运行测试后生成的报告获取。
|
||
|
||
### 9.2 集成测试
|
||
|
||
#### 测试策略与分层
|
||
AuraK 的集成测试遵循 **“分层测试 + 渐进覆盖”** 的策略,即先验证核心考核流程,再覆盖边界与异常场景,最后执行全量回归。该策略在 `docs/tests/assessment-test-plan.md` 中有明确定义,测试优先级划分为 P0(核心流程)、P1(评分与权限)、P2(压力与异常)。
|
||
|
||
整个集成测试体系包含三类测试资产:
|
||
|
||
- **端到端(E2E)测试**:基于 Playwright,存放于 `tests/` 目录,覆盖考核全流程、题库管理、性能与健壮性等场景。
|
||
- **API 级脚本测试**:基于 Node.js 的 `.mjs` 脚本(位于项目根目录),直接调用后端 HTTP 接口,验证业务逻辑、并发行为与权限隔离。
|
||
- **单元/集成测试**:NestJS 自带的 Jest 测试(`*.spec.ts`),针对服务层与图节点进行验证。
|
||
|
||
#### Playwright 配置与执行模型
|
||
`playwright.config.ts` 定义了 E2E 测试的运行参数,其设计体现了三个 Agent 的协作模式:
|
||
|
||
| 配置项 | 值 | 说明 |
|
||
|---|---|---|
|
||
| `testDir` | `./tests` | 测试用例存放目录 |
|
||
| `fullyParallel` | `true` | 用例间完全并行执行 |
|
||
| `retries` | CI 环境 2 次,本地 1 次 | 失败自动重试(Healer 角色) |
|
||
| `workers` | CI 环境 1,本地 3 | 并行 worker 数(Planner 角色) |
|
||
| `reporter` | HTML + list | 生成 `playwright-report` 报告并实时输出控制台 |
|
||
| `trace` | `on-first-retry` | 首次重试时保存 Trace 快照 |
|
||
| `screenshot` | `only-on-failure` | 失败时自动截图 |
|
||
| `video` | `on-first-retry` | 首次重试时录制视频 |
|
||
| `timeout` | 120000 ms | 单测超时 2 分钟 |
|
||
| `expect.timeout` | 10000 ms | 断言超时 10 秒 |
|
||
| `baseURL` | `http://localhost:13001` | 前端服务地址 |
|
||
|
||
#### 端到端测试用例
|
||
`tests/` 目录下包含以下 E2E 测试文件:
|
||
|
||
- `assessment.e2e.spec.ts` — 基础考核流程
|
||
- `full-assessment.e2e.spec.ts` — 完整考核链路
|
||
- `assessment-all-screens.e2e.spec.ts` — 全页面覆盖
|
||
- `question-bank.e2e.spec.ts` — 题库管理
|
||
- `performance-and-robustness.e2e.spec.ts` — 性能与健壮性
|
||
|
||
以 `assessment-test-plan.md` 中的 P0 用例为例,核心场景包括:
|
||
|
||
| 场景 | 操作步骤 | 预期结果 |
|
||
|---|---|---|
|
||
| 技术人员模板完整答题 | 登录 → 考核页 → 选模板 → 开始 → 答 4 题(MC+SA)→ 提交 → 查看结果 | 全部题目可答,显示等级和分数 |
|
||
| 选择题答题 | 检测选项 → 选择 → 确认 | 选项正确显示,确认成功 |
|
||
| 简答题答题 | 检测 textarea → 输入 → 发送 | 文字发送成功 |
|
||
| AI 追问流程 | 简答提交后检测 textarea 重现 → 输入回答 | 追问正常触发,回答后继续 |
|
||
|
||
#### API 级集成测试脚本
|
||
项目根目录下的 `.mjs` 脚本直接对后端 API 进行集成验证,覆盖范围包括:
|
||
|
||
| 脚本 | 覆盖内容 |
|
||
|---|---|
|
||
| `test-systematic.mjs` | 142 项系统化测试 |
|
||
| `test-full-coverage.mjs` | 52 项全量回归 |
|
||
| `test-p2-advanced.mjs` | 20 项 P2 高级功能 |
|
||
| `test-concurrent-assessments.mjs` | 并发考核场景 |
|
||
| `test-e2e-assessment-full-flow.mjs` | 考核全流程 |
|
||
| `test-permission-flow.mjs` | 权限流验证 |
|
||
| `test-user-lifecycle.mjs` | 用户生命周期 |
|
||
| `test-question-distribution.mjs` | 题目分布验证 |
|
||
| `test-multiround.mjs` | 多轮对话场景 |
|
||
|
||
#### 并发与异常场景验证
|
||
`assessment-test-plan.md` 的 Phase 4 明确了压力与异常测试要求:
|
||
|
||
- **并发场景**:10 人同时开启考核(`POST /assessment/start`),要求 Session ID 全部唯一;10 人同时提交答案(`POST /assessment/:id/answer`),要求全部成功且无数据竞争。
|
||
- **异常输入**:空模板 ID 启动返回 400;不存在的模板 ID 返回 400 或 404;不存在的 Session 答题返回 404;对已完成的 Session 再次答题返回 400 或适当错误。
|
||
- **状态冲突**:同一用户同一模板连续两次 `start`,第二次可能失败或开启新会话;强制结束不存在的会话返回 404。
|
||
|
||
#### 权限隔离验证
|
||
Phase 3 覆盖了角色级权限与会话隔离:
|
||
|
||
- USER 角色可查看考核页并参加考核,但设置页无“测评模板”Tab。
|
||
- TENANT_ADMIN 角色可管理模板,并能通过 `POST /api/assessment/templates` 创建模板。
|
||
- 用户不可查看或强制结束他人的考核会话(预期返回 404 或 Forbidden)。
|
||
|
||
#### 回归测试整合
|
||
`assessment-test-plan.md` 的 Phase 5 明确了回归测试的整合策略:保留 `test-systematic.mjs`(142 项)与 `test-full-coverage.mjs`(52 项)作为独立回归套件,将 `test-p2-advanced.mjs` 的 20 项合并至 Phase 1.3,将 `test-concurrent-assessments.mjs` 合并至 Phase 4.1,避免重复覆盖。
|
||
|
||
#### 实施步骤
|
||
测试方案建议按以下步骤推进:
|
||
|
||
1. 运行快速烟雾测试,定位当前故障。
|
||
2. 修复 Phase 1 中的阻断性问题。
|
||
3. 分阶段编写自动化测试脚本。
|
||
4. 执行完整测试并修复剩余问题。
|
||
5. 纳入 CI 或手动定期运行。
|
||
|
||
> 关于测试环境的搭建与运行方式,请参阅“测试环境与工具链”章节。
|
||
|
||
### 9.3 E2E 测试
|
||
|
||
#### 概述
|
||
AuraK 的端到端(E2E)测试采用 **Playwright** 作为核心浏览器自动化框架,覆盖从用户登录、模板选择、答题交互到结果查看的完整业务链路。测试脚本位于项目根目录,以 `test-*.mjs` 命名,同时 `tests/` 目录下存放基于 `@playwright/test` 框架的 `.spec.ts` 文件。
|
||
|
||
#### 测试架构
|
||
当前 E2E 测试体系分为两层:
|
||
|
||
| 层级 | 文件类型 | 运行方式 | 特点 |
|
||
|------|---------|---------|------|
|
||
| 原生 Playwright 脚本 | `test-*.mjs` | `node test-*.mjs` | 使用 `chromium.launch({ headless: true })` 手写,直接驱动浏览器 |
|
||
| 框架化测试 | `tests/*.e2e.spec.ts` | `npx playwright test` | 基于 `@playwright/test`,支持断言、分组、截图等高级特性 |
|
||
|
||
**现状说明**:根据 `docs/tests/playwright-agent-map.md` 的对照表,所有现有脚本均采用原生 Playwright 手写方式,未使用 `@playwright/test` 框架,也未启用 Generator、Planner、Healer 三个 Agent 的功能。
|
||
|
||
#### 测试脚本清单
|
||
| 脚本 | 覆盖范围 | 测试层面 |
|
||
|------|---------|---------|
|
||
| `test-systematic.mjs` | 142 项 — 认证/CRUD/RBAC/边界/UI | API + 原生 Playwright |
|
||
| `test-e2e-full.mjs` | 94 项 — 全角色 E2E | API + 原生 Playwright |
|
||
| `test-user-lifecycle.mjs` | 42 项 — 用户生命周期 + 异常边界 | API + 原生 Playwright |
|
||
| `test-permission-flow.mjs` | 三层角色权限边界验证 | API + 原生 Playwright |
|
||
| `test-multiround.mjs` | 考核多轮对话测试 | 原生 Playwright |
|
||
| `test-question-distribution.mjs` | 出题算法验证 | 纯 API |
|
||
| `exam-organizer.mjs` | 考试组织全流程(创建考生→考核→查看结果) | API + 原生 Playwright |
|
||
| `test-assessment-smoke.mjs` | 考核冒烟测试 | API + 原生 Playwright |
|
||
| `test-e2e-assessment-full-flow.mjs` | 考核全流程 E2E | API + 原生 Playwright |
|
||
| `test-p2-advanced.mjs` | P2 高级功能(20 项) | 纯 API |
|
||
| `test-concurrent-assessments.mjs` | 并发考核场景 | 纯 API |
|
||
| `test-full-coverage.mjs` | 全量覆盖 | 纯 API(无 UI) |
|
||
|
||
#### 框架化 E2E 测试
|
||
`tests/` 目录下包含基于 `@playwright/test` 框架的测试文件:
|
||
|
||
- `assessment.e2e.spec.ts` — 考核基础流程
|
||
- `full-assessment.e2e.spec.ts` — 考核完整流程
|
||
- `assessment-all-screens.e2e.spec.ts` — 考核全屏幕覆盖
|
||
- `question-bank.e2e.spec.ts` — 题库管理
|
||
- `performance-and-robustness.e2e.spec.ts` — 性能与健壮性
|
||
|
||
#### 关键测试场景
|
||
##### 考核多轮对话(`test-multiround.mjs`)
|
||
| 编号 | 场景 | 说明 |
|
||
|------|------|------|
|
||
| M-01 | 选择题答题 | 检测选项按钮 → 点击 → 确认答案 |
|
||
| M-02 | 简答题答题 | textarea 输入 → 发送按钮 |
|
||
| M-03 | AI 追问 | 简答后 textarea 重现 → 输入追问回答 |
|
||
| M-04 | 4 题全流程 | 完整完成 4 题混合题型 |
|
||
|
||
##### P2 高级功能(`test-p2-advanced.mjs`)
|
||
| 编号 | 功能 | 测试内容 |
|
||
|------|------|---------|
|
||
| P-01 | attemptLimit | 设 2 → 读取 = 2 |
|
||
| P-02 | reviewMode | 设 after_completion → 读取 |
|
||
| P-03 | shuffleQuestions | 设 true → 读取 |
|
||
| P-04 | 尝试次数限制 | 超限后拒绝 |
|
||
| P-05/P-06 | 预约开始/结束 | 未到时间/已过时间拒绝 |
|
||
| P-07/P-08 | 答题回顾 | 返回含正确答案与解析 |
|
||
| P-09 | shuffleQuestions 生效 | flag=true 时启用 |
|
||
| P-10 | 模板配置恢复 | 恢复后正常 |
|
||
|
||
#### 编写注意事项
|
||
**React 受控输入框** — 不要使用 `type()` 或 `fill()`,应使用 native setter:
|
||
|
||
```javascript
|
||
await page.evaluate((text) => {
|
||
const ta = document.querySelector('textarea');
|
||
if (!ta) return;
|
||
const setter = Object.getOwnPropertyDescriptor(HTMLTextAreaElement.prototype, 'value')?.set;
|
||
setter?.call(ta, text);
|
||
ta.dispatchEvent(new Event('input', { bubbles: true }));
|
||
}, '你的答案');
|
||
```
|
||
|
||
#### Playwright Agent 应用策略
|
||
根据 `docs/tests/playwright-agent-map.md` 的规划:
|
||
|
||
- **Phase 0(系统回归)**:已有脚本完全覆盖,保持现状,不需要 Agent
|
||
- **Phase 1(新功能 UI 测试)**:使用 Generator(`npx playwright codegen`)录制操作生成脚本,或使用 Planner(`npx playwright codegen --target test`)编排多步骤测试流程
|
||
- **Healer**:在 CI 场景下使用 `npx playwright test --trace on` 实现失败自动重试并记录 DOM 快照
|
||
|
||
#### 相关文档
|
||
- 完整测试框架说明见 `docs/tests/complete-test-framework.md`
|
||
- 测试报告见 `docs/tests/AuraK-测试报告.md` 与 `docs/tests/AuraK-最终测试报告.md`
|
||
- 测试计划见 `docs/tests/assessment-test-plan.md`
|
||
|
||
## 10. 开发规范与附录
|
||
|
||
### 10.1 代码风格
|
||
|
||
#### 语言与框架
|
||
项目采用 **TypeScript** 作为主要开发语言,覆盖后端(NestJS)与前端(React)全栈。后端基于 **NestJS** 框架构建,前端基于 **React 18** 与 **Vite** 构建工具。所有源码文件均使用 `.ts` / `.tsx` 扩展名,类型定义集中存放于 `server/src/types.ts` 与 `web/types.ts`。
|
||
|
||
#### 目录结构约定
|
||
- **后端模块化**:`server/src/` 下按业务域划分模块(如 `assessment/`、`auth/`、`knowledge-base/`),每个模块包含 `*.controller.ts`、`*.service.ts`、`*.module.ts`、`entities/`、`dto/` 等文件。
|
||
- **前端组件化**:`web/components/` 存放通用组件,`web/src/pages/` 存放页面级组件,`web/services/` 存放 API 调用封装。
|
||
- **测试文件**:单元测试与源码同目录,命名规范为 `*.spec.ts`;端到端测试存放于 `server/test/` 与 `tests/` 目录。
|
||
|
||
#### 命名规范
|
||
| 类别 | 规范 | 示例 |
|
||
|---|---|---|
|
||
| 类名 | PascalCase | `AssessmentService` |
|
||
| 方法名 | camelCase | `getAssessmentById` |
|
||
| 常量 | UPPER_SNAKE_CASE | `DEFAULT_TENANT_ID` |
|
||
| 枚举 | PascalCase,成员 UPPER_SNAKE_CASE | `UserRole.SUPER_ADMIN` |
|
||
| 文件/目录 | kebab-case | `question-bank.controller.ts` |
|
||
| DTO 类 | PascalCase + 后缀 | `CreateTemplateDto` |
|
||
| 实体类 | PascalCase + 后缀 | `AssessmentSessionEntity` |
|
||
|
||
#### 格式化与静态检查
|
||
后端使用 **ESLint** 进行代码规范检查,配置文件位于 `server/eslint.config.mjs`。前端使用 **TypeScript** 编译器进行类型检查,`web/tsconfig.json` 与 `server/tsconfig.json` 分别定义前后端的编译选项。后端构建配置见 `server/tsconfig.build.json`,启用增量编译(`tsbuildinfo` 文件存在)。
|
||
|
||
#### 依赖管理
|
||
项目使用 **Yarn** 作为包管理器,根目录、`server/`、`web/` 各有一份 `package.json`。根目录 `package.json` 仅包含少量开发依赖(如 `@playwright/test`),业务依赖分别管理于前后端子项目。`yarn.lock` 文件锁定依赖版本。
|
||
|
||
#### 数据库迁移
|
||
数据库结构变更通过 **TypeORM 迁移** 管理,迁移文件存放于 `server/src/migrations/`,命名格式为 `<时间戳>-<描述>.ts`(如 `1773220000000-CreateQuestionBankTables.ts`)。另有部分手动 SQL 迁移文件(`.sql` 后缀)存放于同目录。
|
||
|
||
#### 环境配置
|
||
后端通过 `.env` 文件加载环境变量(如 `JWT_SECRET`),示例文件为 `server/.env.sample`。前端通过 `vite.config.ts` 配置开发服务器端口(默认 `13001`)与代理规则。
|
||
|
||
#### 测试约定
|
||
- **单元测试**:使用 **Jest** 测试框架,测试文件与被测文件同目录,命名 `*.spec.ts`。
|
||
- **端到端测试**:使用 **Playwright**,配置文件为 `playwright.config.ts`,测试文件存放于 `tests/` 目录,命名 `*.e2e.spec.ts`。
|
||
- **脚本测试**:根目录存在多个 `.mjs` 脚本(如 `test-e2e-full.mjs`),用于执行特定场景的集成测试。
|
||
|
||
#### 文档与协作约定
|
||
仓库根目录包含 `AGENTS.md` 与 `CLAUDE.md`,为 AI 辅助开发工具提供项目架构、权限模型、测试模式与代码约定的完整参考。`README.md` 与 `README_ZH.md` 提供中英文双语的项目说明。
|
||
|
||
### 10.2 分支与提交规范
|
||
|
||
#### 分支策略
|
||
源码仓库中未提供独立的 CI 配置文件(如 `.github/workflows`、`.gitlab-ci.yml` 或 `Jenkinsfile`),因此分支策略主要依据项目文档中的约定进行描述。
|
||
|
||
根据 `docs/plans/2026-04-23-assessment-system-full-plan-v2.md` 中的规划,项目采用基于主干开发的简化分支模型:
|
||
|
||
| 分支类型 | 用途 | 合并目标 |
|
||
|---|---|---|
|
||
| `main`(或 `master`) | 稳定发布分支,始终保持可部署状态 | — |
|
||
| 功能分支 | 按功能模块(如 `assessment`、`feishu`、`knowledge-base`)创建独立分支进行开发 | 合并回主干 |
|
||
|
||
规划文档中明确要求:**每个功能模块的开发应在独立分支上进行,完成并通过测试后合并回主干**。该策略适用于评估系统、飞书集成、知识库增强等主要功能模块的开发。
|
||
|
||
#### 提交信息规范
|
||
项目文档中未定义严格的提交信息格式(如 Conventional Commits 规范),但 `docs/tests/AuraK-最终测试报告.md` 中体现了以下提交实践要求:
|
||
|
||
- **提交粒度**:按功能模块或修复单元进行提交,避免将无关改动混入同一提交。
|
||
- **提交关联**:提交信息中应关联对应的测试用例或测试报告,便于追溯功能验证状态。
|
||
- **版本标记**:`VERSION.md` 文件用于记录版本号,版本更新应与对应功能的提交同步进行。
|
||
|
||
#### 版本管理
|
||
`VERSION.md` 文件位于仓库根目录,用于维护当前版本号。版本号更新遵循以下约定(依据 `docs/plans/2026-04-23-assessment-system-full-plan-v2.md`):
|
||
|
||
- **主版本号**:重大架构调整或不兼容变更时递增。
|
||
- **次版本号**:新增功能模块时递增。
|
||
- **修订号**:缺陷修复或小范围优化时递增。
|
||
|
||
版本发布时需同步更新 `VERSION.md` 并在提交信息中注明版本号。
|
||
|
||
#### 代码评审与质量门禁
|
||
`code-review-knowledge-base.md` 文件定义了代码评审的知识库规范,要求所有合并到主干的代码必须通过:
|
||
|
||
1. **静态检查**:`server/` 目录下配置了 `eslint.config.mjs`,提交前需通过 ESLint 检查。
|
||
2. **单元测试**:后端使用 Jest(`server/package.json` 中配置),关键模块(如 `assessment.service.spec.ts`、`grader.node.spec.ts`)必须包含单元测试。
|
||
3. **端到端测试**:`tests/` 目录包含 Playwright 端到端测试用例(如 `assessment.e2e.spec.ts`、`full-assessment.e2e.spec.ts`),涉及核心流程的改动需通过 E2E 测试。
|
||
4. **评审记录**:代码评审结论应记录在 `code-review-knowledge-base.md` 中,作为后续评审的参考依据。
|
||
|
||
#### 测试与合并流程
|
||
依据 `docs/tests/AuraK-最终测试报告.md` 中描述的测试流程,功能分支合并到主干前需完成以下步骤:
|
||
|
||
```mermaid
|
||
graph LR
|
||
A[功能分支开发] --> B[本地单元测试]
|
||
B --> C[ESLint 静态检查]
|
||
C --> D[端到端测试]
|
||
D --> E{测试是否通过}
|
||
E -->|是| F[合并到主干]
|
||
E -->|否| G[修复缺陷并重新测试]
|
||
G --> B
|
||
```
|
||
|
||
#### 发布流程
|
||
发布流程遵循 `docs/plans/2026-04-23-assessment-system-full-plan-v2.md` 中的规划:
|
||
|
||
1. 主干代码冻结,进入发布候选阶段。
|
||
2. 执行完整回归测试(参考 `docs/tests/complete-test-framework.md` 中的测试框架)。
|
||
3. 更新 `VERSION.md` 版本号。
|
||
4. 生成发布提交,标记版本标签。
|
||
|
||
> 说明:以上分支与提交规范主要来源于项目规划文档和测试报告中的约定描述,源码中未提供自动化 CI 流水线配置。实际执行时可能因团队实践有所调整,具体以仓库实际配置为准。
|
||
|
||
### 10.3 环境变量清单
|
||
|
||
#### 环境变量总览
|
||
本系统通过环境变量进行运行时配置,涵盖服务端口、数据库连接、外部服务地址、认证密钥及 AI 模型参数等。所有环境变量均在 `server/.env` 文件中定义,部署前需根据实际环境进行配置。
|
||
|
||
#### 核心服务配置
|
||
| 变量名 | 必填 | 说明 | 示例值 |
|
||
|---|---|---|---|
|
||
| `PORT` | 可选 | 后端服务监听端口 | `3001` |
|
||
| `JWT_SECRET` | 必填 | JWT 签名密钥,用于用户认证令牌签发与验证 | `your-secret-key` |
|
||
| `JWT_EXPIRES_IN` | 可选 | JWT 令牌有效期 | `7d` |
|
||
| `CORS_ORIGIN` | 可选 | 允许跨域访问的前端地址 | `http://localhost:13001` |
|
||
|
||
#### 数据库配置
|
||
| 变量名 | 必填 | 说明 | 示例值 |
|
||
|---|---|---|---|
|
||
| `DB_TYPE` | 可选 | 数据库类型,当前支持 `sqlite` | `sqlite` |
|
||
| `DB_DATABASE` | 可选 | SQLite 数据库文件路径 | `database.sqlite` |
|
||
| `DB_HOST` | 可选 | 数据库主机地址(使用 MySQL/PostgreSQL 时) | `localhost` |
|
||
| `DB_PORT` | 可选 | 数据库端口(使用 MySQL/PostgreSQL 时) | `3306` |
|
||
| `DB_USERNAME` | 可选 | 数据库用户名(使用 MySQL/PostgreSQL 时) | `root` |
|
||
| `DB_PASSWORD` | 可选 | 数据库密码(使用 MySQL/PostgreSQL 时) | `password` |
|
||
|
||
#### 外部服务配置
|
||
| 变量名 | 必填 | 说明 | 示例值 |
|
||
|---|---|---|---|
|
||
| `ELASTICSEARCH_HOST` | 可选 | Elasticsearch 服务地址,用于全文检索与向量存储 | `http://localhost:9200` |
|
||
| `TIKA_SERVER_URL` | 可选 | Apache Tika 服务地址,用于文档内容解析 | `http://localhost:9998` |
|
||
| `LIBREOFFICE_SERVER_URL` | 可选 | LibreOffice 转换服务地址,用于文档格式转换 | `http://localhost:3002` |
|
||
| `OCR_SERVER_URL` | 可选 | OCR 识别服务地址 | `http://localhost:3003` |
|
||
|
||
#### AI 模型配置
|
||
| 变量名 | 必填 | 说明 | 示例值 |
|
||
|---|---|---|---|
|
||
| `OPENAI_API_KEY` | 可选 | OpenAI 兼容接口的 API 密钥 | `sk-xxxxxxxx` |
|
||
| `OPENAI_BASE_URL` | 可选 | OpenAI 兼容接口的基础地址 | `https://api.openai.com/v1` |
|
||
| `OPENAI_MODEL` | 可选 | 默认使用的对话模型名称 | `gpt-4o` |
|
||
| `GEMINI_API_KEY` | 可选 | Google Gemini API 密钥 | `AIzaxxxxxxxx` |
|
||
| `EMBEDDING_MODEL` | 可选 | 向量化模型名称 | `text-embedding-3-small` |
|
||
| `RERANK_MODEL` | 可选 | 重排序模型名称 | `rerank-multilingual-v2.0` |
|
||
| `VISION_MODEL` | 可选 | 视觉理解模型名称 | `gpt-4o-mini` |
|
||
|
||
#### 飞书机器人配置
|
||
| 变量名 | 必填 | 说明 | 示例值 |
|
||
|---|---|---|---|
|
||
| `FEISHU_APP_ID` | 可选 | 飞书应用的 App ID | `cli_xxxxxxxx` |
|
||
| `FEISHU_APP_SECRET` | 可选 | 飞书应用的 App Secret | `xxxxxxxx` |
|
||
| `FEISHU_WS_ENDPOINT` | 可选 | 飞书 WebSocket 长连接地址 | `wss://open.feishu.cn/connect` |
|
||
|
||
#### 其他配置
|
||
| 变量名 | 必填 | 说明 | 示例值 |
|
||
|---|---|---|---|
|
||
| `NODE_ENV` | 可选 | 运行环境标识 | `development` / `production` |
|
||
| `LOG_LEVEL` | 可选 | 日志输出级别 | `info` |
|
||
| `UPLOAD_DIR` | 可选 | 文件上传存储目录 | `./uploads` |
|
||
| `MAX_FILE_SIZE` | 可选 | 单文件上传大小上限(字节) | `10485760` |
|
||
|
||
#### 配置说明
|
||
- **必填变量**:`JWT_SECRET` 为必填项,未设置时服务将无法正常启动。其余变量均有默认值或可在运行时通过管理界面配置。
|
||
- **AI 模型配置**:系统支持同时配置 OpenAI 兼容接口与 Gemini 接口,实际调用时根据模型配置动态选择。模型相关参数也可通过管理后台的「模型配置」页面进行可视化维护。
|
||
- **外部服务依赖**:Elasticsearch、Tika、LibreOffice 等外部服务可通过 `docker-compose.yml` 一键启动,未配置时系统将降级使用内置的轻量实现(如 SQLite 全文检索替代 Elasticsearch)。
|
||
- **敏感信息管理**:所有包含密钥的变量(`JWT_SECRET`、`OPENAI_API_KEY`、`GEMINI_API_KEY`、`FEISHU_APP_SECRET`)在生产环境部署时务必通过安全的密钥管理服务注入,避免明文写入版本控制。
|
||
|
||
> 环境变量的完整加载逻辑与默认值定义位于 `server/src/defaults.ts` 文件中,如需查看各变量的默认取值可参考该文件。
|
||
|
||
### 10.4 变更记录
|
||
|
||
#### 版本概览
|
||
AuraK 当前版本信息记录于项目根目录的 `VERSION.md` 文件中。系统定位为企业级 AI 知识库与人才评估平台,核心能力涵盖多租户隔离、细粒度 RBAC 权限控制、AI 智能评估、知识库混合检索及飞书机器人集成。
|
||
|
||
#### 近期提交记录
|
||
由于源码中未包含结构化的变更记录文档,以下为项目近期 Git 提交的概要信息(基于源码目录状态推断,具体提交历史需在项目目录执行 `git log --oneline -20` 获取):
|
||
|
||
| 提交范围 | 主要内容 |
|
||
|---|---|
|
||
| 评估模块 | 新增评估会话、证书、题库相关数据表及迁移脚本 |
|
||
| 租户体系 | 添加默认租户初始化、租户模块及租户级数据隔离 |
|
||
| 知识库增强 | 知识库分块配置、记忆监控、文本分块服务 |
|
||
| 飞书集成 | 飞书机器人知识字段、评估会话表、WebSocket 管理 |
|
||
| 权限系统 | 角色权限实体、权限守卫、超级管理员/租户管理员守卫 |
|
||
| 模板扩展 | 评估模板扩展字段、证书表创建 |
|
||
| 数据库调整 | 移除笔记租户字段、清理设置表、恢复时间戳 |
|
||
|
||
#### 重要里程碑
|
||
##### 评估系统演进
|
||
评估模块经历了从基础评估流程到完整人才评估体系的演进:
|
||
|
||
- **基础评估**:支持单选题与简答题的自动生成,具备自适应追问与加权多维度评分能力
|
||
- **模板体系**:内置技术类(20 题,4 维度)与非技术类(10 题,3 维度)两套评估模板,维度与权重完全可配置
|
||
- **题库系统**:新增题库实体、题库模板及题库项实体,支持结构化题库管理
|
||
- **证书体系**:新增评估证书表,支持评估完成后自动生成证书
|
||
- **会话管理**:新增评估会话实体,支持评估过程的状态跟踪与历史记录
|
||
|
||
##### 多租户架构落地
|
||
- 新增租户实体、租户成员、租户设置及租户中间件
|
||
- 通过 `tenant-entity.subscriber.ts` 实现数据自动隔离
|
||
- 添加默认租户初始化迁移,确保系统开箱即用
|
||
- 移除笔记模块中的租户字段,优化租户数据模型
|
||
|
||
##### 知识库能力增强
|
||
- 引入双通道文档处理:Tika 快速通道与 Vision Pipeline 高精度通道
|
||
- 实现混合检索(BM25 + 向量检索),支持多格式文档
|
||
- 新增分块配置服务与文本分块器,支持自定义分块策略
|
||
- 集成 Elasticsearch 与重排序服务,提升检索精度
|
||
|
||
##### 飞书机器人集成
|
||
- 实现 WebSocket 长连接管理,支持实时消息推送
|
||
- 新增交互式消息卡片,支持移动端评估
|
||
- 添加评估命令解析器,支持通过飞书会话发起评估
|
||
|
||
##### 权限体系完善
|
||
- 建立三级角色体系:超级管理员、租户管理员、普通用户
|
||
- 实现 26 项细粒度权限常量,支持自定义角色
|
||
- 新增权限矩阵可视化配置界面,权限变更即时生效
|
||
|
||
#### 技术栈演进
|
||
| 层面 | 技术选型 |
|
||
|---|---|
|
||
| 后端框架 | NestJS(TypeScript) |
|
||
| 前端框架 | React 18 + Vite + TailwindCSS |
|
||
| 数据库 | SQLite(开发)/ 可迁移至其他 TypeORM 支持的数据库 |
|
||
| 搜索引擎 | Elasticsearch |
|
||
| AI 模型 | OpenAI 兼容接口 + Gemini,支持 LLM/Embedding/Rerank/Vision 多模型配置 |
|
||
| 文档处理 | Tika + LibreOffice + OCR(Tesseract) |
|
||
| 测试框架 | Jest(单元测试)+ Playwright(E2E 测试) |
|
||
|
||
#### 数据库迁移记录
|
||
源码中包含多个时间戳命名的迁移文件,记录了数据库结构的演进过程:
|
||
|
||
- `1737800000000`:知识库增强字段
|
||
- `1739260000000`:移除 SupportsVision 列
|
||
- `1772329237979`:添加默认租户
|
||
- `1772334811108`:添加租户模块
|
||
- `1772340000000`:知识分组添加父级 ID
|
||
- `1773198650000`:手动添加评估表
|
||
- `1773200000000`:飞书机器人知识字段
|
||
- `1773200000001`:创建飞书评估会话表
|
||
- `1773210000000`:从笔记移除租户字段
|
||
- `1773210000002`:模板扩展字段
|
||
- `1773210000003`:创建证书表
|
||
- `1773220000000`:创建题库表
|
||
|
||
> 完整的数据库表结构、字段定义及关系说明,请参阅「数据模型」章节。API 端点及调用方式详见「API 参考」章节。
|
||
|