petstore-docs/P0-研发落地清单.md

22 KiB
Raw Blame History

宠小它 — P0 研发落地清单

本体对齐:任务条目引用 ontology/ 中的实体/规则 IDentity:reportrule:BR-RPT-002)。冲突以本体为准。

用途:发给研发拆任务与验收;仅含 P0(本期质量与主线闭环必需,不含 P1/P2 增强)。
依据:《产品全方位优化说明 v1》《本期主线》《宠主端预约体验优化》《产品设计文档》及当前仓库实现粗对齐。
更新2026-07-05P0 稳定化轮次:冻结本期范围,重新标记状态并绑定 Owner 与验收命令)

关联 产品全方位优化说明-v1 · 本期主线-下一步产品优化点 · 宠主端预约体验优化-产品说明 · 架构与产品评估报告-2026-07-05 · Cursor P0 Handoff


本期 P0 范围(冻结口径)

本期 P0 范围:

  • 门店端:预约列表、开始服务、填写报告、发送报告、回访池。
  • 宠主端:预约填单、公开报告页、下次服务提醒留资、报告打开基础埋点。
  • 报告能力:服务前/服务后照片、服务过程素材、短片生成与下载、分享链接/二维码/话术。

不进入 P0

  • 会员、储值、套餐、复杂 CRM。
  • 宠主账号内历史报告汇总。
  • 完整经营分析看板。
  • 即使已有预约容量模型,也没有排队/叫号与准点履约保证;对外仍不承诺「到店不排队」,统一文案为「在线选时段,到店更省心」。

状态标记说明

  • 已实现:仓库已实现且通过本次构建/验收命令。
  • 🟡 部分实现:主路径已落,但仍有 gap已列出需按验收命令闭环。
  • 未实现:本期必须补齐。
  • 🧪 待测试:实现可能已存在,但缺自动化测试或人工 smoke 证据。

优先级说明

  • P0:本迭代必须交付;阻塞对外口碑、数据脏读、合规提示缺失、或主线(传播/成片/留资)不可用。
  • 已部分实现的项:仍保留,以下方「验收标准」为准做 gap 关闭。

A. 后端Spring Boot

ID 需求 验收标准 Owner 状态 验收命令 备注
A1 预约状态机校验PUT /appointment/status(及任意改状态入口)禁止非法迁移 仅允许:new→doingnew→canceldoing→donedoing→cancel(与产品最终规则一致);非法迁移返回 4xx + 明确业务码(如 INVALID_STATUSCANCEL_NOT_ALLOWED Backend Core 🟡 部分实现:AppointmentService.updateStatus/startService 已集中校验,但缺自动化测试 mvn -f backend/pom.xml test(待补 AppointmentServiceTest 与「谁点谁服务」一致Batch D 补测试
A2 开始服务仅当 status=new startServicenew 时拒绝,勿静默改库 Backend Core 🟡 部分实现:服务层已校验,需补测试 同 A1 与 A1 同一套状态机
A3 取消预约校验:仅允许目标状态为 cancel 且前置状态符合产品规则 与 A1 同一套状态机;前端取消按钮仅 new 时展示则后端仍要防篡改 Backend Core 🟡 部分实现:状态机已收口,需补测试 同 A1 防恶意请求
A4 留资去重:同一 report_token + 同一手机号 二次提交返回成功态或「已提交」语义,不重复插库 Report Media Backend 🟡 部分实现:去重逻辑已存在,需补测试用例 mvn -f backend/pom.xml test(待补 ReportLeadControllerTest 口径见《本期主线》C
A5 公开报告字段裁剪GET /api/report/get?token= 不返回 top-level userId/storeId/reportToken;日志只记 token hash 公开 token 请求只返回页面必要字段store 对象可返回 id 用于预约跳转 System Architect / Report Media Backend 已实现Batch B 手工 curl + mvn test 对应 P0-2
A6 报告一约一份Report.appointment_id 唯一约束;服务层拒绝同预约重复提交 同一 appointmentId 第二次提交返回 409 / REPORT_ALREADY_EXISTS;非 doing 预约不能创建报告;无预约提交返回 APPOINTMENT_REQUIRED System Architect / Data Model / Report Media Backend 已实现Batch B/DReportServiceTest/ReportControllerTest mvn -f backend/pom.xml test 对应 P0-3上线前需清理重复数据
A7 报告前后照片必填后端兜底 缺 before 返回 BEFORE_PHOTO_REQUIRED;缺 after 返回 AFTER_PHOTO_REQUIRED Report Media Backend 已实现Batch BReportControllerTest mvn -f backend/pom.xml test 与前端 B5 同步落地
A8 统一鉴权上下文HMAC session token + CurrentUserContextprotected API 不再信任请求里的身份字段 未登录返回 401A 店用户访问 B 店预约/报告/线索返回 403customer 不能用任意 userId 创建他人宠物/预约 System Architect / Backend Core 已实现Batch CSessionTokenServiceTest mvn -f backend/pom.xml test + 跨店/跨用户接口验证 对应 P0-1不引入完整 Spring Security
A9 线索脱敏/report/leads 默认不返回完整 wechatOpenid/wechatUnionid 回包只有 wechatBoundwechatOpenidMaskedwechatUnionidMasked Report Media Backend 已实现Batch B 手工 curl + mvn test 对应 P0-2
A10 配置安全与启动迁移收口application.yml 不保留真实敏感值;生产 profile 禁用 ddl-auto:update/show-sql、万能验证码和宽 CORS生产启动不写默认业务数据 仓库不含真实 DB/微信密钥;最终配置不安全时启动失败;有 liveness/readiness、只读 schema/数据预检和上线 smoke Backend Ops / System Architect 代码与脚本已实现;待真实环境留证 mvn test + deploy/release-preflight.sh + deploy/production-smoke.sh 对应 P0-8生产域名/凭据/迁移/线上 smoke 归 H3已暴露凭据需轮换
A11 上传路径与类型保护FileController 归一化路径 + 扩展名/MIME 校验 /api/upload/image/../...、伪装扩展名、超大文件均被拒绝 Backend Core / System Architect 已实现Batch D 手工 curl + mvn test 对应 P0-9
A12 最小测试基线:补 SessionTokenServiceTestReportServiceTestReportControllerTestAppointmentServiceTest mvn test 不再输出 No tests to run,新增用例全部通过 Core Flow QA / System Architect 已实现Batch D mvn -f backend/pom.xml test 对应 P0-10持续回归数量以 Surefire 当次统计为准
A13 预约/报告身份语义拆分:客户、创建人、服务技师、报告作者不得复用同一语义字段 customer 自约身份从 session 派生门店代约必须提供真实宠主宠主报告按预约客户归属查询legacy 字段只做兼容 System Architect / Backend Core / Report Media Backend 已实现Phase 0 RC1 后) mvn -f backend/pom.xml test + H5/小程序构建 迁移见 backend/db/migrations/20260801_split_service_identity.sql
A14 StoreCustomer 门店客户主档:客户列表不再临时拼成无 ID 投影 预约/留资自动建档同店账号与手机号唯一API 返回 storeCustomerId 且手机脱敏;历史数据可回填 Backend Core / Report Media Backend / Data Model 已实现(待生产迁移) mvn -f backend/pom.xml test + npm --prefix admin run build 迁移见 backend/db/migrations/20260801_create_store_customer.sql
A15 BusinessEvent 业务事件落库:经营漏斗不再依赖日志或前端猜测 首批 7 类事实统一落库稳定事件幂等metadata 不含 token/手机号/IP工作台已打开可统计历史可靠事实可回填 Backend Core / Report Media Backend / Data Model 已实现(待生产迁移) mvn -f backend/pom.xml test + npm --prefix admin run build + 本体漂移审计 迁移见 backend/db/migrations/20260801_create_business_event.sql
A16 真实预约容量与连续排班占用:服务时长、门店并发容量和预约时长快照共同决定号源 长服务跨半小时桶占号;walk_in 消耗一份容量,blocked 关闭全部;并发创建不超卖 Backend Core / Store Admin FE / Data Model 已实现(待生产迁移) backend 全测 + admin/H5/小程序构建 + 本体漂移审计 迁移见 backend/db/migrations/20260801_create_booking_capacity.sql;不等同排队/准点承诺
A17 报告显式确认发送状态:传播动作与发送事实分离 历史为 unknown;新报告为 unsent;首次确认写不可覆盖回执与幂等 report_sent;工作台仅提醒新报告待发送 Report Media Backend / Store Miniapp FE / Store Admin FE / Data Model 已实现(待生产迁移) backend 全测 + admin/H5/小程序构建 + 本体漂移审计 迁移见 backend/db/migrations/20260801_create_report_send_status.sql;不宣称微信投递成功
A18 门店开通 + 一次性员工邀请 + AuditLog 老板入驻须微信核验;历史开通状态 unknown完成清单需资料/容量/服务;邀请 token 只显一次且库内仅 hash手机号微信核验、限时/一次/可撤销;删员工立即失效旧会话 Backend Core / Store Miniapp FE / Store Admin FE / Data Model 代码完成(待生产迁移与微信真机验收) backend 全测 + admin/H5/小程序构建 + 本体漂移审计 迁移见 backend/db/migrations/20260802_create_store_onboarding.sql;单角色账号冲突明确拒绝
A19 StoreCustomer 事实时间线:客户详情不再只显示当前聚合快照 以 canonical storeCustomerId 同店校验BusinessEvent 按发生时间稳定分页;合并前别名事件不断档;预约/报告/回访提供低敏摘要和跳转不返回手机号原文、备注、媒体、token 或原始 metadata Backend Core / Store Admin FE 代码完成(待生产迁移) backend 全测 + admin build + 本体漂移审计 迁移见 backend/db/migrations/20260802_create_store_customer_timeline.sql;既有事件不改写

B. 小程序 — 门店端(老板/员工)

ID 需求 验收标准 Owner 状态 验收命令 备注
B1 「已完成」Tab 列表默认不含已取消 Tab「已完成」下默认仅展示 status===donecancel 通过次级筛选或单独子 TAB 实现 Store Miniapp FE 🟡 部分实现(以现状为准做回归) npm --prefix frontend run build:h5 + 手工 smoke 当前 Home.vue 需对照
B2 发送报告成功页:同屏 报告链接 + 二维码 + 两条可复制话术 + 显式确认发送 话术支持变量;复制/预览不自动确认;宠主实际收到后选择微信/扫码/其他并确认 Store Miniapp FE 已实现(ReportShareModal.vue npm --prefix frontend run build:h5 + 手工 smoke 对齐 A17不得把剪贴板动作冒充发送
B3 报告提交锁死提示 提交前弹窗固定文案:「提交后不可修改,请确认照片与备注无误」 Store Miniapp FE 🟡 部分实现:核对文案与位置 手工 smoke 与产品 v1 锁死策略一致
B4 「我的」老板端分组标题 至少两组:店铺与经营 / 团队与账号;高频在上;使用 .module-title Store Miniapp FE 已实现 npm --prefix frontend run build:h5 + 手工 smoke 见《产品全方位优化说明》§2.2
B5 报告前后照片必填前端校验 无 before 提示「请至少上传1张服务前照片」无 after 提示「请至少上传1张服务后照片」 Store Miniapp FE / Customer Experience FE 已实现Batch A npm --prefix frontend run build:h5 + npm --prefix frontend run build:mp-weixin 对应 A7、P0-4
B6 小程序开通向导与员工邀请卡片 老板可查看/完成开通清单;创建邀请后原始口令只显示一次,可直接 open-type=share 转发;员工预览脱敏信息并经微信手机号核验加入 Store Miniapp FE / Backend Core 代码完成,待微信真机 smoke H5 + mp-weixin 构建;老板/员工双微信真机验收 H5 只预览,不绕过微信核验

C. 小程序 — 宠主端customer

ID 需求 验收标准 Owner 状态 验收命令 备注
C1 单一主预约路径 首屏仅保留一个主级「预约服务」入口;不再同屏强并存「大按钮 + 空态大按钮 + FAB +」等效重复 Customer Experience FE 🟡 部分实现:需对照当前 Home.vue 复核 手工 smoke 见《宠主端预约体验优化》§9
C2 扫码 / 分享落地 storeId(含小程序码 scene 解码) 普通 storeId query、小程序码 scene=storeId%3D1、分享 path/query 均预填门店且可「更换门店」 Customer Experience FE 已实现Batch A npm --prefix frontend run build:h5 + npm --prefix frontend run build:mp-weixin + 手工 smoke 对应 P0-6、P1-1
C3 登录时机与草稿(冻结策略:提交时登录 + guest 草稿恢复) 未登录可填单,提交时跳登录,登录后草稿恢复;草稿 key 不依赖 userInfo.id;不会产生 userId: undefined Customer Experience FE / Backend Core 已实现Batch A 手工 smoke未登录填写 → 提交跳登录 → 草稿恢复 Login.vue redirect 联动
C4 异常可理解 无可用时段、网络失败、未登录:均有 toast / 空态 / 重试,禁止静默失败 Customer Experience FE 🟡 部分实现:需逐场景回归 手工 smoke 专文 §7
C5 报告页角色判断isStaff 改为角色判断boss/staff customer 登录态打开公开报告页仍显示留资/预约 CTAboss/staff 才显示内部分享/保存 Customer Experience FE 已实现Batch A 手工 smoke 对应 P0-7

D. H5 报告页(report-view / 独立 H5

ID 需求 验收标准 Owner 状态 验收命令 备注
D1 隐私提示(短期策略) 首屏或固定条:「本页含宠物服务影像,请勿公开转发或发群」 Customer Experience FE / Product Design 🟡 部分实现:核对文案与位置 手工 smoke 对齐《本期主线》A token 风险
D2 短片三态与文案对齐小程序 processing / failed / successReportHighlightBlock 一致;失败展示归类中文,不暴露堆栈 Customer Experience FE 🟡 部分实现:需对照三态文案 手工 smoke H5 与小程序报告页行为一致
D3 弱网 / 失败重试 报告主接口失败:按钮「重新加载」;超时阈值 810s 后出失败态 Customer Experience FE 🟡 部分实现 手工 smoke 与《产品全方位优化说明》§3.3
D4 公开报告 token 使用方式:不依赖回包 reportToken,只用路由 token 做留资/分享 公开报告页 reminderToken = 路由 token不读 reportData.reportToken Customer Experience FE 已实现Batch A 手工 smoke + 代码审查 与 A5 联动

E. 传播与埋点P0 最小集)

ID 需求 验收标准 Owner 状态 验收命令 备注
E1 分享卡片元信息规则 小程序 onShareAppMessage:标题「宠物名 + 服务 + 门店」;封面优先级 成片封面 > 服务后首图 > Logo Customer Experience FE 已实现(reportShare.js 手工 smoke + 代码审查 frontend/src/utils/reportShare.js
E2 埋点:报告打开 前端提交 token 定位报告;事件表仅存 report ID、首次/再次和时间,不存 token/hashH5/小程序均上报 Report Share QA / Backend Ops 已落 BusinessEvent 并进入工作台去重统计(待生产迁移) BusinessEventServiceTest + admin build 对应 P0-10、P1-4
E3 埋点事件 schema(最小集) 定义 report_openedreport_reopenedhighlight_succeededhighlight_failedvideo_playvideo_savelead_submitted 字段、来源、统计窗口 Report Share QA / Product Design 已冻结;核心履约/打开/留资已落库,成片与客户端播放事件待接入 见《本期主线-下一步产品优化点》埋点 schema 表 对应 P1-4

F. 视觉与规范(工程债)

ID 需求 验收标准 Owner 状态 验收命令 备注
F1 禁止业务页硬编码主色 主色/品牌浅底统一 var(--c-brand) 等;`rg "#16a34a #2db96d"业务 vue 内为 0global.css`/极少量渐变定义) Store Miniapp FE / Customer Experience FE 🟡 部分实现 `rg "#16a34a
F2 空态禁用 emoji 作主视觉 宠主空态等用 AppIcon 或插图占位,不用 📋 等作为主视觉 Customer Experience FE 🟡 部分实现 代码审查 Home.vue 空态 slot

G. 文案与对外承诺(配置级)

ID 需求 验收标准 Owner 状态 验收命令 备注
G1 无排队/叫号能力不承诺「不排队」 全局检索「排队」「不排队」;宠主副标题等改为「在线选时段,到店更省心」 Product Design / Customer Experience FE 已实现Batch A 文档冻结,容量模型上线后仍成立) `rg "到店不排队 不排队" docs frontend/src`
G2 对内录单表述(可选) 门店端新建预约入口文案是否改为「代客预约」由产品拍板;若改则全局统一 Product Design 🟡 待产品拍板 降低「预约」歧义

H. 发布 RC 门禁Batch D 收口)

ID 需求 验收标准 Owner 状态 验收命令 备注
H1 后端可重复发布门禁 README + production profile + 配置校验 + schema/26 项只读预检 + liveness/readiness + 只读 smoke + systemd/Nginx 模板 Backend Ops 仓库能力已实现;待真实环境执行 backend 全测/打包 + bash -n deploy/*.sh + Runbook 不把模板/本地通过写成已上线
H2 前端可重复发布门禁 admin/H5/小程序真实域名配置先门禁再构建;仓库占位值不能进入正式包;微信合法域名、体验版、静态回滚路径明确 Frontend Release Ops 仓库能力已实现;待真实环境执行 admin/frontend preflight + 三端构建 + Runbook 真实配置不得提交
H3 P0 通过条件 见下方「P0 通过条件」块 System Architect / Core Flow QA 🟡 待人工 smoke 复核 见下方 对应 P0-10

建议排期顺序(供研发参考)

  1. A1A3(后端状态机)— 防脏数据,优先合。
  2. B1(已完成 Tab— 前端小改、用户感知强。
  3. B2、D1、D2、E1(传播与报告体验)— 主线门面。
  4. C1C5(宠主)— 与登录/路由并行可排。
  5. E2、E3、F1、F2、G1 — 可并行或插空。
  6. A5A12(后端边界、隐私、配置、上传、测试)— Batch B/C/D。
  7. H1H3(发布 RC 门禁)— Batch D 收口。

P0 通过条件(最终门禁)

  • 后端 mvn -f backend/pom.xml test 有实际测试用例并通过(不再 No tests to run)。
  • 前端 npm --prefix frontend run build:h5npm --prefix frontend run build:mp-weixin 均通过。
  • 公开报告页 token 匿名可打开,且不返回 top-level userId/storeId/reportToken
  • boss/staff 登录后可生成报告、发送报告、查看回访池。
  • customer 登录态打开报告仍显示留资和预约 CTA。
  • 同一 appointmentId 第二次提交报告返回 REPORT_ALREADY_EXISTS
  • 报告前后照片缺失返回对应业务码。
  • A 店 boss/staff 不能查 B 店 leads/list/reportcustomer 不能用任意 userId 创建他人宠物/预约。
  • 生产配置扫描不含真实 DB/微信密钥,最终 profile 为 ddl-auto=validateCORS 仅允许显式生产 HTTPS 源;只读生产预检通过。
  • 已按顺序完成身份、StoreCustomer、BusinessEvent、预约容量四个生产迁移并归档备份与验证证据。
  • liveness/readiness、只读 smoke 与 boss/staff/customer 三角色真实环境 smoke 通过Gitea/GitLab 未受 Petstore 配置影响。
  • 文档口径扫描:rg "到店不排队|会员储值 \| 路线图 P0|宠主通过微信查看服务报告v2|无限制,随便选" docs 无命中。

不在 P0勿与本清单混排

  • 会员卡 / 储值 / 次卡 / 套餐P1/P2
  • 宠主账号内历史报告汇总P2
  • 报告 token 作废重发(中期,见 D3 决策)
  • 多技师分成、排班深度联动
  • 复杂数据看板、漏斗大屏
  • 分包优化(可 P1

评审后可将本页 ID 勾进看板;与专文冲突以迭代评审为准。