teacher-earnings-2026-10-15.md 10 KB

老师结课、复习和收入优化交付记录

代码基线:7bb38260e49e21dec0f466e4de713f868aa7b365。目标网关版本:2026-10-15-teacher-earnings-v12。本轮完成源码与本地验收,尚未部署生产,也未修改任何线上历史工资。

已实现

  • 老师可直接结束课程,反馈后补。事务仍校验身份、课程状态、学习批次、课时凭据,保存完课工资快照、扣课时并生成适用复习计划;后补反馈不重做结课。独立 feedbackStatus 区分待补和已提交。
  • 销课记录和结课结果显示实际课酬,合法零元与工资待核对分开。无统一固定单价、无测试账号工资特例。
  • 复习首次完成按数据库生成的北京时间完成时间计薪。当天 1 元、逾期 0 元、未来拒绝,重试返回原凭据;状态与收入同事务。行锁后取实际服务器时间,避免请求排队跨午夜仍使用请求开始时间。旧 content_update 入口同样受规则约束。
  • 首页仅显示全部今日任务,按每页 100 条完整加载后显示;发送 scope 与明确日期兼容旧接口,并在客户端过滤非今日记录,计数与列表一致。每条“查看计划”进入该任务详情;底部只保留“查看全部学员复习计划”,进入完整日历。没有任务、全部完成与加载失败分别呈现。
  • 首页、我的、销课和复习工资使用后台同一计算规则与净收入视图。老师收入是累计已记账收入,与工资实际发放分开;不再按课次数乘 20/40 元估算。缺失工资依据计入待核对数量。首页按最新反馈简化为累计时长与累计收入一行:时长直接显示,总收入默认隐藏,眼睛切换显隐;首页移除收入拆分、发放说明和待核对提示,具体明细仍从原入口查看。
  • 老师浏览日历、销课、工资、课程详情等页面保留现有底部导航。复习页去除内容区重复的“返回复习任务”,沿用左上角返回;练习中未提交离开有提示,提交中禁止离开;完成后有继续今日、返回原列表及首页,原列表日期、学生、页码与滚动位置可恢复。缓存隔离账号、日期、筛选和业务数据版本,跨页/标签写入失效;首页今日列表单独按登录账号、会话与北京时间自然日缓存到 sessionStorage,返回首页、切回前台和同日重载页面均复用,跨日/切换账号/新登录重新加载;手动刷新保留。服务器确认复习成功后更新缓存任务及计数,不重拉列表。
  • 历史错计提供只读核对工具、后台筛选和逐条纠正入口。原凭据不可改写;未结算来源净额冲销,草稿行移除,已审核/已发放原单保留,后续草稿记唯一关联调整。理由、原金额、调整金额和工资单可导出。没有运行历史纠正。

验证证据

检查 结果及限制
Node / 数据库回归 211 项通过;真实 PostgreSQL DDL、触发器、约束与事务在 PGlite 执行
移动端 ChromeHeadless 228 项通过,含未反馈结课、防重复提交、完整今日列表和按登录/日期缓存
管理端 ChromeHeadless 271 项通过,含纠正权限、理由和承接草稿版本检查
双端生产构建 通过;存在原有 SCSS budget 与 CommonJS 警告
cloud:validate 11 个函数校验通过
本地动作覆盖检查 122 个使用动作检查,missing 为空
浏览器页面 本地生产构建+隔离接口数据:当天/逾期完成、金额、首页缓存复用、手动刷新错误态、导航通过;360px/390px 截图已人工查看,姓名和工资不互相挤压
组合迁移 一笔事务安装,连续执行两次通过,原完课和反馈记录保留

复现:npm run test:server、npm run test:mobile:ci、npm run test:admin:ci、npm run build、npm run cloud:validate、npm run app:actions:audit:local。浏览器验收:npm run teacher-earnings:browser,截图/结果写入忽略目录 tmp/teacher-earnings-qa/,不会连接线上账号。

PGlite 单连接的并发调用会排队,不能证明生产 PostgreSQL 多连接并发性能。浏览器模拟数据不能证明线上账号、手机浏览器或微信 WebView 已通过。

性能实测及边界

以下为最初 4 条预览版本的查询阶段测量,不代表后来“全部今日任务+当天缓存”版本的首载性能;后者首载请求量随当天任务数变化。

固定 10,000 条任务,40 条今天任务,原始与修改后 appReviewPage 使用同一 PGlite 数据库和现有索引。先各预热 4 次,再按 AB/BA 交替各测 20 次,不注入网络延迟。原始首页请求 pending/20 条,修改后请求 today/4 条并省略日历和学员元数据。

测量 原版 修改后
p50 120.66 ms 34.90 ms
p75 124.43 ms 35.90 ms
p95 134.27 ms 36.39 ms
页面数据 SQL 数 6 3
序列化响应 28,665 bytes 2,046 bytes
首页结果中的今日任务 0 4
错误率 0/20 0/20

p75 查询阶段下降约 71%。这是本地 SQL 和序列化测量,排除了真实网络、版本查询和浏览器渲染,不等于五条真实路径已经达成 50% 提速。最初缺少索引的探测中,新查询反而更慢,因此保留索引核验作为发布检查;没有据此盲目添加生产索引。原始采样见 perf/teacher-review-2026-10-15.json。

复现:准备基线提交的 scripts/cloud/mobile-teaching.js,执行 npm run teacher-earnings:benchmark -- --baseline=/绝对路径/mobile-teaching.js。线上须核查现有 CommonModel/company/model/item、CommonModel/company/model/general、DailyStudyRecord/company/id、MemoryPracticeRecord/company/user/time 与 coach/status 索引和实际执行计划。

以下仍待同一隔离账号、设备、网络下交替各测至少 10 次,报告 p50/p75/p95、请求数、响应体积及错误率:

  1. 老师首页:从导航到今日任务和收入均可使用。
  2. 今日复习:从入口到任务列表可操作。
  3. 复习内容:从任务点击到单词可操作。
  4. 完成复习:从点击提交到服务端确认且页面显示结果。
  5. 工资明细:从入口到真实金额明细可核对。

仍需关注:累计课酬读取规范化工资来源及历史规则,特定学员复习仍可能等待旧数据同步;本轮未将旧同步改成无监控的后台任务,也未宣称这两条路径已提速。

收入字段兼容修正

2026-10-15 再次只读检查,线上仍为 2026-10-14-member-credit-v11。旧版统计仅提供按课次数估算的 t_yongji,不能作为真实总收入。首页优先显示 totalIncome,或将有效的实际 lessonIncome 与 reviewIncome 按分合计;两者均不可用时明确显示“暂不可用”,不再只显示横线。真实金额仍依赖兼容数据库迁移与收入网关发布;当前执行环境未配置发布主密钥及管理员会话,未执行发布。

线上只读核对

2026-10-15 11:43 北京时间只读检查公开 migration_status:HTTP 200,现网仍为 2026-10-14-member-credit-v11,尚无 app_review_complete。只检查版本,不触碰账号或业务数据。

本轮环境检查:未提供 XIAOSHU_SESSION_TOKEN 或 XIAOSHU_MASTER_KEY。因此没有核对录音中的钱老师账号、10 月 13 日课程与真实错计名单,不能把测试数据当作业务清单。

在已授权环境设置现有管理员会话(不要把凭据写进文档或终端参数),使用明确老师编号和年份范围:

npm run teacher-earnings:audit -- --check
npm run teacher-earnings:audit -- --coach-id=实际编号 --from=YYYY-MM-DD --to=YYYY-MM-DD --output=/私有路径/核对目录

工具只读查询,输出课程/学习批次/保存计划/既定周期/任务归属/错计凭据及工资单状态。按实际结课日核对 1、2、3、5、7、9、11、14、17、21 天;缺少完成日或索引时列出限制。无适用学习内容的课不要求生成单词复习任务。历史手工转交必须结合转交审计解释,不能直接按当前预约老师覆盖。错计接口要求 beijing-day-v1 标记,旧网关不会被误当作完整清单。

先核对唯一老师身份和年份,再运行;输出私有 JSON,不进入 Git。清单完成后逐笔确认,不自动批量冲销、不自动发放。

发布与回滚

发布需确认本次提交版本,按计划另行执行。本轮没有运行以下写入步骤。

  1. 确认现网已具备 member-enrollment、mobile-teaching、lesson-study-batches、payroll-integrity 前置安装及 Parse 类。读取线上网关版本和发布文件哈希,确认同步任务空闲、既有索引和关键表结构。
  2. 在可信环境设置主密钥和现有经理会话。npm run teacher-earnings:migrate 只输出 SQL 哈希,不执行;审核哈希后使用 --apply --backup-dir=/私有绝对路径。脚本验证身份和活动同步任务,先保存一致性表数据、函数及列定义,再将四份兼容 SQL 作为单事务执行;失败回滚,成功回读函数和字段。临时函数限定操作者、15 分钟过期且 finally 清理。不要复用同一个备份目录覆盖上次备份。
  3. 核对 readback 三项均为 true、备份可读取。发布 xiaoshu.app.gateway、xiaoshu.ops.gateway、xiaoshu.ops.gateway.v3,再发布本次移动端与管理端构建;确认 migration_status 为目标版本。保留线上原始文件备份。
  4. 用隔离账号执行真实闭环和金额回读:不填反馈结课→只扣一次→待补反馈→补交不重复记薪;当天/昨天任务分别 1/0;旧客户端重试、新客户端并发、跨日重试;老师、明细、后台、导出金额一致。再核对录音账号只读清单。
  5. 分别完成手机浏览器、真实微信 WebView 和上述五条路径性能验收,再开放发布范围。具体历史工资调整只执行已核对的单条记录。

回滚优先退回前端文件,必要时回退后端展示逻辑;数据库新增账本、调整凭据、防重约束、当天资格规则和已发生的真实账务必须保留。不得删除凭据、改回金额或恢复可绕过资格判断的完成函数。历史纠正不通过删行撤回;如纠正依据有误,另行审核财务调整。新旧客户端仍使用同一数据库守卫。