# Project Context

## Purpose
本项目是一个面向“考试/答题/问卷”场景的 Web 应用，支持用户免注册答题、题库管理、考试科目与任务分派、答题记录与统计分析，并提供管理员端的日常运营能力（题库/科目/任务/用户管理、导入导出、配置管理等）。

## Tech Stack
- 前端：React 18 + TypeScript + Vite + React Router + Ant Design + Tailwind CSS + Zustand
- 后端：Node.js + Express + TypeScript（`tsx` 运行，`nodemon` 热重载）
- 数据库：SQLite3（本地文件数据库）
- 文件处理：Multer（上传）+ XLSX（Excel 导入/导出）
- 其他：Axios（HTTP）、UUID、dotenv、concurrently

## Project Conventions

### Code Style
- 语言与模块：项目为 ESM（`package.json:type=module`），前后端均以 TypeScript 为主。
- 命名风格：前端组件/页面使用 PascalCase；变量与函数使用 camelCase；路由资源使用 kebab 或小写复数（以现有接口为准）。
- 错误返回：后端接口大多返回 `{ success: boolean, message?: string, data?: any, pagination?: any }` 的统一结构（见 `api/middlewares/index.ts` 的 `responseFormatter` 相关逻辑与各控制器实现）。
- 代码组织：尽量沿用现有分层与文件结构，不引入新的技术栈或重复实现。

### Architecture Patterns
- 前端：`src/pages` 放页面级组件；`src/components` 放复用组件；`src/contexts` 存放上下文状态；`src/services/api.ts` 封装接口访问；`src/utils` 存放通用工具。
- 后端：以 `api/server.ts` 为主要 API 入口，使用 Express Router 组织路由；业务按 `controllers/`（HTTP 处理）与 `models/`（数据库访问与领域逻辑）分层。
- 数据库初始化：`api/database/init.sql` 负责建表/初始化；应用启动时由 `initDatabase()` 执行初始化与连接。
- 环境变量：使用 `dotenv` 加载 `.env`；端口默认 `3001`（可通过 `PORT` 覆盖）；SQLite 文件路径可通过 `DB_PATH` 覆盖。
- 服务端口：
  - 前端开发：`http://localhost:5173/`
  - 后端开发：`http://localhost:3001/api`
- 本地代理：Vite 将 `/api` 代理到 `http://localhost:3001`（见 `vite.config.ts`），前端请求统一走相对路径 `/api`（见 `src/utils/request.ts`）。

### Runbook
- 安装依赖：`npm install`
- 启动开发：`npm run dev`（并行启动 `dev:api` 与 `dev:frontend`）
- 类型检查：`npm run check`
- 生产构建：`npm run build`
- 启动生产：`npm start`（运行 `dist/api/server.js` 并托管 `dist/` 下静态文件）
- 目录约定：前后端构建产物当前共享 `dist/` 目录；若构建过程出现互相覆盖，需要调整构建输出目录或构建顺序。

### OpenSpec 工作流（本仓库约定）
- 查看现有规格：`openspec list --specs`
- 查看变更提案：`openspec list`
- 校验变更提案：`openspec validate <change-id> --strict`
- 交互式选择：`openspec show`、`openspec validate`

### Testing Strategy
- 优先保证：`npm run check`（TypeScript 类型检查）与 `npm run build`（生产构建）可通过。
- 目前仓库存在 `test/` 下的接口测试样例（Jest + Supertest 风格），但 `package.json` 未提供统一的 `test` 脚本与相关依赖声明时需先补齐再启用。
- 功能新增或行为变更应补充可执行的自动化测试（单测/接口测试均可），并避免引入仅用于一次性验证的脚本逻辑进入生产代码路径。

### Git Workflow
- 建议以功能为单位创建分支，保持提交粒度清晰（一个提交聚焦一个主题）。
- 与规范相关的变更（需求/行为/接口/数据结构）优先通过 OpenSpec 变更提案（`openspec/changes/<change-id>/`）描述，再进入实现。

## Domain Context
- 核心领域对象：
  - 用户（User）：通过姓名 + 手机号进入系统；密码字段目前存在且为敏感信息。
  - 题库（Question / QuestionCategory）：支持题目类别、题型（单选/多选/判断/文本）、导入导出。
  - 考试科目（ExamSubject）：描述抽题规则（题型比例、类别比例、总分、时长）。
  - 考试任务（ExamTask）：面向一组用户分派某科目，在开始/结束时间范围内有效；支持按用户与按用户组混合选择，并在服务端进行去重；原始选择通过 `selectionConfig`（JSON 字符串）保留。
  - 答题（QuizRecord / QuizAnswer）：记录得分、正确数、明细答案等。
  - 系统配置（SystemConfig）：保存抽题配置、管理员账号配置等。
  - 用户组（UserGroup / UserGroupMember）：
    - 内置“全体用户”系统组：新用户自动加入；不可删除/不可修改；用户不可主动退出。
    - 注意：用户组相关功能（管理、成员关系、考试任务按组分派与混合选择）目前已实现但处于未测试状态，且缺少“用户组变更审计日志”能力。
- 管理员能力：管理员登录目前为简化实现（固定账号与 token），并通过 `adminAuth` 中间件保护管理接口。

## Important Constraints
- 鉴权现状：`adminAuth` 当前为简化放行逻辑，`/api/admin/login` 返回固定 token；生产环境需要替换为真实鉴权（例如 JWT 校验）并在前后端一致落地。
- 安全：用户密码目前存在明文存储/传输路径的风险，属于待整改项；任何日志与导出都应避免泄露敏感信息。
- 数据库：使用 SQLite 文件库，适合轻量/单机；并发与事务能力有限，涉及批量写入或一致性要求时需谨慎设计。

## External Dependencies
- 当前不依赖外部第三方服务；主要外部依赖为本地 SQLite 数据文件（`data/` 目录）与 Excel 文件导入导出能力。
- 若未来接入统一登录、对象存储、日志审计等外部服务，应在 OpenSpec 规范中补充依赖与接口约束。
