petstore-docs/架构决策-身份字段拆分-2026-08-01.md

2.9 KiB
Raw Blame History

架构决策:预约与报告身份字段拆分

日期2026-08-01

状态:已采纳,兼容迁移期

范围Backend Core、Report Media Backend、Store Miniapp、Store Admin

1. 决策背景

RC1 之前,Appointment.user_id 同时被解释为客户或创建人;门店代客预约会把操作员工写入该字段。Report.user_id 实际保存技师/报告提交人,但宠主报告列表又曾把它当客户归属。两处语义冲突会污染客户档案、报告可见性、回访归因和后续经营指标。

2. 冻结语义

聚合 字段 语义
Appointment customer_user_id 被服务的客户账号
Appointment created_by_user_id 实际创建预约的登录账号,可为 customer/boss/staff
Appointment assigned_user_id 服务技师API 新增语义别名 assignedStaffId
Appointment user_id legacy 兼容字段;新数据镜像 customer_user_id
Report customer_user_id 报告归属客户,从 Appointment 派生
Report author_staff_id 实际提交报告的门店账号
Report user_id legacy 兼容字段;新数据镜像 author_staff_id
Report staff_name 服务技师姓名快照,优先取 Appointment.assigned_user_id

“服务技师”和“报告作者”允许不同:老板可代员工提交报告,但报告仍展示实际服务技师。

3. 写入规则

宠主自行预约

  • customerUserId = current.userId
  • createdByUserId = current.userId
  • 忽略请求体中的身份字段

门店代客预约

  • createdByUserId = current.userId
  • 必须提交 customerUserIdcustomerPhone
  • 手机号不存在时创建 customer 账号;若手机号已绑定 boss/staff则拒绝静默复用
  • petId 存在时必须属于解析出的客户

提交报告

  • authorStaffId = current.userId
  • customerUserId = appointment.customerUserId
  • 服务技师继续来自 appointment.assignedUserId

4. 历史回填

迁移脚本:backend/db/migrations/20260801_split_service_identity.sql

预约客户按以下证据顺序回填:

  1. pet.owner_user_id
  2. legacy user_id 且对应账号角色为 customer
  3. 无可靠证据则保持空值,进入人工修正清单

报告客户只从关联预约回填;report.user_id 仅用于回填 author_staff_id,禁止当作客户。

5. 兼容与退出条件

  • 兼容期继续读写 legacy userId / assignedUserId,同时输出 canonical 字段。
  • 客户预约查询优先 customer_user_id,字段为空时回退 legacy user_id
  • 客户报告查询通过 report.customer_user_id 或关联预约归属,不再按 report.user_id 查询。
  • 只有在生产回填完成、旧客户端退出、关键指标稳定后,才可另立迁移删除 legacy 字段。

6. 非目标

本决策不引入多角色账号、跨店客户共享、StoreCustomer 主档、订单/支付或多门店组织;这些保持在后续独立阶段。