# 排课、结课与学生评价改造 2026-10-11。源代码实现完成;用户最后要求只在本地运行,不部署线上。本文件不代表三端真实账号验收完成。 2026-10-15 增补:结课与反馈已分离。`app_lesson_complete` 可不带 feedback,报告标记 pending,正常校验、课时事务与工资快照不变。结课后由 `app_lesson_feedback_update` 首次补交或修改;未填写不显示为已提交。当前交付与验收见 [老师收入优化](teacher-earnings-2026-10-15.md)。 ## 业务与实现 - 流程改为后台排课 → 老师上课 → 老师一次结课(0→10→30)→ 学生随后评价。评价不再阻塞报告、完课记录或课酬快照。 - 管理端、师生课表及详情使用同一新库预约。归属按帐套、教师/学生编号、GeneralID、bindingId 匹配。新课表不等待旧系统实时拉取。 - 课表和详情在页面可见时每 15 秒查询新库版本;版本变化才重载。回到前台、恢复网络与手动刷新立即查询。隐藏页面不发轮询请求,离开页面清理监听器。 - 未来课程也可打开详情,开始权限由服务器北京时间当天规则决定。已开始课程可跨午夜继续。保留日期、学生筛选,增加清除筛选与最近课程入口。 - 详情失败时缓存只展示,不开放写操作;开课失败给出持久提示。写作分类兼容旧 if_writing,沿用原有授课和反馈流程,无需选择单词单元,不新增音视频课堂。 - app_lesson_complete 在一个 SQL 事务内完成报告、课堂成果快照、完课记录、预留消费、扣费和状态推进。重复请求、连点及并发由预约锁、请求键和已有结果共同约束。 - app_lesson_review 校验预约学生、已结课状态、1–5 分、最多 200 字。首次评价生效,重复请求返回已有评价,课程状态与账务保持不变。 - 历史 11/20 课程复用已有学习记录、评价及扣费凭据;缺失、重复或矛盾凭据进入后台异常清单,不猜测补扣。旧 11/20/40 保留读取,不批量改历史。 - 后台按预约查看计划/实际时间、报告、评价、预留状态、上课记录数和异常。管理员原有课时纠错操作增加事务内原因记录。 - 旧分步结课/确认写入口返回刷新提示;通用内容接口不能创建或修改正式预约、上课记录与评价。新库推进过的课次有同步保护和状态回退触发器。 - 工资仍使用唯一有效课次和原计价快照;没有修改已锁定工资单。 ## 本地运行 ```sh npm run start:mobile # http://localhost:4200/pages/home/shop npm run start:admin # http://localhost:4300/admin/schedule ``` 两端开发服务和 main.js 已 HTTP 验证成功。开发代理仍连接现有云后台,不是隔离后端。当前线上缺少新结课/评价接口;本地新详情会提示服务尚未更新并保持只读。不要把本地前端启动视为新业务闭环的线上验收。 ## 已执行验证 | 检查 | 结果与边界 | | --- | --- | | 移动端 ChromeHeadless | 169 项通过,含路由、开课错误、写作分类、详情只读、结课和评价页面测试;接口为测试替身 | | 管理端相关测试 | 41 项通过,覆盖排课页面和服务调用 | | 开课、课时、教学与新流程 Node 测试 | 41 项通过;新事务测试使用 PGlite 和真实网关函数代码,非生产 PostgreSQL 多连接验收 | | 工资回归 | 20 项通过,保留计价快照、跨批次防重、审计与锁单规则 | | 云函数语法 | 11 个定义校验通过 | | 生产构建 | 师生端、管理端通过;保留现有样式预算和 CommonJS 警告 | | 本地 HTTP | 两个课表入口与主脚本均为 200 | | 线上能力检查 | 新接口 app_lesson_complete、app_lesson_review 尚未发布;app:actions:audit 因这两项缺失返回失败 | | 钱老师实际样例 | 尚未拿到账号对应的预约/接口响应,不能认定现场根因;未修改真实课程 | | 三端真实浏览器/手机 | 尚未验收;浏览器控制连接超时,自动测试不替代手机体验 | 数据库专项覆盖:失败注入后报告/扣费/状态整体回滚、重复完成/评价、越权、过期版本、取消、同日提前开课、非当天阻止、跨午夜恢复、旧凭据复用与拒绝补扣、旧接口拒绝回退、超过一页的列表、后台凭据查询及新库版本变化。 ## 后续发布与验收步骤(本次未执行) 1. 只读核对钱老师:运行 `node scripts/audit-lesson-chain.mjs`,先返回候选编号,再配置 `XIAOSHU_AUDIT_TEACHER_ID` 精确检查。配置 `XIAOSHU_AUDIT_TEACHER_SESSION` 可核对本人列表及详情。脚本需要环境中的 `XIAOSHU_MASTER_KEY`,不创建临时用户、不改课时。业务输出不要提交 Git。 2. 先核对目标库已有 member-enrollment、mobile-teaching 迁移和 Parse Schema。运行 `npm run lessons:migrate -- --apply` 注册兼容字段、安装事务和回退保护;脚本无历史数据回填。 3. 发布云函数并确认 migration_status 为 `2026-10-11-lesson-workflow-v2`,再发布管理端和师生端;执行 `npm run app:actions:audit`。 4. 配置部署环境后运行 `npm run lessons:smoke`:创建隔离账号、排当天课程、保存真实词库学习成果、并发结课、评价、后台对账、清理测试资源。该脚本会写入隔离业务数据,不是只读探测。清理失败时保留受限 fixture 文件,禁止删除真实业务记录来补救。 5. 用管理、老师、学生三个会话人工走同一条预约;老师课表保持打开验证下一轮 15 秒出现。测试断网恢复、双击、改期取消、会话过期,再核对一条有效课次、一份报告及一组扣费流水。 6. 手机体验、前端实际部署版本、三端浏览器验收和账务对账分别记录。满足这些条件后才可称为全流程上线完成。 复跑本地检查:`npm run test:lesson-workflow`、`npm run test:member-enrollment`、`npm run test:payroll-integrity`、`npm run test:mobile:ci`、`npm run cloud:validate`、`npm run build`。 ## 同日开课问题复核与修正(2026-10-11 晚) 在已登录的本地教师端复现:当天 14:00、16:00、21:00 的课都被按计划结束时刻标成“计划未完成”;详情能打开,但旧接口缺少 `allowedActions` 时,前端把原有开课动作一并禁用了。 - 课表按北京时间的预约日期判断过期,当天始终保留“未开始/已开始”。点击直接打开详情,避免等待学员资料请求;详情负责绑定当前预约学员。 - 成功取得编号一致的服务端详情后,旧接口仅兼容该课次老师的 `start/continue`:未开始课程限预约当天,已开始课程允许跨午夜继续。开课仍通过原接口再次校验,不能从缓存推导写权限;新接口明确返回的权限不被覆盖。 - 详情显示当天可提前或延后的规则;未选单元时保留明确错误提示。新结课和评价功能仍需后续发布,不因兼容开课而放宽。 - 本地浏览器已确认三节课程状态修正,以及 21:00 课程可显示开课按钮、未选单元时正确提示。未对真实课次提交开始、结课或扣费操作。 - 移动端全量 181 项通过;其中流程专项 19 项覆盖旧接口兼容、同日早晚、跨午夜、非当天、其他老师、取消、编号不符、后台刷新失败和服务器拒绝。开课写入及课堂跳转使用隔离接口替身验证,真实三端写入验收仍未执行。