petstore-docs/架构决策-真实预约容量模型-2026-08-01.md
2026-08-01 22:56:31 +08:00

36 lines
2.3 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 架构决策:真实预约容量模型
日期2026-08-01
状态Accepted
范围:单店 SaaS 真实试点
## 决策
1. 服务项目配置 `duration_minutes`,范围 30480 分钟且按 30 分钟递增。
2. 预约保存 `duration_minutes` 快照,后续修改服务项目不会改变已承诺号源。
3. 门店配置 `booking_capacity`110表示同一半小时容量桶可并行服务的顾客数。
4. 可约性必须检查服务从开始到结束覆盖的每个半小时桶;有效预约和 `walk_in` 各消耗一个名额,`blocked` 关闭覆盖范围内全部名额。
5. 创建预约或手动占用时,对门店行使用悲观写锁,在同一事务内重新读取占用并判定,避免两个并发请求同时通过可用性检查。
6. `booking_last_slot_start` 保留兼容语义:它是最后一个 30 分钟容量桶的开始时间,营业容量结束时刻为其后 30 分钟;服务必须在结束时刻前完成。
## 为什么先做门店容量
现有预约在开始服务时才绑定 `assigned_user_id`,宠主下单也不选择技师。在这种数据结构下宣称已经具备“技师排班”会制造假精度。试点阶段先由老板配置门店可真实兑现的并发接待数,足以阻止长服务跨档冲突和同店并发超卖。
个人技师日历延后到预约前可分配技师、员工可维护可工作时段、服务项目可声明技师技能之后再引入。届时门店容量仍作为总上限,不会推翻本决策。
## 兼容与迁移
- 旧接口未传 `serviceType` 查询号源时采用 60 分钟安全默认值;创建预约必须解析到本店有效服务项目。
- 历史系统默认与预约按稳定名称映射回填:洗澡 60、美容 120、洗澡+美容 150、剪指甲/驱虫 30未知服务 60 分钟。
- 旧手动占用回填为 30 分钟;旧门店并发接待数回填为 1。
- 生产不自动执行迁移,发布前按 `backend/db/migrations/README.md` 备份、测试和人工执行。
## 验收
- 120 分钟服务会占用连续四个半小时桶。
- 容量为 2 时,同一桶允许两个有效占用,第三个被拒绝。
- `walk_in` 消耗一个名额;`blocked` 覆盖处全部不可约。
- 候选服务结束晚于营业容量结束时刻时不可约。
- 并发创建不会突破门店容量。