5.8 KiB
5.8 KiB
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 规范中补充依赖与接口约束。