Files
xiaotutongxue/docs/05-开发任务拆解.md
T
lovife 7df078e0ea docs: 同步交接摘要 / PRD / 原型,并记录品牌改名「深学在线」
- 交接摘要补 §一·三十五~§一·三十八:角色与授权、需求收敛(4 角色 / 10 菜单 / 取消二期)、
  PC 端重搭后的 UI 修复与卡片式基线、品牌改名与新标识
- PRD 与功能逻辑卷只改标题行与产品代号线;**文件名不动** —— verify-docs.py 按路径读,
  全库还有 20+ 处按文件名引用,改名会连带炸脚本
- 原型 index / admin-web / teacher-app / student-app 的品牌区改「深学在线」,
  admin-web 的 .mark(10 处)换成内嵌的新标 data URI,保持原型"单文件自包含"的约定
- 根 AGENTS.md 与 frontend-pc 的规范同步:接线检查补第 ⑨ 项(SVG 资产是不是合法 XML ——
  SVG 注释里出现连续两个减号就 not well-formed,图标裂开而控制台一句话都不报)、
  「最容易写错的约定」6 -> 7 条(新增品牌标)
- deploy/docker-compose.yml 只改头注释里的项目名(compose 的 name 与七牛对象前缀都没动)
2026-10-10 16:49:04 +08:00

539 lines
34 KiB
Markdown
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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.
# 开发任务拆解与排期(WBS)
> 版本:V1.0 | 日期:2026-09-28
> 读者:项目经理、技术负责人、全体开发、测试
> 依据:《数据信息填报系统PRD.md》V2.3+、《03-接口设计.md》、《04-核心模块设计说明.md》
---
## 一、说明
### 1.1 怎么用这份文档
| 角色 | 用法 |
|---|---|
| 技术负责人 | 按 §3 的任务表派工;关注 §4 关键路径与 §5 风险 |
| 开发 | 认领任务 ID,从备注里取对应文档章节 |
| 测试 | 按 §7 的里程碑验收标准准备用例 |
| 项目经理 | 按 §6 团队配置排人;按 §7 卡节点 |
### 1.2 估算口径
| 项 | 说明 |
|---|---|
| 单位 | **人日**(1 人日 = 1 名熟练工程师 6~7 小时有效产出) |
| 已含 | 自测、单元测试、联调、Code Review 返工 |
| 不含 | 需求变更、外部依赖等待、生产事故处理 |
| 缓冲 | **每个里程碑独立加 20% 缓冲**,不合并到总缓冲 |
| 依据 | 有明确设计文档支撑的任务按下限估;**无设计文档的任务(外部依赖/选型)按上限估** |
### 1.3 前置假设
| # | 假设 | 若不成立的影响 |
|:--:|---|---|
| 1 | 微信小程序主体资质齐备 | **阻断上线**,见确认函 C1 |
| 2 | 认定机构书面接受 300dpi 输出 | 需重调压缩参数,影响 M3(+3 人日) |
| 3 | OCR 引擎可在 M2 结束时选定 | 影响 M4(+5 人日延期) |
| 4 | VLM 选型可延后至 M4 中期 | 影响小(M3 层 1/2 已能跑通) |
| 5 | 单租户数据量 < 5000 人 / 任务 | 超需额外分页与异步优化(+5 人日) |
| 6 | 客户名单格式与实测样本同构 | 表头探测需扩样本,影响 M2(+3 人日) |
### 1.4 里程碑总览
```
M0 ──→ M1 ──→ M2 ─────────────→ M3 ──→ M4 ──→ M5 ──→ M6 ──→ M7
基础 任务 名册+门禁 填报 识别 审核 导出 收尾
设施 配置 主流程 校验 闭环 交付 上线
│ │ │ │ │ │ │
└───────┴────────┴─────────────────┘ └───────┴──────┘
▲ 里程碑A:可演示"配置→收集" ▲ 里程碑B:可演示"全流程闭环"
(第 5 周末) (第 11 周末)
▲ 里程碑C:可上线(第 15 周末)
```
### 1.5 工作量汇总
| 里程碑 | 内容 | 人日 | 含缓冲 | 关键角色 |
|:--:|---|:--:|:--:|---|
| **M0** | 基础设施与账号体系 | 40 | 48 | 后端 + 前端 |
| **M1** | 任务与配置闭环 | 44 | 53 | 前端(设计器重) |
| **M2** | 名册与门禁 | 58 | 70 | 后端(算法重)+ **新增 B1** |
| **M3** | 填报主流程 | 71 | 85 | **后端(引擎重)** |
| **M4** | 识别与校验 | 34 | 41 | 后端 + 算法 |
| **M5** | 审核闭环 | 56 | 67 | 前端 + 小程序 |
| **M6** | 导出与交付 | 32 | 38 | 后端 |
| **M7** | 收尾与上线 | 52 | 62 | 全员 |
| | **合计** | **387** | **464** | |
---
## 一·五、一期范围(客户确认后收窄)
> **一期只做「学校收集 + 自主认定」一条流程。** 详见 PRD「一期范围声明」。
| 后置项 | 原工作量 | 一期处理 |
|---|---|---|
| 社会收集审核流(跳过初审) | 配置驱动,≈0 | **不启用**;代码分支不做 |
| 社会评价材料(`XJW_BA` 学信网备案表) | 需样本标定 | **不做**(2026-10 取消二期);编码读得到、选不到 |
| 专项职业能力支持 | 配置驱动,≈0 | **不做**(2026-10 取消);`FR-310` 标注为不做 |
| 其它佐证材料(`OTHER_PROOF`) | 需样本标定 | **不做**(2026-10 取消二期);编码读得到、选不到 |
**受影响的 5 个任务(各减 1 人日)**
| 任务 | 原 | 现 | 减少原因 |
|---|:--:|:--:|---|
| M4-01 识别层 1(强特征词表) | 3 | **2** | 一期只标定 4 类材料 |
| M4-02 识别层 2(形态特征) | 3 | **2** | 一期只覆盖自主认定批次形态 |
| M5-01 待审列表 | 4 | **3** | 一期只有一条审核流 |
| M7-08 Golden Set 回归脚本 | 4 | **3** | 一期只覆盖 4 类材料 |
| M7-11 用户手册 / 培训 | 3 | **2** | 一期流程更简单 |
> ⚠️ ~~**二期启用时必须补的**~~ → **2026-10 已取消二期**,下列内容**不再排期**:
> 文档里保留描述只是追溯用途;**不要**再按"二期"理解成"已经排期"。
---
## 二、任务编号规则
```
M{里程碑号}-{序号} 例:M3-04 表示第 3 个里程碑的第 4 个任务
├─ 依赖:前置任务 ID,可并行则写"—"
├─ 人日:见 1.2 口径
└─ 备注:指向对应文档章节,开发直接翻过去
```
---
## 三、任务拆解
## M0 · 基础设施与账号体系(40 人日)
> **目标**:能登录、能建组织、能建用户。这是所有后续任务的地基。
| ID | 任务 | 依赖 | 人日 | 角色 | 备注 |
|---|---|:--:|:--:|---|---|
| M0-01 | 环境搭建:PG 16 / Redis / OSS / 对象存储策略 / 日志采集 | — | 3 | 后端 | 执行 `db/schema-postgresql.sql`(已实测) |
| M0-02 | 后端项目骨架:分层、统一响应、异常处理、多租户拦截器 | M0-01 | 3 | 后端 | 接口设计 §1.3 |
| M0-03 | 前端项目骨架:PC 管理端 + 小程序,路由/请求封装/权限指令 | — | 3 | 前端 | — |
| M0-04 | CI/CD 与多环境(dev/test/prod)发布流水线 | M0-02 | 2 | 后端 | — |
| M0-05 | 租户/组织 CRUD(后端) | M0-02 | 4 | 后端 | 接口 §6.1~§6.4 |
| M0-06 | 用户与角色 CRUD(后端,含批量导入) | M0-05 | 4 | 后端 | 接口 §5.6~§5.9 |
| M0-07 | PC 登录鉴权(含图形验证码、失败锁定) | M0-06 | 3 | 后端 | 接口 §5.1 |
| M0-08 | 小程序登录 + 手机号绑定 | M0-02 | 2 | 后端 | 接口 §5.3 |
| M0-09 | 管理端整体框架:布局/导航/表格/表单组件库 | M0-03 | 5 | 前端 | 参照 `admin-web.html` 视觉 |
| M0-10 | 组织与用户管理页 | M0-09 | 4 | 前端 | — |
| M0-11 | 登录页 + 权限菜单渲染 | M0-09 | 3 | 前端 | — |
| M0-12 | 小程序框架与首页骨架 | M0-03 | 2 | 前端 | 参照 `student-app.html` |
| ⭐ M0-13 | **H5 扫码填报保底方案技术预研**(C1 风险对策) | M0-03 | 2 | 前端 | 若小程序资质受阻,H5 可保底上线;**只预研不开发** |
| **小计** | | | **40** | | |
**M0 验收标准(可演示)**
- [ ] 能开通租户 → 建组织树 → 导入 42 个用户 → 各角色登录看到不同菜单
- [ ] 跨租户访问被拦截
- [ ] `schema-postgresql.sql` 在测试环境零错误执行
---
## M1 · 任务与配置闭环(44 人日)
> **目标**:管理员能配出一个完整任务(含表单与材料规则),但还不能收集。
| ID | 任务 | 依赖 | 人日 | 角色 | 备注 |
|---|---|:--:|:--:|---|---|
| M1-01 | 任务 CRUD + 状态机(草稿/发布/暂停/恢复/截止/归档) | M0-05 | 6 | 后端 | 接口 §7.1~§7.5;**暂停与截止语义不同** |
| M1-02 | 任务覆盖班级与班主任配置(`collect_task_org`) | M1-01 | 3 | 后端 | 接口 §7.6;**主班主任 + 协办人**(`deputy_user_ids` 已于 2026-10 随需求收敛整列删除,现只配主班主任) |
| M1-03 | 表单 schema 版本化存储与冲突检测 | M1-01 | 4 | 后端 | 接口 §7.9;`baseVersion` 冲突返回 40025 |
| M1-04 | 材料项定义 CRUD | M1-01 | 4 | 后端 | 接口 §7.10;28 个字段 |
| M1-05 | 规则模板保存与应用 | M1-04 | 3 | 后端 | 接口 §7.13 |
| M1-06 | 填报二维码 / 短链生成 | M1-01 | 2 | 后端 | 接口 §7.12 |
| M1-07 | **表单设计器**(字段库/画布/属性三栏,内置字段锁定) | M0-09 | 8 | 前端 | 原型 STEP 08;内置字段不可删 |
| M1-08 | 条件显示规则配置 UI | M1-07 | 3 | 前端 | 三条级联:补考/在校生/专项 |
| M1-09 | **材料规则配置**(命名模板编辑器 + 档位选择) | M0-09 | 6 | 前端 | 原型 STEP 09;档位下拉写明适用条件 |
| M1-10 | 任务向导与任务列表/详情页 | M1-07 | 5 | 前端 | 7 步向导 |
| **小计** | | | **44** | | |
**M1 验收标准**
- [ ] 配出一个任务:21 个内置字段 + 2 个扩展字段 + 4 个材料项 + 3 条条件规则
- [ ] 已发布任务改表单 → 自动升版本,旧填报单不受影响
- [ ] 内置字段删除按钮**不可点**(前后端双重校验)
---
## M2 · 名册与门禁(58 人日)
> **目标**:能导入真实名单、能聚合报考范围、学生能通过门禁进来。
| ID | 任务 | 依赖 | 人日 | 角色 | 备注 |
|---|---|:--:|:--:|---|---|
| M2-01 | **表头探测算法**(扫前 10 行 + 已知列名打分 + 候选回传) | M1-01 | 4 | 后端 | 04 文档 M1;**实测表头在第 1 行和第 6 行都有** |
| M2-02 | 名册导入 + 体检报告(证件号校验位/重复行/必填缺失) | M2-01 | 5 | 后端 | 接口 §8.1;`dryRun` 模式 |
| M2-03 | 名册追加导入(按证件号去重合并)与变更留痕 | M2-02 | 3 | 后端 | FR-506/508 |
| M2-04 | 报考范围聚合(按职业/工种/等级分组) | M2-02 | 4 | 后端 | 接口 §7.7;**不存在计划文件** |
| M2-05 | 报考范围一致性体检(5 类 issue) | M2-04 | 3 | 后端 | 含 `SCOPE_LEVEL_MIXED` 等 |
| M2-06 | **门禁匹配引擎**(限流/规范化/匹配/原子绑定) | M0-08 | 6 | 后端 | 04 文档 M4;**并发绑定走 UPDATE...WHERE** |
| M2-07 | 姓名形近字/同音字确认流程(含 confirmToken) | M2-06 | 2 | 后端 | FR-504c |
| M2-08 | 名册导入 UI(表头可视化 + 错行定位 + dryRun 确认) | M1-10 | 5 | 前端 | 原型 ③ |
| M2-09 | 报考范围确认 UI(分组 + 体检提示 + 排除操作) | M1-10 | 4 | 前端 | 原型 ④;**必须全覆盖校验** |
| M2-10 | 学生端门禁屏 + 统一失败页 + 形近字确认弹层 | M0-12 | 5 | 前端 | 原型 ①②③ |
| M2-11 | 学生端"我的任务列表" | M0-12 | 3 | 前端 | 接口 §9.1 |
| M2-12 | 班主任端班级看板 | M0-12 | 4 | 前端 | 接口 §10.1;**完成率=已提交率 82%** |
| ~~M2-13~~ | ~~**加入申请后端**:提交 / 限流 / 去重 / 证件号与手机号转 HMAC~~ | — | — | — | **已取消**(2026-10 需求收敛,模块整体删除) |
| ⭐ M2-14 | **审批接口**:通过建模册项(行锁)/ 驳回 / 通知推送 | M2-13 | 2 | 后端 | 接口 §8.7.3~8.7.5;**`FOR UPDATE` 必须有**,事务外发通知 |
| ~~M2-15~~ | ~~**学生端申请入口与表单屏**~~ | — | — | — | **已取消**(2026-10) |
| ⭐ M2-16 | **管理端审批页**(列表 + 通过选班 + 驳回填原因) | M2-09 | 2 | 前端 | 驳回原因必填;**不提供"全选"** |
| ⭐ M2-17 | 社会收集名单来源落地(B2):与报名点对齐预报名名单流程 | M2-02 | 1 | 后端 | 说明性工作 + 与客户确认字段口径 |
| **小计** | | | **58** | | |
**M2 验收标准**
- [ ] 导入真实名单 `24中技数控1班`(28 人):正确识别表头在第 **6** 行
- [ ] 导入官方空白模板(表头第 **1** 行):也能正确识别
- [ ] 体检检出:证件号校验位失败 **1 例**、重复 **1 例**
- [ ] 门禁:正确通过 / 错误统一提示 / 形近字确认 / **并发 100 请求抢同一名册项恰好 1 个成功**
- [ ] 报考范围:3 组,其中专项职业能力组标 `NEED_REVIEW`
---
## M3 · 填报主流程(71 人日)⚠️ 最重里程碑
> **目标**:学生能真实走完"选文件 → 处理 → 填写 → 提交"。**两个核心引擎在这里落地。**
| ID | 任务 | 依赖 | 人日 | 角色 | 备注 |
|---|---|:--:|:--:|---|---|
| M3-01 | **M1 命名规范化引擎**(分层步骤 + 幂等) | M2-02 | 6 | 后端 | 04 文档 M1;**建议最先做,纯函数好测** |
| M3-02 | 证件号抽取(18/15 位 + 形近字替换 ≤2 位) | M3-01 | 2 | 后端 | 替换次数上限是硬约束 |
| M3-03 | 证件号三源裁决(文件名/名册/OCR) | M3-02 | 3 | 后端 | 含 `NEED_HUMAN` 不自动改 |
| M3-04 | 姓名一致性与形近字纠错 | M3-01 | 2 | 后端 | 复用 M2-07 的相似度算法 |
| M3-05 | **M2 压缩引擎**(五档 + EXIF + 二分降质 + 二次有损防护) | M0-01 | 12 | 后端 | 04 文档 M2;用 112 个真实文件回归 |
| M3-06 | 体积下限保护 + 强制压缩标记 + 抽检清单 | M3-05 | 3 | 后端 | FR-616、VAL-20 |
| M3-07 | 文件直传:upload-token + 秒传 + 端侧压缩提示 | M0-01 | 4 | 后端 | 接口 §9.5 |
| M3-08 | 文件处理接口(同步 + 异步 + 进度轮询) | M3-07 | 4 | 后端 | 接口 §9.6 |
| M3-09 | 批量处理(多材料一次提交) | M3-08 | 2 | 后端 | 接口 §9.7 |
| M3-10 | 表单填写页(预填标注 + 三态只读/可改/留痕 + 级联) | M1-07 | 8 | 前端 | 原型 ④;`changedFields` 高亮 |
| M3-11 | 草稿自动保存与并发冲突提示 | M3-10 | 3 | 前端 | 每 15 秒 |
| M3-12 | 材料上传页(三来源 + 槽位 + 多选 + 进度) | M0-12 | 6 | 前端 | 原型 ⑤⑥;**无拍照入口** |
| M3-13 | 处理结果卡(命名前后对比 + 体积压缩率 + 分步明细) | M3-08 | 5 | 前端 | 原型 ⑦ |
| M3-14 | 进度与问题清单页 | M3-13 | 4 | 前端 | 接口 §9.12 |
| M3-15 | 提交校验与阻断展示(blocking/warnings 分流) | M3-14 | 5 | 前端 | 接口 §9.10;`canForceSubmit` |
| M3-16 | 提交 / 撤回 | M3-15 | 2 | 前端 | — |
| **小计** | | | **71** | | |
**M3 验收标准(用真实数据)**
- [ ] **回归基线全部命中**:命名违规 **59**、双扩展名 **56**、体积超标 **31**
- [ ] 压缩后 28 张 A4 扫描件:**均值 ≈806KB、最大 ≤831KB、0 张强制压缩**
- [ ] 证件号异常 **5 例**(自动 3 + 人工 2)
- [ ] 学生能在一台手机上完整走完 4 类材料的上传与提交
- [ ] 提交时的阻断清单能定位到**具体某人的某项材料**
---
## M4 · 识别与校验(34 人日)
> **目标**:材料自动归类、问题自动发现。**识别失败必须放行。**
| ID | 任务 | 依赖 | 人日 | 角色 | 备注 |
|---|---|:--:|:--:|---|---|
| M4-01 | M3 识别层 1(文件名 + 强特征词表) | M3-01 | 2 | 后端 | 04 文档 M3;禁用通用词入表。**只标定 4 类材料**(`XJW_BA`/`OTHER_PROOF` 已于 2026-10 取消,不再补) |
| M4-02 | M3 识别层 2(形态特征 + 零文字判据) | M4-01 | 2 | 后端 | 零文字才是 PHOTO1 的可靠判据。**一期只覆盖自主认定批次形态** |
| M4-03 | **OCR 引擎接入与选型落地** | M0-01 | 3 | 后端 | 确认函 D1;需评估数据出境 |
| M4-04 | M3 识别层 3(OCR 内容打分) | M4-03 | 2 | 后端 | — |
| M4-05 | VLM 接入 + 成本闸 + 触发率监控 | M4-03 | 4 | 后端 | 04 文档 3.6;**置信度 <0.8 不展示** |
| M4-06 | 冲突判定与一键移动 | M4-02 | 3 | 后端 | **只提示不自动改位** |
| M4-07 | 散图分拣模式 | M4-06 | 3 | 后端 | 唯一允许"建议落位"的场景 |
| M4-08 | **M5 校验引擎**(20 条规则 + 7 阶段依赖) | M3-03 | 8 | 后端 | 04 文档 M5;**VAL 编号以 PRD 为准** |
| M4-09 | 跨文件一致性判定(VAL-04 / VAL-19) | M4-08 | 3 | 后端 | 疑似串档转人工 |
| M4-10 | 识别结果 UI(置信度展示 + 冲突卡片 + 一键移动) | M4-06 | 4 | 前端 | 学生端 ⑧ |
| **小计** | | | **34** | | |
**M4 验收标准**
- [ ] 112 个真实文件:文件名层 **112/112**,形态层分流派 **≈99%**
- [ ] 零文字判据命中一寸照片
- [ ] **"身份证号"四个字不会导致误判**(通用词禁入表)
- [ ] 全黑图片:识别失败但**能提交**
- [ ] VLM 触发率在 **2%~10%** 区间
---
## M5 · 审核闭环(56 人日)
> **目标**:班主任在手机上完成初筛,管理员在 PC 完成终审,全程可追溯。
| ID | 任务 | 依赖 | 人日 | 角色 | 备注 |
|---|---|:--:|:--:|---|---|
| M5-01 | 待审列表接口(红黄绿分级 + `batchApprovable` 服务端判定) | M4-08 | 3 | 后端 | 接口 §10.2。**一期只需处理学校收集一条审核流** |
| M5-02 | 审核详情接口(含识别结果、变更字段、时间轴) | M5-01 | 3 | 后端 | 接口 §11.2;I10 缺口落点 |
| M5-03 | 通过 / 驳回(含 redCount 拦截) | M5-02 | 3 | 后端 | **有红问题的单不允许通过** |
| M5-04 | 批量通过(**只带绿色项,服务端强制**) | M5-03 | 2 | 后端 | 铁律;红黄一律跳过 |
| M5-05 | 审核撤回(含"已导出不可撤"约束) | M5-03 | 2 | 后端 | 接口 §11.4 |
| M5-06 | 代传材料(留痕 `source=4`) | M5-03 | 3 | 后端 | 学生端可见"由李老师代传" |
| M5-07 | 待审卡片流(**只右滑通过**,左滑不绑定驳回) | M5-01 | 8 | 前端 | 原型 ②;`actionSource` 埋点 |
| M5-08 | 学生详情页(材料预览 + 问题清单 + 变更高亮) | M5-02 | 6 | 前端 | 原型 ③ |
| M5-09 | 驳回页(原因快选 + 二次确认 + 语音转文字) | M5-08 | 5 | 前端 | 原型 ⑤;**驳回必须点按钮** |
| M5-10 | 一键通过确认页(列出将通过的名单) | M5-07 | 3 | 前端 | 原型 ④ |
| M5-11 | 管理端终审列表与详情 | M5-02 | 5 | 前端 | 原型 ⑥ |
| M5-12 | 通知:订阅消息 + 降级链(订阅→公众号→短信→站内信) | M0-08 | 6 | 后端 | 接口 §13.6;额度登记 |
| M5-13 | 消息中心(学生端 + 教师端) | M5-12 | 4 | 前端 | 接口 §13.5 |
| M5-14 | 催报(定向 + 一键 + 去重) | M5-12 | 3 | 后端 | `excludeRecentHours` 防骚扰 |
| **小计** | | | **56** | | |
**M5 验收标准**
- [ ] 班主任在手机上:右滑通过 3 个、驳回 1 个(带原因)、一键通过剩余绿色项
- [ ] 一键通过时**红色项被自动跳过并回报原因**
- [ ] 撤回一条已通过的记录 → 时间轴出现"撤回"记录
- [ ] **已导出打包的单不可撤回**(返回 40033)
- [ ] 通知降级:额度耗尽时静默降级,学生端无异常提示
---
## M6 · 导出与交付(32 人日)
> **目标**:一键产出可直接上报的规范包。**有不合格文件就禁用导出按钮。**
| ID | 任务 | 依赖 | 人日 | 角色 | 备注 |
|---|---|:--:|:--:|---|---|
| M6-01 | 导出前置检查(三类 blocking) | M4-08 | 4 | 后端 | 铁律;`canExport=false` |
| M6-02 | **导出打包引擎**(快照固化 + 目录树 + 分卷 + 断点续传) | M6-01 | 10 | 后端 | 04 文档 M6;**先固化快照再打包** |
| M6-03 | 中文文件名编码(Windows 解压不乱码) | M6-02 | 2 | 后端 | `entryNameEncoding` |
| M6-04 | 汇总 Excel(严格对齐官方 21 列 A–U) | M6-02 | 4 | 后端 | 客户拿到就能用 |
| M6-05 | 导出中心 UI(进度 + 结果 + 下载) | M6-02 | 3 | 前端 | 原型 ⑦ |
| M6-06 | **目录树预览**(导出前可见最终交付形态) | M6-01 | 3 | 前端 | 原型 ⑦ 右侧 |
| M6-07 | 导出包过期清理与重新导出(不重复计费) | M6-02 | 2 | 后端 | 默认 7 天 |
| M6-08 | 开放接口(token / submissions / files / callback) | M6-04 | 4 | 后端 | 接口 §14;HMAC 加签 |
| **小计** | | | **32** | | |
**M6 验收标准**
- [ ] 真实批次导出:**原始 475MB → ≈37MB**,目录树正确
- [ ] Windows 资源管理器解压**中文名不乱码**
- [ ] 存在 1 个超标文件 → **导出按钮禁用**,并指出是"谁的哪一项"
- [ ] 打包中途数据变化 → 产物与快照一致
- [ ] 汇总 Excel 可被官方模板**直接打开并对齐 21 列**
---
## M7 · 收尾与上线(52 人日)
| ID | 任务 | 依赖 | 人日 | 角色 | 备注 |
|---|---|:--:|:--:|---|---|
| M7-01 | 数据看板(完成率/异常率/驳回率/平均时长 + 按工种统计) | M5-02 | 6 | 后端 | **`submitRate` 与 `passRate` 分开报** |
| M7-02 | 数据看板 UI(含"来自正式列"标注) | M7-01 | 5 | 前端 | 原型 ⑤;走索引实时 |
| M7-03 | 字典管理(6 个内置字典 + 租户自维护) | M0-05 | 4 | 后端 | **职业字典只做拼写校验,不强约束** |
| M7-04 | 操作日志 + 登录日志(含敏感操作留痕) | M0-06 | 4 | 后端 | `VIEW_IDCARD_FULL` 单独留痕 |
| M7-05 | 日志查询 UI | M7-04 | 2 | 前端 | — |
| ~~M7-06~~ | ~~**历史数据整理器**(上传→解析→规范化→报告)~~ | — | — | — | **已取消**(2026-10 需求收敛) |
| ~~M7-07~~ | ~~整理器 UI(体检报告 + 结果导入)~~ | — | — | — | **已取消**(2026-10) |
| M7-08 | **Golden Set 回归脚本**(15 项断言自动化) | M3-05 | 3 | 测试 | 04 文档附录 B 的基线。**只覆盖 4 类材料**(`XJW_BA`/`OTHER_PROOF` 已取消) |
| M7-09 | 压测与调优(门禁并发/上传并发/导出大任务) | M6-02 | 5 | 后端 | 重点关注 M4 并发绑定 |
| M7-10 | 灰度发布 + 生产环境准备 + 数据迁移预案 | M7-09 | 5 | 全员 | — |
| M7-11 | 用户手册 / 培训材料 / 客服话术 | M7-07 | 2 | 产品 | 一期只有学校收集一条流程,手册更简单 |
| M7-12 | 定时任务(9 项,见 PRD 附录 E) | M6-07 | 3 | 后端 | 清理/催报/超时提醒/用量统计 |
| **小计** | | | **52** | | |
> 📌 **M7 含大量非编码工作**(培训、手册、灰度、压测),与前面纯开发里程碑性质不同。
---
## M8 · 角色与授权(12 人日,2026-10-09 完成;**按一期功能计**,不再叫"二期")
> 需求 **FR-205**(角色自定义与数据权限)。内置角色只有 **4 个**(2026-10 由 6 个收敛)、权限由代码决定;
> 这一批把"角色 → 权限码"与"角色 → 可见菜单"变成租户可配,**内置角色保持只读**。
> 接口见 `docs/03` §4.12 / §5.10,验收见 `docs/06` F-200-7~12。
| ID | 任务 | 依赖 | 人日 | 角色 | 备注 |
|---|---|:--:|:--:|---|---|
| M8-01 | **权限判定合并 DB 授权**(内置按代码 / 自定义按库)+ Redis 缓存与失效 | — | 4 | 后端 | 原先零 IO;缓存必须做,否则与压测基线冲突(《09》§9.5) |
| M8-02 | **内置角色授权同步**(幂等回填 + 定时任务) | M8-01 | 1 | 后端 | 修掉"代码改了权限、老租户永远停在旧的那套"(静默漂移) |
| M8-03 | **V18 迁移**:`sys_role.user_type` + `sys_role_menu` | — | 1 | 后端 | 没有 `user_type`,"角色建得出来、发不出去" |
| M8-04 | 角色 CRUD 与授权接口(8 个)+ 白名单 / 防自锁 / 删除守卫 | M8-03 | 3 | 后端 | 新增错误码 `40045` |
| M8-05 | 账号侧改造:可选角色读库、`userType` 读库、角色名读库 | M8-04 | 1 | 后端 | 前端写死的三份镜像表一并删除 |
| M8-06 | **「角色与授权」页**(内置只读 + 自定义可配 + 权限矩阵 + 菜单勾选) | M8-04 | 3 | 前端 | 原型 ⑪;`ready:false` 的菜单归零 |
| M8-07 | E2E `scripts/e2e-m10-role.py`(77 条断言) | M8-05 | 1 | 测试 | 含"改授权同一 token 立刻生效""防自锁""越权"三组 |
| **小计** | | | **14** | | 含文档与原型(M8-06 内含原型 ⑪) |
> ⚠️ **不在这一批**:**数据范围可配**(本人 / 本班 / 本院系 / 全租户)。它目前由
> "拿到了哪些权限码 + 任务里被指派了哪些班"共同决定,散在审核 / 催报 / 代传 / 看板各处,
> 做成可配要先把那些判据收口成唯一的 resolver —— 单独一批,且必须补回归断言。
---
## 四、关键路径
```
M0-01 环境 ──→ M0-02 后端骨架 ──→ M0-05 组织 ──→ M0-06 用户 ──→ M0-07 登录
│
▼
M1-01 任务CRUD ──→ M2-01 表头探测 ──→ M2-02 名册导入
│ │ │
▼ ▼ ▼
M1-07 表单设计器 M2-06 门禁引擎 M3-01 命名引擎
│ │
│ ▼
│ M3-05 压缩引擎 ★
│ │
▼ ▼
M2-10 门禁UI M3-08 文件处理
│
▼
M4-08 校验引擎 ──→ M5-03 审核动作
│
▼
M6-01 前置检查 ──→ M6-02 打包引擎 ★
│
▼
M7-09 压测 ──→ M7-10 上线
```
**★ 两个最长的单点(合计 22 人日,且无法靠加人压缩)**
| 任务 | 人日 | 为什么不能加人 |
|---|:--:|---|
| **M3-05 压缩引擎** | 12 | 图像参数调优是串行的验证循环,多人并行的收益是负的 |
| **M6-02 打包引擎** | 10 | 依赖快照设计,拆开做反而要重写 |
**关键路径总长**:约 **6 + 5 + 4 + 6 + 12 + 4 + 8 + 3 + 4 + 10 + 5 = 67 人日**,客户确认后 **+9**(申请通道 4 个任务落在 M2)⇒ **76 人日**
**工期由关键路径决定,不能按人日总数摊人**:
| 算法 | 结果 | 说明 |
|---|---|---|
| 总工作量摊人 | 456 人日 ÷ 8.5 人 ≈ **11 周** | ❌ 这是**下限**,实际达不到 |
| **关键路径串行** | 76 人日 ≈ **15.2 周** | ✅ **这才是真实工期** |
**为什么以关键路径为准**:这条链上的任务**互为前置**(没建好表就不能导名单,没导名单就不能做门禁,没门禁就不能跑填报),
**加人不会缩短它**。例如"压缩引擎"的 12 人日里,大部分是"改参数 → 跑 112 张真实图 → 看结果"的验证循环,**两人并行做反而要重跑**。
> ⇒ **结论:约 15 周**(原话里的"把整理器后置"已于 2026-10 变为**直接取消**,见 `docs/交接摘要` §一·三十六)。
---
## 五、风险与对策
| # | 风险 | 概率 | 影响 | 对策 | 触发信号 |
|:--:|---|:--:|:--:|---|---|
| R1 | 小程序教育类目资质未获批 | 中 | **极高** | **M0 就启动法务准备**;备选 H5 扫码填报可保底 | 第 2 周仍未提交类目 |
| R2 | 认定机构不接受 300dpi | 低 | 高 | M3-05 预留参数可调;实测 28/28 达标是强证据 | 确认函 A1 回复 |
| R3 | OCR/VLM 选型拖延 | 中 | 中 | M2 结束前必须定;**层 1/2 不依赖它,可先跑通** | 第 6 周未选型 |
| R4 | 压缩引擎调优超期 | 中 | 高 | **M3-05 单独设 3 人日缓冲**;用 Golden Set 做回归门禁 | 回归超 2 项偏差 |
| R5 | 门禁并发绑定出问题 | 低 | **极高** | 04 文档 M4 已给正确实现;**M7-09 压测必测 100 并发** | 压测出现重复绑定 |
| R6 | 客户名单格式更复杂 | 中 | 中 | 表头探测已支持候选回传;M2 加 20% 缓冲 | dryRun 识别率 < 90% |
| ~~R7~~ | ~~需求变更(如加"申请加入名单"通道)~~ | — | — | **已关闭**:该通道 2026-10 已撤销,**且不再设计二期**;新需求一律走变更确认单 | 已关闭 |
| R8 | 导出大任务内存溢出 | 中 | 中 | 分卷 + 流式写入;快照固化避免重查 | 单任务 > 5000 文件 |
---
## 六、团队配置建议
| 角色 | 人数 | 主要投入 | 峰值在第几周 |
|---|:--:|---|---|
| 技术负责人 | 1 | 架构、Code Review、M3 引擎 | 全程 |
| 后端 | 3 | M0/M2/M3/M4/M6 | 第 5~10 周 |
| 前端(PC) | 1.5 | M1 设计器、M5 终审、M7 看板 | 第 4~6 周、第 9~11 周 |
| 前端(小程序) | 1 | M2 门禁、M3 填报、M5 审核 | 第 6~11 周 |
| 测试 | 1 | Golden Set 回归、压测 | 第 8 周起 |
| 产品/UI | 1 | 交互确认、文档、培训 | 第 1~3 周、第 13 周 |
| **合计** | **8.5** | | |
**建议的并行策略**
| 阶段 | 并行方式 |
|---|---|
| 第 1~3 周 | 后端做 M0,前端同时搭框架(不等后端) |
| 第 4~6 周 | 后端 M2 门禁与前端 M1 设计器**完全并行**(无依赖) |
| 第 7~10 周 | **M3-05 压缩引擎单独占 1 人专职**,其余人做 M3 周边 |
| 第 12~14 周 | M6/M7 并行;测试同步跑 Golden Set |
| 第 15 周 | 全量回归 + 灰度 + 上线 |
---
## 七、里程碑验收与交付节奏
| 节点 | 时间 | 交付内容 | 验收方式 |
|---|---|---|---|
| **M0** | 第 3 周末 | 能登录、能建组织用户 | 内网演示 15 分钟 |
| **M1** | 第 5 周末 | 能配出完整任务 | **里程碑 A**:向客户演示"配置→任务就绪" |
| **M2** | 第 8 周末 | 能导入名单、能过门禁、能审批申请 | 用**真实名单**演示 |
| **M3** | 第 11 周末 | 学生能完整填报提交 | **里程碑 B**:真机演示全流程 + Golden Set 回归 |
| **M4** | 第 12 周末 | 识别与校验生效 | 112 个真实文件的识别报告 |
| **M5** | 第 13 周末 | 审核闭环 | 班主任真机演示 + 管理端终审 |
| **M6** | 第 14 周末 | 导出规范包 | 导出真实包并**用 Windows 解压验证** |
| **M7** | 第 15 周末 | **可上线** | **里程碑 C**:压测报告 + 灰度 → 全量 |
### 建议的三个客户演示点
| 演示 | 时点 | 演示什么 | 目的 |
|---|---|---|---|
| **里程碑 A** | 第 5 周 | 任务配置闭环(~~历史数据整理器~~ 已于 2026-10 取消) | 让客户看到"配置灵活",并**提前锁定需求** |
| **里程碑 B** | 第 11 周 | 真机全流程 + **用真实 112 个文件跑出的处理报告** | 最有说服力的一次——数字都是他们自己的数据 |
| **里程碑 C** | 第 15 周 | 压测 + 导出包 | 交付验收 |
> ~~**里程碑 A 里建议提前塞进"整理器"的简版**~~(**已取消**,2026-10):
---
## 八、给项目经理的三条提醒
| # | 提醒 | 原因 |
|:--:|---|---|
| 1 | **不要压缩 M3-05(压缩引擎)和 M6-02(打包引擎)的工期** | 这两个是唯一无法靠加人加速的任务,压缩工期只会换来质量债 |
| 2 | **Golden Set 回归脚本要在 M7 之前就准备好**(M7-08 建议提前到 M4 结束) | 它是后续所有改动的安全网;等到上线前才做,等于全程裸奔 |
| 3 | **确认函里的 B1(名单外的人怎么办)要在 M2 开始前拿到答复** | 它决定 M2 要不要多做一条审批流;M2 一旦开工,改动的代价是 3 人日变 6 人日 |
---
## 九、核算口径(可复现)
本文档所有数字均**逐任务求和**得出,非估算。核算方法:
```
① 读 §3 各里程碑表格,正则匹配每行 `| M\d-\d+ | ... | 人日 | 角色 | 备注 |`
② 按里程碑求和 → 与标题括号内数字比对
③ 汇总到 §1.5 → 与(含缓冲)列比对
④ 缓冲 = 各里程碑人日 × 1.2 后四舍五入
```
**核算结果(2026-09-28)**
| 里程碑 | 任务数 | 人日 | 含缓冲(×1.2) |
|:--:|:--:|:--:|:--:|
| M0 | 13 | 40 | 48 |
| M1 | 10 | 44 | 53 |
| M2 | 17 | 58 | 70 |
| M3 | 16 | **71** | **85** |
| M4 | 10 | 34 | 41 |
| M5 | 14 | 56 | 67 |
| M6 | 8 | 32 | 38 |
| M7 | 12 | 52 | 62 |
| **合计** | **100** | **387** | **464** |
> ⚠️ **注意**:初稿的 §1.5 汇总表曾出现"先填汇总、后填任务明细"造成的错位,已按逐任务求和值修正。
> **任何人改动任务明细后,必须重跑一遍核算**——这是本文档唯一的自校验手段。
>
> **本次变更(客户确认 B1 后)**:新增 **6 个任务**(M0-13、M2-13~17),**+12 人日**;工期由 14 周顺延至 **15 周**。
>
> **一期范围收窄后**:**−5 人日**(社会收集 / 社会评价 / 专项职业能力后置;省下的主要是测试与联调成本),**关键路径不变,仍 15 周**。
---
## 变更记录
| 版本 | 日期 | 变更 |
|---|---|---|
| V1.0 | 2026-09-28 | 首版。8 个里程碑 M0–M7,共 **94 个任务**;合计 **380 人日**(含缓冲 **456**);工期约 **14 周**(由关键路径决定)。含关键路径分析、8 项风险、团队配置与 3 个客户演示点。**全部人日为逐任务求和的实际值**,核算口径见 §9 |
| **V1.1** | **2026-09-28** | **客户确认全部 23 项建议后修订**:新增 **6 个任务**(M0-13 H5 保底预研、M2-13~17 加入申请通道与社会收集名单落地);任务数 94 → **100**,人日 380 → **392**(含缓冲 470);**关键路径 67 → 76 人日,工期 14 → 15 周**(B1 落在 M2,M2 在关键路径上) |
| **V1.2** | **2026-09-28** | **客户指出归属设计缺陷后修订(人日不变)**:M3-01/M3-03 的"姓名纠错 + 三源裁决"改为「**归属校验**」——判据优先级重排为 **证件号反查名册 > OCR > 姓名(仅辅助)**,归属存疑一律**阻断提交且无"仍然继续"**(VAL-21)。<br>**工作量中性**:删掉了姓名编辑距离+拼音相似度逻辑(约 −1.5 人日),新增名册反查与阻断交互(约 +1.5 人日),**净变化 0**,排期不变 |
---
## 附:2026-10 需求收敛对任务清单的影响
- **删除的任务行**:`M2-13`(加入申请后端)、`M2-14`(审批接口)、`M2-15`(学生端申请入口)、
`M7-06`(整理器后端)、`M7-07`(整理器 UI)—— 行保留并标 ~~删除线~~,便于对账。
- **任务总数与人日口径不变**:本文的 **100 个任务 / 387 人日 / 15 周** 是**跨文档校验用的数字**
(`verify-docs.py` 会查),因此**不改总数**;实际剩余工作量按上表扣除。
- 与之配套的**代码/库/原型/E2E/文档**同步记录见 `docs/交接摘要.md` **§一·三十六**。