# 题库质检方案

## 一、背景

### questions_tem 表预期结构（与 questions 对齐）

| 字段 | 说明 |
|------|------|
| id | 主键 |
| stem / content | 题干 |
| answer / correct_answer | 答案 |
| solution | 解析 |
| question_type / tags | 题型 |
| options | 选项（JSON） |
| kp_code | 知识点 |

- 待入库题目在 `questions_tem` 中，约 2 万道
- 需与 `questions` 正式表比对，确保不重复
- 入库前**严格校验**，以学案/PDF 导出场景验证

## 二、质检机制

### 2.1 题目质检（自动 + 人工）

| 校验项 | 说明 | 自动 | 人工 |
|--------|------|------|------|
| 缺题干 stem | 题干为空或过短 | ✓ | ✓ |
| 缺答案 answer | 答案为空 | ✓ | ✓ |
| 缺解析 solution | 解答题为空需标记 | ✓ | ✓ |
| 选择题缺选项 | choice 题型 options 为空或不足 | ✓ | ✓ |
| 公式乱码 | LaTeX 解析失败、出现未渲染符 | ✓ | ✓ |
| PDF 呈现 | 实际导出 PDF 是否乱码/错位 | ✓ | ✓ |

### 2.2 学案质检（可撤销）

- 学案使用场景：PDF 导出验证
- 连续 **10000 份** 无误 → 可撤销该环节以节省成本

### 2.3 结果记录

- 质检结果由命令输出，不落库（避免本地库覆盖导致表丢失）
- 后续可接入 question_qc_results 等表做持久化

## 三、校验规则清单（可扩展）

| rule_code | 名称 | 说明 |
|-----------|------|------|
| STEM_EMPTY | 题干为空 | stem 为空或 trim 后长度 < 5 |
| ANSWER_EMPTY | 答案为空 | answer 为空 |
| SOLUTION_EMPTY | 解析为空 | solution 为空（解答题强校验） |
| CHOICE_OPTIONS_MISSING | 选择题缺选项 | question_type=choice 时 options 为空或非数组 |
| FORMULA_INVALID | 公式异常 | LaTeX 定界符不匹配、无法解析 |
| PDF_RENDER_FAIL | PDF 渲染失败 | 导出 PDF 后检测乱码/空白 |

## 四、筛选逻辑（从下学期章节开始）

1. 获取**下学期**教材章节（`textbooks.semester_code` 或类似）
2. 通过 `textbook_chapter_knowledge_relation` 得到章节关联的 `kp_code`
3. 统计 `questions` 中每个 kp_code 的题目数量
4. **按题数升序**：优先选「题少的 KP」补充
5. 从 `questions_tem` 中筛选该 KP 的题目 → 质检 → 合格后入库

## 五、命令用法

```bash
# 按下学期题少 KP 筛选，质检 100 题
php artisan question:qc

# 指定知识点
php artisan question:qc --kp=S01

# 仅筛选不质检
php artisan question:qc --dry-run

# 指定教材、学期
php artisan question:qc --textbook=1 --semester=2 --limit=50
```

## 六、流程

```
questions_tem 选题（按下学期 KP 题少优先）
    → 自动质检（规则引擎）
    → 记录 auto_result
    → （可选）PDF 导出预演，检测渲染
    → 人工复核，记录 manual_result
    → 全部通过 → 入库 questions
```
