# 按器械填写课后评价 教练从已完成课程详情的「为这次课写评语」进入,评价继续关联该预约与学员。成长档案的「寄语 → 写评价」也可以记录不关联课程的教练笔记。 - 保留整体评价,新增 M、R、TT、Chair、ARC、SC、LB 七项自由文本,每项最多 1000 字。 - 所有字段均选填;整体评价或任意一项器械有非空白内容即可保存。空白器械不入库、不展示。 - 按器械展开填写,收起保留摘要;保存失败保留当前输入,可重试。主动关闭时会提醒放弃未保存内容。 - 继续沿用「分享给学员」开关,默认关闭。学员只可读取已共享笔记。历史笔记无需转换。 ## 部署 新增可空 MySQL JSON 字段 `member_notes.apparatus_notes`,迁移为 `20261018100000_lesson_apparatus_notes`。先在目标环境执行 `pnpm --filter @mp-pilates/server exec prisma migrate deploy`,重新生成 Prisma Client 并部署后端,然后发布小程序。此命令会部署目标库中所有尚未执行的迁移,应按现有发布流程核对。 本次迁移及服务端改动已与月卡周期功能一并部署生产。发布前纠正了原迁移误用 PostgreSQL JSONB 的问题,并在生产数据库的临时表上验证 MySQL SQL。详见 [联合发布记录](combined-release-2026-10-18.md)。新版小程序尚未上传或发布。 ## 验收 1. 从一节已完成课程进入,仅填写 M、仅填写整体评价、填写多种器械,分别保存;检查关联课程、换行及各器械内容。 2. 所有输入为空或只有空格时不可保存。填满 1000 字,检查计数和输入上限。 3. 展开、收起、切换器械,检查内容摘要与填写数量;滚动至 LB,检查软键盘、输入框和底部按钮在微信 iOS / Android 的可见性。 4. 保存时连续点击不重复提交;断网保存后内容保留,恢复网络可重试;关闭未保存表单可选择继续填写。 5. 默认私密记录仅馆主可见,开启共享后学员端按器械分段展示;未填写的器械不显示,历史整体评价仍显示。 本地已验证共享包构建、前端类型检查、小程序构建、后端构建,以及完整 Jest 测试。本地浏览器组件预览用于验证展开、切换、填写计数、仅器械保存及分段展示;不替代微信真机验收。 ## 单条评价分享 保存后自动进入评价详情页;档案内每条评价底部的「查看与分享」也可进入。教练页底固定「分享给学员」主按钮,避免长评价滚动后找不到操作。私密记录首次点击会确认开启该学员查看,再次点击调起微信转发;可随时关闭学员查看。 - 分享仅携带评价 ID,跳转 `/pages/profile/lesson-feedback?id=...`,不带管理员预览参数 `userId`。 - 分享标题与封面固定,不包含学员姓名、评价正文或页面截图。 - 学员详情接口 `GET /user/progress/notes/:id` 强制登录,并在同一次数据库查询中限定 JWT 学员 ID、评价 ID 与 `shared=true`。管理员打开学生分享链接同样没有跨学员读取权限。 - 教练预览和共享设置分别使用现有 ADMIN 权限控制下的 `GET /admin/members/:userId/progress/notes/:id` 与 `PUT .../notes/:id/sharing`;二者均限定目标学员与评价归属。共享修改仅接受布尔 `shared`。 - 详情响应设置 `Cache-Control: private, no-store`,仅返回展示所需内容。无权限、已删除、未共享统一返回 404,不泄露评价是否存在。 - 未登录先展示登录引导,登录后留在同一条评价;不显示任何姓名或正文预览。退出登录或页面进入后台时清除详情,返回页面重新请求和验证权限。 - 关闭共享后旧链接不再能从接口读取;已经阅读、截图或自行保存的内容不能远程撤回。 本次分享功能不新增表、字段或环境变量,沿用已部署的器械评价字段。