生成一个文件并不等于完成出版。真实交付会遇到缺失题图、跨页裁片、字体替换、渲染超时、Worker 重启、下载权限和终态文件丢失。只要页面显示“导出成功”而最终文件不可读,系统就把技术中间态冒充成了教师结果。
TeachFlow 将作业出版拆成预检、创建 Job、异步渲染、终态检查和授权下载。

预检先回答“能不能出版”
预检检查题目版本、图片与多裁片来源、纸张配置和必要资源,不写最终发布事实。缺少来源时返回可解释问题,教师可以回到组卷修改,而不是等到 Worker 中途失败。
Job 状态不能只存在进程内
渲染任务写入持久状态,由 Worker 领取;成功必须同时具备终态记录和可读取文件。进程退出后,未完成任务可以重新判断,而不是因为内存 Promise 消失就永远停在“处理中”。重复请求通过稳定输入指纹避免制造多个不一致文件。
DOCX 与 PDF 也不是同一个成功信号。DOCX 结构正确不保证 PDF 分页正确;PDF 生成成功也不保证题图、页码与引用完整。项目用 Golden Fixture、多裁片反例和浏览器下载状态分别检查这些边界。
文件也需要保留与授权
终态附件只能由任教教师或目标学生按业务范围读取。保留策略先支持 dry-run 和报告,再执行受控清理;删除文档不能顺便删除作业、题目或发布事实。
一个“数据库成功、文件失败”的反例
假设 Worker 已把 Job 更新为 succeeded,随后文件写入失败,或文件在后续清理中意外丢失。若下载接口只相信数据库状态,教师会看到成功徽标,却拿到 404 或空文件。正确合同要求终态记录与可读取 artifact 一致;文件缺失应变成明确、可重试的失败,而不是继续展示为成功。
反过来,磁盘里出现一个文件也不等于业务成功。它可能来自已取消任务、旧输入或越权请求,必须通过 Job、输入指纹、所有者和文档快照才能被领取。由此可见,出版产物不是普通静态文件,而是受业务状态和身份约束的交付证据。
设计取舍:为什么预检不能保证最终一定成功
预检只能验证当前可知条件,例如题目版本、来源裁片、页面配置和资源可读性;它不能消除渲染进程崩溃、字体环境差异、存储失败或队列竞争。预检的价值是尽早拒绝确定性错误,Job 状态机负责表达运行期失败,两者不能互相替代。
关于“是否兼容所有 Office”,当前证据只能说明本轮没有跨 WPS、Word 和不同字体环境重渲染。现有复核截图、持久化检查源码和历史多裁片文档可以证明既有路径,但不能把已有 DOCX/PDF 样例扩大成全平台兼容声明。
当前边界
当前源码、历史出版批次文档和验收截图支持上述机制,但本轮没有重新调用 WPS/Office、PDF 渲染 Worker 或执行跨平台视觉检查,因此状态为 partial。不同办公软件兼容、字体许可、大批量排队和对象存储仍需生产验证。
结论
文档出版的产品价值不是“有一个导出按钮”,而是教师在提交前能判断风险、失败后知道停在哪里、成功后能拿到经过授权且可复核的文件。