DB Redesign 需求分析(场景清单 + 查询清单)
6 阶段设计流程(需求分析 → 概念设计 → 选型 → 逻辑设计 → 物理设计 → 实现调优)的第 1 阶段产出。来源:2026-07-02 会议 transcript、
entity-relationship-map.md/why-tenant.md/v1-gaps.md、studio-api 代码实扫(apps/api 全部读路径)、test 库实测量级。 状态:DRAFT — 待 Max/Peter 确认频率与补充遗漏场景;§C 的 4 个问题正在用 brainstorming 流程逐个敲定。
A0. 能力需求总表(需求的锚点:一套系统的两个面)
retaintive 是一套系统的两个面,谁也不能缺:
- Revenue 引擎(帮客户从电话/lead 里找到钱):信号进入 → AI 理解 → 派任务 → 执行 → 度量 → 变现放大
- 管理面(我们经营这套 SaaS):onboarding → 身份权限 → 计费套餐 → 客户生命周期 → 内部运营 → 合规
两面咬合:Revenue 引擎的每行数据都 stamp 着管理面定义的边界(tenant / store / person);管理面的每次变更(挪店、转让、churn)都不许弄脏引擎的历史。数据地基必须同时撑住两面——只修管理面是为架构而架构,只做引擎功能就是回到现在这个状态。
判定口径:✅ 骨架已撑住(只差机制收口)/ ⚠️ 方向对但缺前置 / ❌ 模型缺概念。
Revenue 引擎(R 侧)
管理面(M 侧)
判定汇总:骨架合理,五个概念级的洞
tenant/store/事件表三层骨架不用推倒。但 5 个"模型缺概念"的洞,不补则上表一半撑不住:
不用现在还的债(有触发条件,提前做是浪费):v2/v3 双平面合并(跟 DDB 退役走)、rc_* 改名(Final)、DB placement(第一个 Silo 客户来时)。
场景 SoT 索引(已有的成体系场景库,不在本文重复)
A. 变更/完整性场景清单(A0 的证据层:会发生什么事)
A1. 店与电话拓扑(高危区,全部有实锤)
A2. 客户/租户生命周期
A3. 人员与权限
A4. 顾客(contact)生命周期
A5. 数据管道(写入侧场景)
A6. 平台化(future,设计时留口即可)
对外 API(per-tenant key + rate limit)、AI agent 介入(MCP)、3 方 CPaaS、BPO 转售、Pool/Silo 搬家 —— 均以 tenant_id 为锚,见 why-tenant §十一。
B. 查询清单(workload inventory,来自 apps/api 代码实扫)
B1. 隔离键机制(现状)
- 三层中间件:auth(Cognito JWT→userId)→ tenant-context(control-plane 查 user→tenant)→ store-guard(storeId 从请求参数提取,只校验归属,
TENANT_GUARD_ENFORCE=false时 fail-open) - 真正的授权兜底在每个 route 的
getStoreContext():rc_stores.user_id(owner)→ store_members(shared)→ 取 store_phones - 双数据平面:v2 路由读 DynamoDB(phone-keyed),v3 读 Neon(store_id-keyed)
B2. 主要读路径(按页面)
B3. 口径冲突(代码实扫发现,6 条)
- "intro booked" 三个源:summary 从 calls(outcome=success+revenue_impacting);multi-store/funnel 从 tasks(close_result='booked');lead-tracker 从 inbound calls
- lead funnel 三套实现:task-based / contacts-based / inbound-call-based —— 同名指标不同分母
- "leads 数"分裂:dashboard 从
contacts.lifecycle_stage='lead';pipeline incoming 从leads表(account 级)—— 永远对不上(= 会上 Vivian 报的问题的完整版) - store_id vs account_id 隔离混用:leads/lead-communications/contacts-profile 按 account_id,其余按 store_id;多处
store_id=$1 OR (store_id IS NULL AND account_id=$x)兜底 - v2(DDB/phone)vs v3(Neon/store_id)双平面,calls 数两边可能不一致
- staff 的 task 归属缺失:closed_by_staff_name 基本是 system/NULL,staff 绩效只能 call-based
B4. 写路径
写路径分两类,不能混成"全部 phone→store 反查":
C. 待 Max/Peter 回答(第 1 步收口条件)
- A1-A4 每个场景的频率/重要性确认;有没有漏的场景?
- 指标口径的业务定义(这是需求不是实现):"intro booked" 以哪个源为准?lead funnel 以哪套分母为准?—— 定一次,全站遵守
- S12(评估型访问)要不要支持?这决定 tenant 模型要不要 guest 概念
- S19:SMS 自动触达现在开了吗?(决定 DNC person 层的优先级)
下一步(第 2 步预告)
场景清单收口后 → 从场景提炼 entity 表(名词 + 关系 + 会不会变),对齐 5 个 open decisions(D1-D5),产出目标概念模型。参考:entity-relationship-map.md(现状 + D1-D5)+ codex 审计(目标方向,.claude/specs/2026-07-02-codex-table-relationship-audit.md)+ postgres skill schema-design reference(第 3 步用)。