docs: 统一 CLAUDE.md 和 README.md 文档体系

CLAUDE.md(AI 参考):
- 4 个 👉 AI 实现参考 标记,AI 可快速定位
- 完整的实体定义(TypeScript 代码块)
- 权限守卫流水线 + 解析链路
- 考核数据模型 + 出题算法伪代码
- API 认证流程 + 关键端点表
- 测试注意事项(React 受控输入/等待策略)
- 人可读用户指南(与 README 一致)

README.md(人可读):
- 顶部引用 CLAUDE.md — AI 阅读指引
- 功能亮点表格式呈现
- 步骤式操作指南(用户/权限/模板/考试/租户)
- 轻量内容,详细技术参考指向 CLAUDE.md

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Developer
2026-06-09 13:29:28 +08:00
parent 65ede9fcff
commit ebb8fbd298
2 changed files with 520 additions and 508 deletions
+389 -301
View File
@@ -1,309 +1,321 @@
# AuraK — AI 工作指南
# AuraK — 项目指南
> 本文件指导 AI 助手(Claude Code 等)如何理解和使用此仓库
> 项目:AuraK — 企业级多租户 AI 知识库与人才评价平台
> 本文件同时服务于 AI 助手(Claude Code / OpenCode / Codex / Gemini CLI)和人类开发者
> 阅读者可根据 `👉 AI 提示` 标记的章节快速定位 AI 需要的信息。
---
## 一、项目全景
## 一、项目速览
**AuraK** 是企业级多租户 AI 知识库与人才评价平台。
| 项目 | 说明 |
|---|---|
| 前端 | React 19 + TypeScript + Vite 6 → 端口 13001 |
| 后端 | NestJS 11 + TypeScript → 端口 3001 |
| 数据库 | SQLite`server/data/metadata.db`+ Elasticsearch 9 |
| 认证 | JWT + API Key 双机制 |
| AI 引擎 | LangChain + LangGraph |
| 部署 | Docker Compose + Nginx |
### 技术栈全景
```
Frontend: React 19 / TypeScript / Vite 6 / Tailwind CSS v4 / Framer Motion / Lucide icons
Backend: NestJS 11 / TypeORM / LangChain / LangGraph / Passport (JWT)
Database: better-sqlite3 (metadata) + Elasticsearch 9 (vector + full-text search)
AI APIs: OpenAI-compatible (DeepSeek, Claude) + Google Gemini native
Infra: Docker Compose (Elasticsearch, Apache Tika, LibreOffice)
```
### 快速命令
```shell
# 启动
cd /d/AuraK/server && node dist/main.js & # 后端
cd /d/AuraK/web && npx vite --port 13001 & # 前端
# 编译
cd /d/AuraK/server && npx nest build # 后端编译
cd /d/AuraK/web && npx vite build # 前端编译
# 测试
cd /d/AuraK && node test-systematic.mjs # 142 项全面测试
# 杀进程(Windows
taskkill //F //IM node.exe 2>/dev/null
```
---
## 二、项目结构
```
AuraK/
├── web/ # React 19 + Vite 前端 (端口 13001)
│ ├── components/ # UI 组件(含 views/ 目录下的主要页面)
│ ├── contexts/ # AuthContext / LanguageContext / ConfirmContext
├── services/ # API 客户端(apiClient.ts + 各服务)
├── hooks/ # usePermissions 等自定义 Hook
└── src/pages/ # 路由页面(薄壳,委托给 components/views
├── server/ # NestJS 后端 (端口 3001)
│ ├── src/auth/ # 认证(JWT/API Key+ 权限(RBAC
│ │ └── permission/ # Permission/Role 实体 + Service + Guard
│ ├── src/assessment/ # 考核评估子系统(最复杂)
│ ├── src/tenant/ # 多租户 + 租户成员管理
└── src/user/ # 用户 CRUD
├── docs/plans/ # 设计文档和计划
├── test-*.mjs # Playwright 测试脚本(项目根目录)
── docker-compose.yml # 基础设施(Elasticsearch, Tika, LibreOffice
```
### 核心技术栈
| 层 | 技术 |
|---|---|
| 前端 | React 19, TypeScript, Vite 6, Tailwind CSS v4, Framer Motion, Lucide icons |
| 后端 | NestJS 11, TypeORM, SQLite (better-sqlite3), LangChain/LangGraph |
| 搜索 | Elasticsearch 9(向量+全文混合检索)|
| 认证 | JWT + API Key 双机制 |
| 部署 | Docker ComposeNginx 反向代理)|
---
## 二、系统架构
### 2.1 前端路由
| 路径 | 组件 | 说明 |
|---|---|---|
| `/login` | LoginPage | 公开 |
| `/` | OverviewPage | 工作台首页 |
| `/chat` | ChatPage | AI 对话 |
| `/assessment` | AssessmentPage | 考核评估 |
| `/assessment-stats` | AssessmentStatsView | 评估统计 |
| `/question-banks` | QuestionBankView | 题库管理 |
| `/settings` | SettingsPage | 系统设置 |
### 2.2 后端模块
app.module.ts 注册了 27 个模块,核心模块:
- **AuthModule** — 认证(JWT/API Key 双策略)
- **PermissionModule** — RBAC 权限(Role/RolePermission 实体 + PermissionService + PermissionsGuard
- **UserModule** — 用户 CRUD
- **TenantModule** — 多租户(全局模块)
- **AssessmentModule** — 考核评估(最复杂,含会话/出题/评分/证书)
- **AdminModule / SuperAdminModule** — 管理端 API
- **KnowledgeBaseModule** — 知识库索引和检索
- **ModelConfigModule** — AI 模型配置
### 2.3 认证流程
```
密码登录:
POST /api/auth/login (username, password)
→ LocalAuthGuard → JwtService.sign(payload) → { access_token, user }
获取 API Key:
GET /api/users/api-key (Authorization: Bearer <JWT>)
→ 返回 kb_xxxxxxxx...(存前端 localStorage
后续所有请求:
Headers: { x-api-key: <apiKey>, x-tenant-id: <tenantId> }
全局守卫: CombinedAuthGuardAPP_GUARD 注册)
→ 先尝试 API Key 认证,失败则回退 JWT
→ @Public() 装饰器跳过认证
├── web/ # React 前端
│ ├── components/
│ ├── views/ # 主要页面视图
│ │ ├── SettingsView.tsx # 系统设置
├── PermissionSettingsView.tsx # RBAC 权限矩阵
│ │ ├── AssessmentView.tsx # 考核流程
│ │ │ └── AssessmentTemplateManager.tsx # 考核模板编辑
│ ├── LoginPage.tsx # 登录页
│ │ └── PermissionGate.tsx # 组件级权限门控
│ ├── src/
│ ├── contexts/AuthContext.tsx # 认证/租户上下文
│ ├── hooks/usePermissions.ts # 权限 Hook
│ │ └── services/ # API 客户端
│ └── index.tsx # 路由入口
── server/ # NestJS 后端
│ ├── src/
│ │ ├── auth/ # 认证 + 权限
│ │ │ ├── permission/ # RBAC 模块(详见第 4 章)
│ │ │ ├── roles.guard.ts # @Roles() 守卫
│ │ │ └── combined-auth.guard.ts # 全局认证守卫
│ │ ├── assessment/ # 考核评估(详见第 5 章)
│ │ ├── user/ # 用户 CRUD
│ │ ├── tenant/ # 多租户管理
│ │ └── app.module.ts # 根模块(27 个子模块)
├── docker-compose.yml
├── test-*.mjs # Playwright 测试脚本(8 个)
├── CLAUDE.md / README.md / README_ZH.md # 本文件
└── STARTUP.md / AGENTS.md / VERSION.md
```
---
## 三、权限系统(RBAC)核心
## 三、系统功能
### 3.1 三层角色
### 3.1 多租户与用户系统
| 角色 | 权限数 | 能做什么 |
| 角色 | 权限数 | 核心能力 |
|---|---|---|
| **SUPER_ADMIN** | 26 项 | 全部权限:用户/租户/知识库/考核/模型/插件/设置 |
| **TENANT_ADMIN** | 21 项 | 管理本租户用户和资源;不能跨租户/删用户/改系统设置 |
| **USER** | 5 项 | kb:view/create/edit, assess:view, plugin:view |
| **SUPER_ADMIN** | 26 项 | 全部权限:用户/租户/知识库/考核/模型/设置 |
| **TENANT_ADMIN** | 21 项 | 本租户管理:用户/知识库/考核/模型;不能跨租户删用户改系统设置 |
| **USER** | 5 项 | 使用知识库、参与考核、查看插件 |
### 3.2 权限常量定义
### 3.2 考核评估系统
- **AI 出题**:从知识库提取素材生成题目,支持选择题/简答/判断题,3:7 比例
- **题库系统**:预置题目 + AI 实时生成双来源,审核发布流程
- **多轮对话**:AI 对简答可发起追问,模拟真实面试
- **模板引擎**:可配置维度/权重/题数/及格分/时限
- **证书系统**:自动生成等级证书(Novice/Proficient/Advanced/Expert
### 3.3 知识库与 AI 对话
- 双处理模式(Tika 快速 / Vision Pipeline 高精度)
- 混合检索(BM25 + 向量 + Rerank
- SSE 流式响应
---
## 四、权限系统(RBAC)— 👉 AI 实现参考
### 4.1 权限定义
位于 `server/src/auth/permission/permission.constants.ts`
```typescript
// 用户管理: 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
```
### 3.3 权限守卫流水线
```
CombinedAuthGuard (认证) → 已有,全局注册
→ RolesGuard (角色门控) → @Roles(SUPER_ADMIN, TENANT_ADMIN)
→ PermissionsGuard (权限门控) → @Permission('user:view')
```
**系统角色保护**: 系统角色(isSystem=true)的权限不可通过 API 修改。
### 3.4 权限解析链路
```
PermissionService.getUserPermissions(userId, tenantId)
→ 1. 如果 user.isAdmin === true,返回全部 SUPER_ADMIN 权限
→ 2. 查找 TenantMember(userId, tenantId)
→ 3. TenantMember.role → Role.baseRole → RolePermission.permissionKey
```
---
## 四、考核评估系统
### 4.1 数据模型
```
AssessmentTemplate (模板)
└── question_count, dimensions[{name, label, weight}], passingScore
└── QuestionBank (题库,一对一关联模板)
└── QuestionBankItem (题目)
├── questionType: SHORT_ANSWER / MULTIPLE_CHOICE / TRUE_FALSE
└── dimension: PROMPT / LLM / IDE / DEV_PATTERN / WORK_CAPABILITY
AssessmentSession (会话)
├── questions_json (缓存的题目列表)
├── messages (对话历史)
├── scores / dimensionScores
└── finalReport (AI 生成的报告)
AssessmentCertificate (证书)
└── level: Novice / Proficient / Advanced / Expert
```
### 4.2 出题算法
`selectQuestions()``question-bank.service.ts`:
```typescript
// 按维度权重公平分配(floor + remainder,保证总和 = count
// 20题模板: PROMPT(30%)→6题, LLM(30%)→6题, IDE(20%)→4题, DEV_PATTERN(20%)→4题
```
### 4.3 模板配置(数据库 `assessment_templates` 表)
```typescript
// dimensions 字段是 JSON 数组,前端「测评模板」页面可编辑
dimensions = [
{ name: "PROMPT", label: "Prompt Engineering", weight: 30 },
{ name: "LLM", label: "LLM Knowledge", weight: 30 },
{ name: "IDE", label: "IDE Proficiency", weight: 20 },
{ name: "DEV_PATTERN", label: "Dev Patterns", weight: 20 },
]
```
---
## 五、测试脚本
所有 Playwright 测试位于项目根目录:
| 脚本 | 用途 | 运行命令 |
| 分类 | 权限 | 说明 |
|---|---|---|
| `test-systematic.mjs` | **142 项系统性测试**(身份/CRUD/权限/边界/UI | `node test-systematic.mjs` |
| `test-e2e-full.mjs` | 94 项全角色 E2E 测试 | `node test-e2e-full.mjs` |
| `test-user-lifecycle.mjs` | 42 项用户生命周期测试 | `node test-user-lifecycle.mjs` |
| `test-multiround.mjs` | 考核多轮对话测试 | `node test-multiround.mjs` |
| `test-permission-flow.mjs` | 三层角色权限验证 | `node test-permission-flow.mjs` |
| `test-question-distribution.mjs` | 出题分布验证 | `node test-question-distribution.mjs` |
| `exam-organizer.mjs` | 考试组织者场景(创建考生+考核+查看结果) | `node exam-organizer.mjs` |
| 用户管理 | `user:view / :create / :edit / :delete / :role / :password` | 用户 CRUD + 角色变更 + 密码重置 |
| 租户管理 | `tenant:view / :create / :edit / :delete / :members` | 租户 CRUD + 成员管理 |
| 知识库 | `kb:view / :create / :edit / :delete / :publish` | 知识库全生命周期 |
| 考核 | `assess:view / :manage / :template / :bank` | 考核查看/管理/模板/题库 |
| 模型 | `model:view / :config` | 模型配置查看/修改 |
| 插件 | `plugin:view / :manage` | 插件查看/启停 |
| 设置 | `settings:view / :system` | 系统设置查看/修改 |
---
## 六、开发指南
### 6.1 启动项目
```bash
# 后端
cd server && node dist/main.js # 生产模式(需要先 nest build)
cd server && yarn start:dev # 开发模式(热加载)
# 前端
cd web && npx vite --port 13001 # 开发模式
cd web && npx vite build # 编译
# 基础设施(需要 Docker
docker-compose up -d elasticsearch tika libreoffice
```
### 6.2 运行测试
```bash
cd /d/AuraK && node test-systematic.mjs # 142 项全面测试
```
### 6.3 重启服务
```bash
taskkill //F //IM node.exe 2>/dev/null # 杀所有 Node 进程
cd /d/AuraK/server && node dist/main.js & # 启动后端
cd /d/AuraK/web && npx vite --port 13001 & # 启动前端
```
### 6.4 数据库管理
```bash
# SQLite 文件路径
server/data/metadata.db
# 直接查询
cd /d/AuraK && node -e "
const sqlite3 = require('better-sqlite3');
const db = new sqlite3('server/data/metadata.db');
db.prepare('SELECT * FROM users').all();
db.close();
"
```
### 6.5 常见问题
- **端口占用**: `netstat -ano | grep 3001``taskkill //F //PID <pid>`
- **后端启动失败**: 确保从 `server/` 目录启动以加载 .env
- **Windows 杀进程**: 用 `taskkill //F //PID``kill` 不可靠
- **Dist 目录修改**: `server/dist/` 下的 .js 直接修改即可生效(无需 nest build)
---
## 七、代码规范
### 7.1 TypeScript 模式
- **实体定义**: TypeORM `@Entity` + `@Column` + 枚举类型
- **控制器**: `@Controller` + `@UseGuards(CombinedAuthGuard)` + `@Permission()`
- **服务**: `@Injectable` 类,方法名用动词开头
- **前端组件**: React FC + TypeScript interface props
### 7.2 权限装饰器使用
### 4.2 实体模型
```typescript
// 后端 API — 在控制器方法上标注所需权限
// Role 实体
@Entity('roles')
class Role {
id: string; name: string; description?: string;
isSystem: boolean; // 系统角色不可删改
baseRole: UserRole | null; // 映射到 UserRole 枚举
tenantId: string | null; // null=全局, 非null=租户自定义
}
// RolePermission 关联
@Entity('role_permissions')
class RolePermission {
roleId: string Role.id;
permissionKey: string; // 如 'user:view'
}
// TenantMember 实体(已有)
@Entity('tenant_members')
class TenantMember {
userId: string User.id;
tenantId: string Tenant.id;
role: UserRole; // SUPER_ADMIN / TENANT_ADMIN / USER
}
```
### 4.3 守卫流水线
```
CombinedAuthGuard (全局 APP_GUARD) → API Key 或 JWT 认证
→ RolesGuard (@Roles(SUPER_ADMIN)) → 角色级门控
→ PermissionsGuard (@Permission('user:view')) → 权限级门控
```
### 4.4 权限解析链路
```
PermissionService.getUserPermissions(userId, tenantId):
1. 查 user.isAdmin → true 则返回全部权限
2. 查 TenantMember(userId, tenantId) → 获取 role
3. 查 Role(baseRole=role, isSystem=true) → 获取 roleId
4. 查 RolePermission(roleId) → 返回权限 Set
```
### 4.5 权限装饰器用法
```typescript
// 后端——标记路由需要的权限(OR 关系)
@Post()
@UseGuards(PermissionsGuard)
@Permission('user:create')
async createUser(@Request() req, @Body() body: CreateUserDto) { ... }
async createUser(...) { ... }
// 前端 — 用 PermissionGate 组件或 usePermissions hook
// 前端——组件级门控
<PermissionGate permission="user:create">
<Button></Button>
</PermissionGate>
// 前端——条件渲染
const { hasPermission } = usePermissions();
{hasPermission('user:view') && <UserList />}
{hasPermission('user:delete') && <DeleteButton />}
```
### 7.3 通用 React 约定
### 4.6 系统角色保护
- 使用 `cn()` 工具函数(tailwind-merge)合并 className
- 图标用 `lucide-react`
- 动画用 `framer-motion`
- API 调用用 `apiClient` 或原生 `fetch`
- 模态框用 `createPortal` + `AnimatePresence`
`setRolePermissions()` 加了 `if (role.isSystem) throw Error`
系统角色的名、权限、存在性均不可通过 API 修改。
---
## 八、Playwright 测试指南
## 五、考核评估系统 — 👉 AI 实现参考
### 8.1 测试模式
### 5.1 数据模型
```javascript
import { chromium } from 'playwright';
const browser = await chromium.launch({ headless: true });
const page = await browser.newPage({ viewport: { width: 1440, height: 900 } });
```typescript
AssessmentTemplate: id, name, question_count, dimensions[{name,label,weight}],
passingScore(60=6.0/10); perQuestionTimeLimit(300s); totalTimeLimit(1800s)
QuestionBank: id, templateId(unique), items[]
QuestionBankItem: id, type(SHORT_ANSWER|MULTIPLE_CHOICE|TRUE_FALSE),
dimension(PROMPT|LLM|IDE|DEV_PATTERN|WORK_CAPABILITY),
difficulty(STANDARD|ADVANCED|SPECIALIST), status(PUBLISHED|...)
// 模拟 API 调用
const r = await fetch(`${API}/api/auth/login`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ username, password }),
});
AssessmentSession: id, userId, status(IN_PROGRESS|COMPLETED),
questions_json[], messages[], scores, finalScore, finalReport, passed
AssessmentQuestion: content, keyPoints
AssessmentAnswer: userAnswer, score, feedback, isFollowUp
AssessmentCertificate: id, userId, sessionId, level(Novice|Proficient|Advanced|Expert),
totalScore, dimensionScores, passed
```
### 8.2 React 受控输入框操作(关键)⚠️
### 5.2 出题算法 (`selectQuestions`)
React 的受控 input/textarea 依赖 native setter 触发 `onChange`。**不要用 `type()``fill()`**,应使用:
```typescript
selectQuestions(bankId, count, dimensionWeights):
// 1. floor + remainder 分配(保证 sum = count
// 各维度 target = floor(count × weight / totalWeight)
// remainder = count - sum(targets),按权重降序分配
// 2. 各维度池 shuffle 后抽 target 道
// 3. 不足时从剩余池随机补足
// 4. 最终 shuffleArray 返回
// 20题模板示例:
// PROMPT(30%)→6, LLM(30%)→6, IDE(20%)→4, DEV_PATTERN(20%)→4
```
### 5.3 考核流程
```
startSession():
1. 判断是否有关联题库(QuestionBank),且已发布题数 >= targetCount
2. 是 → 从题库抽题(selectQuestions
3. 否 → AI 实时生成(LangGraph 工作流)
4. 创建 AssessmentSession,缓存 questions_json
submitAnswer():
1. 检查时间限制
2. 将答案送入 LangGraph → AI 评分
3. 如需追问 → 设置追问状态 → 等待用户再次提交
4. 所有题答完 → 生成 finalReport → 计算分数
5. finalScore = 带权平均(按风格维度)
passingScore ≥ X/10 → passed = true
```
---
## 六、认证与 API — 👉 AI 实现参考
### 6.1 认证流程
```
密码登录:
POST /api/auth/login (username, password)
→ LocalAuthGuard → JwtService.sign({ username, sub, role, tenantId })
→ 返回 { access_token, user }
获取 API Key:
GET /api/users/api-key (Authorization: Bearer <JWT>)
→ 返回 kb_xxxxxxxx...(前端存 localStorage
后续请求:
Headers: { x-api-key: <apiKey>, x-tenant-id: <tenantId> }
```
### 6.2 全局守卫
`CombinedAuthGuard` 注册为 `APP_GUARD`
- 优先 API Key 认证(`x-api-key` header 或 `Authorization: Bearer kb_*`
- 回退 JWT 认证
- `@Public()` 装饰器跳过认证
- 设置 `request.user = { id, username, role, tenantId }`
### 6.3 关键 API 端点
| 方法 | 路径 | 鉴权 | 说明 |
|---|---|---|---|
| POST | `/api/auth/login` | 公开 | 密码登录 |
| GET | `/api/users` | `user:view` | 用户列表 |
| POST | `/api/users` | `user:create` | 创建用户 |
| PUT | `/api/users/:id` | `user:edit` | 编辑用户 |
| DELETE | `/api/users/:id` | `user:delete` | 删除用户 |
| GET | `/api/permissions/mine` | 认证 | 当前用户权限 |
| GET | `/api/roles` | `TENANT_ADMIN+` | 角色列表 |
| POST | `/api/roles` | `TENANT_ADMIN+` | 创建角色 |
| PUT | `/api/roles/:id/permissions` | `TENANT_ADMIN+` | 设角色权限 |
| GET | `/api/assessment/templates` | 认证 | 考核模板列表 |
| POST | `/api/assessment/start` | 认证 | 开始考核 |
| POST | `/api/assessment/:id/answer` | 认证 | 提交答案 |
---
## 七、测试脚本
所有 Playwright 测试在项目根目录,以 `test-*.mjs` 命名:
| 测试 | 覆盖 | 运行 |
|---|---|---|
| `test-systematic.mjs` | 142 项:认证/CRUD/RBAC/边界/UI | `node test-systematic.mjs` |
| `test-e2e-full.mjs` | 94 项:全角色 E2E | `node test-e2e-full.mjs` |
| `test-user-lifecycle.mjs` | 42 项:用户生命周期 + 异常 | `node test-user-lifecycle.mjs` |
| `test-permission-flow.mjs` | 3 角色权限边界 | `node test-permission-flow.mjs` |
| `test-multiround.mjs` | 考核多轮对话 | `node test-multiround.mjs` |
| `test-question-distribution.mjs` | 出题算法验证 | `node test-question-distribution.mjs` |
| `exam-organizer.mjs` | 考试组织全流程 | `node exam-organizer.mjs` |
### 👉 AI 编写测试注意事项
**React 受控输入框** — 不要用 `type()``fill()`,用 native setter
```javascript
await page.evaluate((text) => {
@@ -312,11 +324,10 @@ await page.evaluate((text) => {
const setter = Object.getOwnPropertyDescriptor(HTMLTextAreaElement.prototype, 'value')?.set;
setter?.call(ta, text);
ta.dispatchEvent(new Event('input', { bubbles: true }));
}, '输入文字');
}, '输入文字');
```
### 8.3 等待按钮可用
**等待 button 可用**
```javascript
await page.waitForFunction(() => {
const btn = document.querySelector('button:has(svg.lucide-send)');
@@ -324,20 +335,16 @@ await page.waitForFunction(() => {
}, { timeout: 10000 });
```
### 8.4 等待 spinner 消失
**等待 spinner 消失**
```javascript
await page.waitForFunction(() => !document.querySelector('.animate-spin'), { timeout: 60000 });
```
### 8.5 检测考核题型
**检测考核题型**
```javascript
const state = await page.evaluate(() => {
// 选择题选项按钮
const optionBtns = Array.from(document.querySelectorAll('button.w-full.text-left.px-5.py-4'))
.filter(b => !b.textContent?.includes('确认答案'));
// 简答题 textarea
const ta = document.querySelector('textarea');
return { choiceCount: optionBtns.length, hasTextarea: ta?.offsetParent !== null };
});
@@ -345,54 +352,135 @@ const state = await page.evaluate(() => {
---
## 九、部署配置
## 八、用户指南(人可读)
### 端口
### 8.1 用户管理
```
系统设置 → 用户管理
```
- 创建用户:用户名 + 密码 + 显示名
- 编辑用户:修改基本信息、分配角色(USER / TENANT_ADMIN / SUPER_ADMIN
- 删除用户:不可删自己、不可删内置 admin 账号
- 角色变更即时生效(不需要重新登录)
### 8.2 权限管理
```
系统设置 → 权限管理
```
- 左侧角色列表:SUPER_ADMIN / TENANT_ADMIN / USER + 自定义角色
- 点击角色 → 右侧显示该角色的权限矩阵 → 勾选/取消权限 → 保存
- 系统角色(SUPER_ADMIN 等)不可修改、不可删除
- 自定义角色:创建 → 设权限 → 在用户管理中分配给用户
### 8.3 考核模板配置
```
系统设置 → 测评模板
```
- **技术人员模板**(默认):
- PROMPT 30%、LLM 30%、IDE 20%、DEV_PATTERN 20%
- 20 题、10 分钟限时
- **非技术人员模板**
- PROMPT 50%、LLM 30%、WORK_CAPABILITY 20%
- 10 题,不含 IDE 和开发范式考核
- 维度名称用英文大写(PROMPT/LLM/IDE/DEV_PATTERN/WORK_CAPABILITY
- 权重是整数,总和不必为 100(系统会自动归一化)
### 8.4 组织考试
**管理员操作:**
1. 系统设置 → 用户管理 → 创建考生账号
2. 告知考生用户名密码
**考生操作:**
1. 登录系统 → 进入考核评估
2. 选择考核模板 → 开始专业评估
3. 答题(选择题点击选项→确认答案;简答题输入文字→发送)
4. AI 可能追问——继续作答
5. 完成后查看成绩
**查看结果:**
- 考核页面右侧「历史记录」栏显示所有历史成绩
- 点击记录查看每题得分、AI 评语
- 「查看证书」显示等级、总分、各维度得分
- 「下载 PDF 报告」「导出 Excel」
### 8.5 租户管理(仅 SUPER_ADMIN
```
系统设置 → 租户管理
```
- 创建租户 → 添加成员 → 分配角色
- 支持父子层级(父租户管理员可访问子租户)
- 数据严格隔离
---
## 九、配置参考
### 端口表
| 服务 | 端口 |
|---|---|
| 前端(开发) | 13001 |
| 前端(生产/Nginx | 80/443 |
| 后端 API | 3001 |
| Elasticsearch | 9200 |
| Apache Tika | 9998 |
| LibreOffice | 8100 |
| 前端(生产/Nginx | 80/443 |
### 环境变量
`server/.env` 关键配置:
### 环境变量`server/.env`
```
PORT=3001
DATABASE_PATH=./data/metadata.db
PORT=3001 # 后端端口
DATABASE_PATH=./data/metadata.db # SQLite 路径
ELASTICSEARCH_HOST=http://127.0.0.1:9200
JWT_SECRET=your-secret
JWT_SECRET=<必填> # JWT 签名密钥
UPLOAD_FILE_PATH=./uploads # 文件存储
MAX_FILE_SIZE=104857600 # 上传限制
```
---
## 十、快速参考命令
## 十、数据库操作
```bash
# 启动
cd /d/AuraK/server && node dist/main.js &
cd /d/AuraK/web && npx vite --port 13001 &
# 后端编译
cd /d/AuraK/server && npx nest build
# 运行测试
cd /d/AuraK && node test-systematic.mjs
# 数据库查询
# 直接查询 SQLite
cd /d/AuraK && node -e "
const s=require('better-sqlite3');
const d=new s('server/data/metadata.db');
const r=d.prepare('...').all(); console.log(r); d.close();"
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();
"
# 清理端口
taskkill //F //IM node.exe 2>/dev/null
# 前端编译
cd /d/AuraK/web && npx vite build
# TypeORM 自动建表(synchronize: true
# 重置数据库:删除 metadata.db 文件后重启即可
```
---
## 附录:架构图
```
┌────────────────────────────────────────────────────────────────┐
│ 前端 (Vite :13001) │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌───────────────────┐ │
│ │ AuthCtx │ │ Pages │ │ Views │ │ Services │ │
│ │ 登录/租户 │ │ 路由页 │ │ 设置/考核 │ │ API 客户端 │ │
│ └──────────┘ └──────────┘ └──────────┘ └───────────────────┘ │
└──────────────────────────┬─────────────────────────────────────┘
│ HTTP / SSE
┌──────────────────────────▼─────────────────────────────────────┐
│ 后端 (NestJS :3001) │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌───────────────────┐ │
│ │ Auth │ │ RBAC │ │ Assessment│ │ Knowledge Base │ │
│ │ JWT/Key │ │ 26 Perms │ │ Templates │ │ Tika/Vision/ES │ │
│ └──────────┘ └──────────┘ └──────────┘ └───────────────────┘ │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌───────────────────┐ │
│ │ Tenant │ │ User │ │ Admin │ │ Super Admin │ │
│ │ 租户隔离 │ │ CRUD │ │ 管理端 │ │ 全局管理 │ │
│ └──────────┘ └──────────┘ └──────────┘ └───────────────────┘ │
└────────────────────────────────────────────────────────────────┘
+131 -207
View File
@@ -1,90 +1,39 @@
# AuraK — Enterprise AI Knowledge Base & Talent Assessment Platform
# AuraK
AuraK is a multi-tenant intelligent platform built with **React 19 + NestJS**, combining RAG-powered knowledge management, interactive AI assessment, and enterprise-grade RBAC permission system.
Enterprise AI Knowledge Base & Talent Assessment Platform.
> **For AI assistants (Claude Code / OpenCode / Codex / Gemini CLI):** See [CLAUDE.md](CLAUDE.md) for the complete technical reference — all architecture details, permission entities, guard flow, assessment data model, test patterns, and code conventions are documented there.
---
## ✨ Features
### 🔐 Enterprise Multi-Tenant & RBAC
- **Tenant Isolation** — Strict data isolation between tenants with independent member management
- **RBAC Permissions** — 3-tier roles (SUPER_ADMIN / TENANT_ADMIN / USER) with 26 granular permissions across 7 categories
- **Custom Roles** — Create and assign custom roles with specific permission sets
- **Permission Matrix UI** — Visual permission matrix editor in Settings panel
- **Role Auto-Seed** — Default roles with permission sets created on startup
### 📊 Interactive AI Assessment
- **AI-Powered Exams** — Automated question generation, grading, and follow-up questioning via LangGraph workflow
- **Dual Question Sources** — Pre-built question banks + AI generation on-the-fly
- **Multi-Dimension Scoring** — Weighted scoring across customizable dimensions (Prompt, LLM, IDE, Dev Patterns, Work Capability)
- **Certificate System** — Auto-generated certificates with score breakdown by dimension
- **Adaptable Templates** — Configure question count, dimensions, time limits, passing scores per template
- **Non-Technical Mode** — Separate templates for non-technical staff (exclude IDE/Dev Patterns)
**Exam Flow:** Admin creates accounts → Candidates login → Take assessment → AI grades + issues certificate → View history
### 📚 Intelligent Knowledge Base
- **Dual Processing Modes** — Fast mode (Tika text extraction) + High-precision mode (Vision Pipeline for image/PDF)
- **Hybrid Search** — BM25 keyword + vector embedding with Elasticsearch
- **Multi-Format Support** — PDF, Word, PPT, Excel, images
- **Hierarchical Groups** — Folder-style knowledge group management
### 🤖 Multi-Model AI Engine
- OpenAI-compatible APIs (OpenAI, DeepSeek, Claude, etc.)
- Google Gemini native SDK
- Configurable LLM / Embedding / Rerank / Vision models
### 🌐 Additional Features
- Streaming SSE responses
- Multi-language (Chinese, English, Japanese)
- Feishu (Lark) bot integration
- Podcast generation from documents
- Notebook/shared notes system
- User quota management
---
## 🏗️ Tech Stack
### Frontend
- **Framework:** React 19 + TypeScript + Vite 6
- **Styling:** Tailwind CSS v4 + custom design system
- **Icons:** Lucide React
- **State:** React Context
- **UI Components:** Framer Motion, react-router-dom v7
### Backend
- **Framework:** NestJS 11 + TypeScript
- **AI Engine:** LangChain + LangGraph (assessment workflow)
- **Database:** SQLite (better-sqlite3, metadata) + Elasticsearch 9 (vector + full-text)
- **Auth:** JWT + API Key dual mechanism
- **Document Processing:** Apache Tika + Vision Pipeline + LibreOffice
### Infrastructure
- Docker Compose (Elasticsearch, Tika, LibreOffice)
- Nginx reverse proxy (production)
| Area | Highlights |
|---|---|
| **Multi-Tenant** | Strict data isolation, hierarchical org tree, per-tenant settings |
| **RBAC** | 3 tiers (SUPER_ADMIN / TENANT_ADMIN / USER), 26 granular permissions, custom roles, visual permission matrix |
| **AI Assessment** | Auto question generation (MC + short answer), adaptive follow-up dialogue, weighted multi-dimension scoring, certificate system |
| **Knowledge Base** | Dual processing (Fast via Tika / High-Precision via Vision Pipeline), hybrid search (BM25 + vector), multi-format support |
| **AI Engine** | Multi-model (OpenAI-compatible + Gemini), configurable LLM/Embedding/Rerank/Vision, SSE streaming |
| **Feishu Bot** | WebSocket integration, interactive message cards, mobile assessment |
---
## 🚀 Quick Start
### Prerequisites
- Node.js 18+, Yarn
- Docker & Docker Compose
- Node.js 18+, Yarn, Docker & Docker Compose
### 1. Install & Start
```bash
# Clone and install
git clone <repo-url>
cd AuraK
yarn install
# Configuration
cp server/.env.sample server/.env
# Edit server/.env — set JWT_SECRET, API keys
# Edit server/.env — set JWT_SECRET
# Start infrastructure (optional — AI features need Elasticsearch)
# Start infrastructure (optional for basic features)
docker-compose up -d elasticsearch tika libreoffice
# Start development servers
@@ -93,197 +42,172 @@ yarn dev
# Backend: http://localhost:3001
```
### 2. Default Login
### 2. Quick Start (no Docker)
```bash
cd /d/AuraK/server && node dist/main.js &
cd /d/AuraK/web && npx vite --port 13001 &
```
### 3. Default Login
```
Username: admin
Password: admin123
```
### 3. Quick Start (without Docker)
```bash
# Start backend (production mode)
cd server && node dist/main.js &
# Start frontend
cd web && npx vite --port 13001 &
```
---
## 📖 User Guide
### System Setup & User Management
### User Management
```
路径: 系统设置 → 用户管理
Settings → User Management
```
1. **Create Users** — Add users with username, password, display name
2. **Assign Roles** — Click edit on any user → select USER / TENANT_ADMIN / SUPER_ADMIN
3. **Role Preview** — Each role shows its permission count
4. **Bulk Import/Export** — XLSX import and export
| Action | Steps |
|---|---|
| Create user | Fill username, password, display name → Create |
| Edit user | Click Edit icon → Modify info → Select role (USER / TENANT_ADMIN / SUPER_ADMIN) → Save |
| Change password | Click key icon → Enter new password → Confirm |
| Delete user | Click trash icon → Confirm |
| Export/Import | Click Export/Import buttons → XLSX format |
> Role changes take effect immediately — the user does not need to log out and back in.
### Permission Management
```
路径: 系统设置 → 权限管理
Settings → Permission Management
```
1. **Role List** — Left panel shows all roles (SUPER_ADMIN, TENANT_ADMIN, USER + custom)
2. **Permission Matrix** — Click a role → toggle individual permissions
3. **Custom Roles** — Create role → set permissions → assign to users
4. **System Role Protection** — Built-in roles cannot be modified
### Assessment Setup
1. **Left panel** — lists all roles: SUPER_ADMIN, TENANT_ADMIN, USER, and any custom roles
2. **Click a role** — right panel shows the permission matrix organized by category
3. **Toggle permissions** — check/uncheck individual items
4. **Save** — changes take effect immediately
5. **Custom roles** — click "+" to create, set permissions, then assign to users via User Management
> System roles (SUPER_ADMIN, TENANT_ADMIN, USER) are protected — their permissions cannot be modified.
### Assessment Templates
```
路径: 系统设置 → 测评模板
Settings → Assessment Templates
```
1. **Create Template** — Set name, question count, passing score, time limits
2. **Configure Dimensions** — Add/remove dimensions, set weights (e.g., PROMPT:30%, LLM:30%, IDE:20%, DEV_PATTERN:20%)
3. **Link Question Bank** — Create/attach a question bank with published items
4. **AI Generation** — If no bank linked, AI generates questions from knowledge base
Two built-in templates:
| Template | Questions | Dimensions | Audience |
|---|---|---|---|
| **Technical** | 20 | PROMPT 30%, LLM 30%, IDE 20%, DEV_PATTERN 20% | Developers, Engineers |
| **Non-Technical** | 10 | PROMPT 50%, LLM 30%, WORK_CAPABILITY 20% | Managers, PMs, Designers |
Dimensions are fully customizable — add/remove, adjust weights, change question count.
### Running an Exam
```
路径: 考核评估 → 选择模板 → 开始专业评估
```
**As an organizer (admin):**
1. Go to `Settings → User Management` → create student accounts
2. Give students their credentials
**For Organizers (Admin):**
1. Go to Settings → User Management → Create student accounts
2. Tell students their credentials
**As a candidate:**
1. Login → go to **Assessment**
2. Select a template → click **Start Assessment**
3. **Multiple choice:** click an option → click Confirm
4. **Short answer:** type your answer in the textarea → click Send
5. The AI may ask follow-up questions — keep answering
6. After all questions, view your score and certificate
**For Candidates:**
1. Login with credentials
2. Go to Assessment → Select template → Start
3. Answer multiple-choice and short-answer questions
4. AI may ask follow-up questions (multi-round dialogue)
5. View results after completion
**Viewing Results:**
- **History** — Right sidebar on Assessment page shows past attempts
- **Details** — Click any history entry to see per-question scores
- **Certificate** — Click "查看证书" to view grade and dimension breakdown
- **Export** — PDF report and Excel download available
**Viewing results:**
- **History** — right sidebar on the Assessment page
- **Details** — click any history entry to see per-question scores
- **Certificate** — click "View Certificate" for level, total score, dimension scores
- **Export** — PDF report and Excel download
### Tenant Management (SUPER_ADMIN only)
```
路径: 系统设置 → 租户管理
Settings → Tenant Management
```
- Create/edit/delete tenants with hierarchical parent-child structure
- Manage tenant members: add users, assign roles (USER / TENANT_ADMIN)
- Separate knowledge bases and settings per tenant
- Data isolation: users in Tenant A cannot see Tenant B's data
---
## 🔄 Key System Flows
### Authentication Flow
```
Password Login → JWT issued → API Key generated (stored in localStorage)
→ All subsequent requests via x-api-key header
→ x-tenant-id header for tenant context
```
### Question Selection Algorithm
```
Template dimensions (e.g., PROMPT:30, LLM:30, IDE:20, DEV_PATTERN:20)
→ floor + remainder allocation (guarantees sum = question count)
→ Higher weight dimensions get remainder priority
→ Each dimension's pool shuffled independently
→ Final result shuffled before return
```
### Role → Permission Resolution
```
User → TenantMember.role (SUPER_ADMIN/TENANT_ADMIN/USER)
→ Maps to Role entity via baseRole
→ RolePermission table gives permission keys
→ Legacy: user.isAdmin = true → ALL permissions
```
- Manage members: add/remove users, assign roles
- Per-tenant settings (models, knowledge bases, features)
- Data isolation: Tenant A users cannot access Tenant B data
---
## 🧪 Testing
Playwright test scripts in project root:
```bash
# Full system test (142 items)
cd /d/AuraK && node test-systematic.mjs
| Command | Coverage |
|---|---|
| `node test-systematic.mjs` | **142 tests** — auth, CRUD, RBAC, boundary, UI, user stories |
| `node test-e2e-full.mjs` | 94 tests — full E2E with 3 roles |
| `node test-user-lifecycle.mjs` | 42 tests — user lifecycle, edge cases |
| `node exam-organizer.mjs` | Exam scenario: create students → take exam → view results |
| `node test-permission-flow.mjs` | 3-role permission boundary verification |
| `node test-multiround.mjs` | Multi-round dialogue in assessments |
# Exam organizer scenario (create students → take exam → view results)
cd /d/AuraK && node exam-organizer.mjs
```
All test scripts are in the project root, prefixed with `test-*.mjs`.
---
## 🏗️ Project Structure
## 📁 Project Structure
```
AuraK/
├── web/ # React frontend
│ ├── components/
│ ├── views/ # Main page components
├── SettingsView.tsx # System settings (users, models, tenants)
│ │ ├── PermissionSettingsView.tsx # RBAC permission matrix UI
│ │ │ ├── AssessmentView.tsx # Assessment flow UI
└── AssessmentTemplateManager.tsx # Template editor
│ │ ── PermissionGate.tsx # Component-level permission gate
│ └── LoginPage.tsx # Login page
│ ├── src/
│ ├── contexts/AuthContext.tsx # Auth state + tenant switching
│ ├── hooks/usePermissions.ts # Permissions hook
│ │ ├── pages/workspace/ # Route pages
│ │ └── services/ # API clients
│ └── index.tsx # Entry + routing
├── server/ # NestJS backend
│ ├── src/
│ │ ├── auth/
│ │ │ ├── permission/ # RBAC module
│ │ │ │ ├── permission.constants.ts # 26 permission definitions
│ │ │ │ ├── permission.service.ts # Resolution + seed
│ │ │ │ ├── permission.guard.ts # @Permission() guard
│ │ │ │ ├── role.entity.ts # Role entity
│ │ │ │ ├── role-permission.entity.ts # Role ↔ Permission join
│ │ │ │ ├── role.controller.ts # Role CRUD API
│ │ │ │ └── permission.controller.ts # Permission API
│ │ │ ├── roles.guard.ts # @Roles() guard
│ │ │ └── combined-auth.guard.ts # Global auth guard
│ │ ├── assessment/
│ │ │ ├── services/question-bank.service.ts # Question selection algorithm
│ │ │ └── assessment.service.ts # Session management + grading
│ │ ├── user/ # User CRUD + controller
│ │ ├── tenant/ # Multi-tenant model
│ │ ├── admin/ # Admin API
│ │ └── super-admin/ # Super admin API
│ └── dist/ # Compiled output
├── docker-compose.yml
└── test-*.mjs # Playwright test scripts
├── web/ # React frontend (:13001)
│ ├── components/views/ # Main page views
│ ├── src/contexts/ # Auth / Language contexts
├── src/hooks/ # usePermissions
└── src/services/ # API clients
├── server/ # NestJS backend (:3001)
├── src/auth/ # Auth + RBAC permission module
│ │ ── permission/ # Role/Permission entities, service, guard
├── src/assessment/ # Assessment subsystem
│ ├── src/user/ # User CRUD
│ ├── src/tenant/ # Multi-tenant
└── src/admin/ # Admin API
├── CLAUDE.md # AI assistant reference
├── README.md # This file
├── README_ZH.md # 中文说明
├── test-*.mjs # Playwright test scripts
└── docker-compose.yml # Infrastructure
```
---
## 🔧 Configuration Reference
## 🏗️ Tech Stack
### Server Environment (server/.env)
| Variable | Default | Purpose |
|---|---|---|
| PORT | 3001 | API server port |
| DATABASE_PATH | ./data/metadata.db | SQLite file location |
| ELASTICSEARCH_HOST | http://127.0.0.1:9200 | Elasticsearch endpoint |
| TIKA_HOST | http://127.0.0.1:9998 | Tika text extraction |
| LIBREOFFICE_URL | http://127.0.0.1:8100 | Document conversion |
| JWT_SECRET | (required) | JWT signing key |
| UPLOAD_FILE_PATH | ./uploads | File storage |
| MAX_FILE_SIZE | 104857600 | Upload limit |
| Layer | Technology |
|---|---|
| Frontend | React 19, TypeScript, Vite 6, Tailwind CSS v4, Framer Motion |
| Backend | NestJS 11, TypeORM, LangChain, LangGraph |
| Database | better-sqlite3 (metadata) + Elasticsearch 9 (vector/text search) |
| Auth | JWT + API Key |
| AI | OpenAI-compatible (DeepSeek, Claude) + Google Gemini |
| Infra | Docker Compose (ES, Tika, LibreOffice) + Nginx |
---
## 📄 License
## 🔧 Configuration
See [LICENSE](LICENSE) file.
| Variable | Default | Purpose |
|---|---|---|
| PORT | 3001 | Backend port |
| DATABASE_PATH | ./data/metadata.db | SQLite path |
| ELASTICSEARCH_HOST | http://127.0.0.1:9200 | Search engine |
| JWT_SECRET | (required) | JWT signing secret |
| UPLOAD_FILE_PATH | ./uploads | File storage |
| MAX_FILE_SIZE | 104857600 | Upload limit (100MB) |
---
## 🔗 Related Documents
| Document | Audience | Content |
|---|---|---|
| [CLAUDE.md](CLAUDE.md) | AI assistants + Developers | Full technical reference: architecture, entities, API, permission system, assessment model, testing patterns |
| [README_ZH.md](README_ZH.md) | Chinese-speaking users | Complete Chinese user guide |
| [STARTUP.md](STARTUP.md) | Operators | Startup scripts and environment setup |
| [VERSION.md](VERSION.md) | All | Version history and changelog |