Files
aurak/CLAUDE.md
T
Developer 65ede9fcff docs: 全面更新文档体系 — AI指南 + 人可读说明书
CLAUDE.md — AI 工作指南:
- 项目全景:目录结构/技术栈/端口
- 系统架构:前端路由/后端模块/认证流程
- 权限系统:三层角色/26项权限/守卫流水线/解析链路
- 考核系统:数据模型/出题算法/模板配置
- 测试脚本:7个Playwright测试说明
- 开发指南:启动/测试/重启/数据库管理
- 代码规范:TypeScript模式/权限装饰器/React约定
- Playwright测试技巧:React受控输入框/等待策略

README.md — 人可读英文说明书:
- 系统介绍 + 功能特性
- 完整使用指南(用户管理/权限管理/考核模板/组织考试)
- 核心流程说明(认证/出题/权限解析)
- 测试命令参考
- 项目结构 + 配置参考

README_ZH.md — 人可读中文说明书:
- 全面中文版本,包含所有新功能
- 步骤式操作指南,便于管理员使用

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-09 13:19:45 +08:00

399 lines
12 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# AuraK — AI 工作指南
> 本文件指导 AI 助手(Claude Code 等)如何理解和使用此仓库。
> 项目:AuraK — 企业级多租户 AI 知识库与人才评价平台
---
## 一、项目全景
```
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() 装饰器跳过认证
```
---
## 三、权限系统(RBAC)核心
### 3.1 三层角色
| 角色 | 权限数 | 能做什么 |
|---|---|---|
| **SUPER_ADMIN** | 26 项 | 全部权限:用户/租户/知识库/考核/模型/插件/设置 |
| **TENANT_ADMIN** | 21 项 | 管理本租户用户和资源;不能跨租户/删用户/改系统设置 |
| **USER** | 5 项 | kb:view/create/edit, assess:view, plugin:view |
### 3.2 权限常量定义
位于 `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` |
---
## 六、开发指南
### 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 权限装饰器使用
```typescript
// 后端 API — 在控制器方法上标注所需权限
@Post()
@UseGuards(PermissionsGuard)
@Permission('user:create')
async createUser(@Request() req, @Body() body: CreateUserDto) { ... }
// 前端 — 用 PermissionGate 组件或 usePermissions hook
<PermissionGate permission="user:create">
<Button></Button>
</PermissionGate>
const { hasPermission } = usePermissions();
{hasPermission('user:view') && <UserList />}
```
### 7.3 通用 React 约定
- 使用 `cn()` 工具函数(tailwind-merge)合并 className
- 图标用 `lucide-react`
- 动画用 `framer-motion`
- API 调用用 `apiClient` 或原生 `fetch`
- 模态框用 `createPortal` + `AnimatePresence`
---
## 八、Playwright 测试指南
### 8.1 测试模式
```javascript
import { chromium } from 'playwright';
const browser = await chromium.launch({ headless: true });
const page = await browser.newPage({ viewport: { width: 1440, height: 900 } });
// 模拟 API 调用
const r = await fetch(`${API}/api/auth/login`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ username, password }),
});
```
### 8.2 React 受控输入框操作(关键)⚠️
React 的受控 input/textarea 依赖 native setter 触发 `onChange`。**不要用 `type()``fill()`**,应使用:
```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 }));
}, '要输入的文字');
```
### 8.3 等待按钮可用
```javascript
await page.waitForFunction(() => {
const btn = document.querySelector('button:has(svg.lucide-send)');
return btn && !btn.disabled;
}, { timeout: 10000 });
```
### 8.4 等待 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 };
});
```
---
## 九、部署配置
### 端口
| 服务 | 端口 |
|---|---|
| 前端(开发) | 13001 |
| 前端(生产/Nginx | 80/443 |
| 后端 API | 3001 |
| Elasticsearch | 9200 |
| Apache Tika | 9998 |
| LibreOffice | 8100 |
### 环境变量
`server/.env` 关键配置:
```
PORT=3001
DATABASE_PATH=./data/metadata.db
ELASTICSEARCH_HOST=http://127.0.0.1:9200
JWT_SECRET=your-secret
```
---
## 十、快速参考命令
```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
# 数据库查询
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();"
# 清理端口
taskkill //F //IM node.exe 2>/dev/null
# 前端编译
cd /d/AuraK/web && npx vite build
```