22 KiB
22 KiB
宠小它 — P0 研发落地清单
本体对齐:任务条目引用
ontology/中的实体/规则 ID(如entity:report、rule:BR-RPT-002)。冲突以本体为准。用途:发给研发拆任务与验收;仅含 P0(本期质量与主线闭环必需,不含 P1/P2 增强)。
依据:《产品全方位优化说明 v1》《本期主线》《宠主端预约体验优化》《产品设计文档》及当前仓库实现粗对齐。
更新:2026-07-05(P0 稳定化轮次:冻结本期范围,重新标记状态并绑定 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→doing、new→cancel、doing→done、doing→cancel(与产品最终规则一致);非法迁移返回 4xx + 明确业务码(如 INVALID_STATUS、CANCEL_NOT_ALLOWED) |
Backend Core | 🟡 部分实现:AppointmentService.updateStatus/startService 已集中校验,但缺自动化测试 |
mvn -f backend/pom.xml test(待补 AppointmentServiceTest) |
与「谁点谁服务」一致;Batch D 补测试 |
| A2 | 开始服务仅当 status=new |
startService 非 new 时拒绝,勿静默改库 |
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/D,含 ReportServiceTest/ReportControllerTest) |
mvn -f backend/pom.xml test |
对应 P0-3;上线前需清理重复数据 |
| A7 | 报告前后照片必填后端兜底 | 缺 before 返回 BEFORE_PHOTO_REQUIRED;缺 after 返回 AFTER_PHOTO_REQUIRED |
Report Media Backend | ✅ 已实现(Batch B,含 ReportControllerTest) |
mvn -f backend/pom.xml test |
与前端 B5 同步落地 |
| A8 | 统一鉴权上下文:HMAC session token + CurrentUserContext,protected API 不再信任请求里的身份字段 |
未登录返回 401;A 店用户访问 B 店预约/报告/线索返回 403;customer 不能用任意 userId 创建他人宠物/预约 |
System Architect / Backend Core | ✅ 已实现(Batch C,含 SessionTokenServiceTest) |
mvn -f backend/pom.xml test + 跨店/跨用户接口验证 |
对应 P0-1;不引入完整 Spring Security |
| A9 | 线索脱敏:/report/leads 默认不返回完整 wechatOpenid/wechatUnionid |
回包只有 wechatBound、wechatOpenidMasked、wechatUnionidMasked |
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 | 最小测试基线:补 SessionTokenServiceTest、ReportServiceTest、ReportControllerTest、AppointmentServiceTest |
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;既有事件不改写 |
| A20 | FollowUpTask 回访状态机与真实再次预约归因 | 留资与操作任务拆分;领取人独占处理;未接通/稍后联系可改期;终态不可回退;退订取消开放任务;只有真实预约保存成功才能记 rebooked/rebook_created;跨店 404,事件/审计低敏 |
Backend Core / Store Admin FE / Data Model | ✅ 代码完成(待生产迁移与三角色验收) | backend 全测 + admin build + 本体漂移审计 | 迁移见 backend/db/migrations/20260802_create_follow_up_task.sql;ReportLead.remind_status 仅兼容投影 |
B. 小程序 — 门店端(老板/员工)
| ID | 需求 | 验收标准 | Owner | 状态 | 验收命令 | 备注 |
|---|---|---|---|---|---|---|
| B1 | 「已完成」Tab 列表默认不含已取消 | Tab「已完成」下默认仅展示 status===done;cancel 通过次级筛选或单独子 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 登录态打开公开报告页仍显示留资/预约 CTA;boss/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 / success 与 ReportHighlightBlock 一致;失败展示归类中文,不暴露堆栈 |
Customer Experience FE | 🟡 部分实现:需对照三态文案 | 手工 smoke | H5 与小程序报告页行为一致 |
| D3 | 弱网 / 失败重试 | 报告主接口失败:按钮「重新加载」;超时阈值 8~10s 后出失败态 | 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/hash;H5/小程序均上报 | Report Share QA / Backend Ops | ✅ 已落 BusinessEvent 并进入工作台去重统计(待生产迁移) | BusinessEventServiceTest + admin build |
对应 P0-10、P1-4 |
| E3 | 埋点事件 schema(最小集) | 定义 report_opened、report_reopened、highlight_succeeded、highlight_failed、video_play、video_save、lead_submitted 字段、来源、统计窗口 |
Report Share QA / Product Design | ✅ 已冻结;核心履约/打开/留资已落库,成片与客户端播放事件待接入 | 见《本期主线-下一步产品优化点》埋点 schema 表 | 对应 P1-4 |
F. 视觉与规范(工程债)
| ID | 需求 | 验收标准 | Owner | 状态 | 验收命令 | 备注 |
|---|---|---|---|---|---|---|
| F1 | 禁止业务页硬编码主色 | 主色/品牌浅底统一 var(--c-brand) 等;`rg "#16a34a |
#2db96d"业务 vue 内为 0(除global.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/31 项只读预检 + 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 |
建议排期顺序(供研发参考)
- A1~A3(后端状态机)— 防脏数据,优先合。
- B1(已完成 Tab)— 前端小改、用户感知强。
- B2、D1、D2、E1(传播与报告体验)— 主线门面。
- C1~C5(宠主)— 与登录/路由并行可排。
- E2、E3、F1、F2、G1 — 可并行或插空。
- A5~A12(后端边界、隐私、配置、上传、测试)— Batch B/C/D。
- H1~H3(发布 RC 门禁)— Batch D 收口。
P0 通过条件(最终门禁)
- 后端
mvn -f backend/pom.xml test有实际测试用例并通过(不再No tests to run)。 - 前端
npm --prefix frontend run build:h5与npm --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/report;customer 不能用任意
userId创建他人宠物/预约。 - 生产配置扫描不含真实 DB/微信密钥,最终 profile 为
ddl-auto=validate,CORS 仅允许显式生产 HTTPS 源;只读生产预检通过。 - 已按固定顺序完成身份、StoreCustomer、BusinessEvent、预约容量、报告发送、门店开通、客户时间线与 FollowUpTask 八个生产迁移,并归档备份与验证证据。
- liveness/readiness、只读 smoke 与 boss/staff/customer 三角色真实环境 smoke 通过;Gitea/GitLab 未受 Petstore 配置影响。
- 文档口径扫描:
rg "到店不排队|会员储值 \| 路线图 P0|宠主通过微信查看服务报告(v2)|无限制,随便选" docs无命中。
不在 P0(勿与本清单混排)
- 会员卡 / 储值 / 次卡 / 套餐(P1/P2)
- 宠主账号内历史报告汇总(P2)
- 报告 token 作废重发(中期,见 D3 决策)
- 多技师分成、排班深度联动
- 复杂数据看板、漏斗大屏
- 分包优化(可 P1)
评审后可将本页 ID 勾进看板;与专文冲突以迭代评审为准。