PP-03 凭据泄露处置: - 清除 wiki + 2 份历史文档中的 Redis 明文密码与公网 IP(4 文件 5 处) - wiki 新增安全告警 + 症状导航条目 - 核实降级:泄露旧密码已失效,HMS 连本地 Redis,云端闲置;公网已关闭 系统深度分析(9 维度 + 6 主题多专家组): - docs/discussions/2026-06-25-analysis/ 新增 7 文件 - 综合 6.8/10,4 CRITICAL,TOP 12 痛点,4 阶段路线图 wiki 关键数字校正(PP-02/05a fix 触发): - 迁移数 175→176(m20260626_000170) - 症状导航新增 device_readings 分区硬截止 + claim_next 注入修复条目
23 KiB
主题 06 — 商业增长与 SaaS 规模化
日期: 2026-06-25 | 分支: feat/media-library-banner | 阶段: V1 上线后 6-12 个月演进 专家: SaaS 产品经理 / 商业化架构师 / 增长专家 证据基准: 代码核实(非臆测),所有论断标注文件路径:行号
一、主题愿景
把 HMS 从「单租户项目交付」转变为「按价值计费、配置化开通、数据飞轮驱动续约」的可规模化 SaaS,核心抓手是把现有但分散的半成品(ai_usage/ai_tenant_config 配额引擎、points_* 6 表、EventBus+Outbox、AnalysisQueue)缝合为三根商业主线:统一计量计费中枢(每多一个租户的实施成本从 3-5 人天降到小时级)、配置化交付蓝图(场景模板化,让交付从写代码变成配 JSON)、主动关怀+行为经济飞轮(把 AI 队列和积分系统从被动记录变成无人值守的留存与续约引擎)。SaaS 定价模型一旦随首批医疗客户固化(合同周期长、改价难),后续调整成本极高,必须在签第 2-5 个客户前确立计量与分层的数据基础,否则会陷入「每个客户一份定制合同」的项目制泥潭——这正是从交付到 SaaS 失败的典型路径。
关键判断(与决策简报 00-INDEX.md 对齐):本主题不阻塞 V1 上线(Phase 0 拆炸弹优先),但所有举措建立在 PP-01 死信接线 + PP-05 队列消费者 + PP-07 RLS FORCE + PP-02 分区自愈这四个 CRITICAL 前置修复完成之后。商业化是上线后 6-12 个月的事,但计量埋点与 entitlement 抽象必须提前到 Phase 1,否则后期改造代价数倍。
二、专家提案摘要与核实
已核实的事实(alreadyKnown=true,作为商业化基础设施的真实存在)
| 资产 | 位置 | 现状(核实) | 商业化含义 |
|---|---|---|---|
| AI 配额引擎 | crates/erp-ai/src/service/quota.rs:7-134 |
仅 token 单维度,仅「超限拒绝」(L41-49),无账单出口 | 可泛化为多维度计量 |
| AI 日聚合 | crates/erp-ai/src/service/usage.rs:110-158 aggregate_daily |
按分析类型聚合到 ai_usage_daily,仅 AI |
rollup 模式可复用到全模块 |
| 积分 6 表 + CAS | points_service/account.rs:82 earn_points + event.rs |
4 个 earn 触发点(checkin/follow_up/care_plan/offline_event),FIFO 消费+CAS 防超卖 | 积分商城已 78% 核销基础设施,差人民币 leg |
| 积分过期 | event.rs:772-875 expire_points |
已实现 12 个月过期清理 + POINTS_EXPIRED 事件 |
decay 机制已存在,增长专家「需加通胀设计」可调参数 |
tenant.settings JSON |
migration/m20260410_000001:28 |
空可空 JSON 列 | branding_json 零迁移可承载白标 |
| 小程序主题 token | apps/miniprogram/src/styles/tokens.scss + token-values.ts |
11 级字号 + 结构 token + .doctor-mode/.elder-mode 覆盖 |
白标皮肤沉没成本已就绪,边际成本极低 |
| EventBus + Outbox | crates/erp-core/src/events.rs |
31 health 事件/82 发布点/15 消费者 | 计量 consumer 可挂载,零新增基础设施 |
retry_dead_letters |
events.rs:382 |
函数存在但 tasks.rs 未注册调度(PP-01) |
计量 consumer 必须先于死信修复,否则计量丢失无察觉 |
增量缺口(alreadyKnown=false,本主题真正要建的)
claim_next(analysis_queue.rs:92)无生产消费方——auto_analysis.rs:108只 enqueue(每 24h),从不消费队列;PP-05 确认。- 无
tenant_usage_ledger/metering_daily/tenant_quota/tenant_plan/tenant_blueprint/tenant_entitlements表——全仓 grep 零命中。 - 无
AppError::PaymentRequired/402 映射——error.rs:17-39仅 8 变体(NotFound/Validation/Unauthorized/Forbidden/Conflict/VersionConflict/RateLimit/Internal)。 - 无
EntitlementCheckertrait /quota_guard中间件 /entitlement_middleware。 - 无
start_usage_rollup/start_auto_analysis_worker调度(tasks.rs只有 event_cleanup + pool_metrics)。
三、战略举措(5 项,归并 3 专家 14 提案)
举措 1 — 统一计量计费中枢(Metering Hub)
归并: SaaS-PMP1 + 商业架构M1 + M2(配额即产品)。把 ai_usage/ai_tenant_config 与 points_* 升级为跨模块事件驱动计量 + 套餐配额矩阵。
rationale: 现有计量是两座孤岛——AI 只统计 token(quota.rs:41),积分商城无人民币核销闭环。不统一计量就无法对 AI/告警/咨询/FHIR 调用定价,AI 越主动成本越不可控(商业反模式)。
phases:
- P1(埋点,1-2w): 新增
metering_daily(tenant_id, metric_key, day, qty, dim_hash, unique 索引)表,用ON CONFLICT DO UPDATE原子累加;在usage.rs、points_service/event.rs、device_reading_service、consultation_service、fhir handler 挂Meter::record()写入。独立连接池避免 PP-08 RLS 串扰。 - P2(配额中间件,2-3w): 新增
AppError::PaymentRequired变体(402);抽象quota_guard中间件(类似require_permission),计费端点声明dimension;预置 3 套餐 seed(基础/专业/旗舰)到tenant_plan+tenant_quota表。 - P3(账单导出,1w):
GET /api/v1/admin/tenants/{id}/usage+/invoice?period=YYYY-MM返回 JSON+CSV。不接 Stripe(医疗 to B 公对公转账为主)。
effortEstimate: 4-6 周(1-2 后端 + 财务定义价格表后置)
expectedImpact: 打开按价值付费收入天花板;每个 AI 分析/告警/咨询/上传可计量可计费;为 P2 套餐分层提供数据基础。从「内部成本控制」反转为「商业化基础设施」。
kpis: 计量覆盖率(计费事件/总事件);月度账单生成准时率;配额误拦截事故数(目标 0);首 3 客户计量对账差异率(<1%)。
dependencies: PP-01 死信接线(计量 consumer 必须有重试兜底);PP-08 RLS 修复(独立池);财务/销售定义价格表(非技术决策);PP-02 分区自愈(device_active_count 计量依赖)。
关键取舍: 不引入 Stripe/Lago 等通用计费引擎(医疗账单维度强绑定业务事件,自建更贴合,省 2-3 周集成)。配额硬上限(hard_cap 402)必须为 critical_alert/article 推送设白名单,否则会阻断医疗业务——这是真实产品权衡,不是 bug。
举措 2 — 配置化交付蓝图(Tenant Blueprint + Onboarding)
归并: SaaS-PMP3 + 商业架构M4 + 增长专家配置化场景。把新租户开通从「跑迁移+手工 SQL」降到「点按钮」。
rationale: 现状菜单/权限/字典/告警阈值/随访模板/积分规则全靠 m0000xx_seed_*.rs 一次性写入,新租户要么继承默认要么手工 SQL——这是「项目交付而非 SaaS」的根因。体检中心连锁(20-50 门店)是 HMS 核心增长客群,交付周期是规模化第一瓶颈。
phases:
- P1(蓝图表,1-2w): 新增
tenant_blueprint(id, name, module_set, quota_plan_id, seed_data JSON, branding_json, schema_version)。把现有 seed 内容重构为按行业分类的 preset 数据包(general_hospital/dialysis_center/checkup_clinic)存config/presets/*.toml(数据非迁移,可版本化)。 - P2(provision 端点,2-3w):
POST /api/v1/admin/tenants/{id}/provision,事务化建 tenant→角色/权限/菜单→points_account→触发tenant.provisioned事件(补齐 §3.4「每个事件有消费者」铁律)。配套 CLIerp-server tenant create --blueprint=standard(顺便补 PP-11 subcommand 缺失)。 - P3(导出标杆,1w): 「导出当前租户配置为 preset」按钮,白名单字段 + PII 过滤(与 PP-12 同源),把标杆客户最佳实践沉淀为可复用模板。
effortEstimate: 4-5 周
expectedImpact: 实施周期从 3-5 人天降到小时级;第 N 个客户复用第 1 个客户的最佳实践配置;支撑体检连锁批量获客;让销售/实施可在签单当天开通试用(医疗采购「先试后买」决策周期)。
kpis: 新租户开通耗时(目标 <30 分钟,含验证);preset 复用率(新租户用 preset 而非手工 SQL 的比例);试点客户首月留存。
dependencies: PP-11 CD pipeline + 迁移独立子命令;preset schema_version + 增量 patch 机制(版本兼容);admin 审批流/邀请码(防刷租户消耗配额)。
举措 3 — 主动关怀 + 行为经济飞轮
归并: 增长专家 G1(AI 队列接通)+ G2(积分行为经济)+ G4(转介绍)。把半成品 AI 队列和积分系统从被动记录变成留存引擎。
rationale: claim_next 存在但无消费方(analysis_queue.rs:92),客户基于「主动关怀」付费但队列是死存储。积分仅 3-4 触发点无消费压力,是债务不是货币。医疗行业 CAC 高,但现有患者家属是天然高质量线索池。
phases:
- P1(队列消费者 MVP,2w):
tasks.rs新增start_auto_analysis_worker:tokio::spawn 循环调claim_next,按 tenant 并发拉取,失败走retry_dead_letters(同时修 PP-01)。worker 数与ai_tenant_config配额做令牌桶联动(避免单租户耗尽 Provider)。 - P2(三种触达,2-3w): 高风险患者→医护 action_inbox「建议介入」项;化验上传→患者 AI 解读 push;每日巡护→依从性下降患者关怀消息(复用
article_service.rs:228事件消费者模式)。每条触达带source=auto_analysis+ outcome 跟踪字段,回流增长看板。 - P3(积分行为经济,1-2w): 扩充 earn 订阅(BLE 上传 +X、连续达标 +bonus、健康评估 +Y、咨询评价 +Z,复用 DomainEvent 无需新表);积分消耗侧新增「健康权益兑换」(优先挂号/远程咨询时长/家属账号)而非仅商城商品;
points_rule加decay_policy调参(过期已实现,需运营定义通胀曲线)。 - P4(转介绍闭环,2w):
patient加referred_by_patient_id自引用 +referral_code;小程序「我的」生成小程序码;反作弊(同手机号/身份证仅一次被介绍,复用phone_hash盲索引)+ 首次就诊才发放(防刷);运营看板「转介绍漏斗」。
effortEstimate: 7-9 周(可分 P1→P4 串行,先有流水线再谈能力升级)
expectedImpact: 把「已付费但空转」的 AI 能力变成转介绍/续约引擎;患者依从性驱动数据密度;医疗转介绍产品化(合规边界内,奖励建档/健康行为而非就诊消费)。
kpis: AI 队列消费吞吐(pending 积压 <阈值);主动触达→就诊转化率;积分兑换深度(人均月兑换次数);转介绍建档数→就诊数漏斗;Top KOC 识别覆盖。
dependencies: PP-01 死信重试;PP-05 队列消费者(即本举措 P1);AI Provider 配额联动(chat_handler fallback chain);医务审核行为定义(防「诱导过度检查」合规);consent 拦截器(家属数据共享授权链路,已有)。
关键取舍: 增长专家主张 AI 队列接通优先级高于 PP-01/PP-02 等基础设施修复。调和:同一个 worker 同时承载 AI 消费和死信重试(都用 retry 机制不冲突),但顺序上 PP-01 仍是 Phase 0 阻塞项(计量 consumer 需要重试兜底,否则触达丢失无人察觉)。
举措 4 — 套餐分层与价值证明(Feature Gating + Health Score)
归并: SaaS-PMP2(Feature Gating)+ PMP4(ROI 仪表盘)+ 增长专家 G3(租户健康度看板)。把计量数据变成续约武器。
rationale: 常规 SaaS 只给客户看「使用量」;本举措做双视角——客户看自己 ROI(续约理由),平台看客户健康度(流失预警)。且不新搭数据仓库,全用现有 stats_service + usage_ledger 在线计算(刻意避免 BI 工具运维负担,匹配 DevOps 4.2 短板现实)。
phases:
- P1(EntitlementChecker,2w):
crates/erp-core定义EntitlementCheckertrait,各 handler 入口(紧邻require_permission)调require_feature("health.ai_copilot");集中entitlement_middleware按 route→feature 映射表统一拦截(防漏检=免费用户白嫖付费功能)。区分边界:permission 管「能不能做」(安全),entitlement 管「付费没付费」(商业)。 - P2(套餐定义,1w): 预置 3 套餐存
config/entitlements.toml(非迁移,便于调整);前端apps/web新增「套餐管理」页给 super-admin;小程序按 entitlements 动态显示/隐藏 AI 助手、深度报告入口。 - P3(健康度+ROI,2-3w):
stats_service新增tenant_health_score(五维度:活跃患者占比、AI 触达数、告警闭环率、随访完成率、医护日活);GET /api/v1/admin/tenants/{id}/health-score给 super-admin 流失预警;每租户 AdminDashboard 新增「我的 ROI」卡片。用现有stats_dto+ 4 Dashboard 组件基础设施。
effortEstimate: 5-7 周
expectedImpact: 防止免费能力裸奔(entitlement 漏检=收入损失);客户续约有量化依据;平台 NRR/流失预警从感觉变成可预警指标。
kpis: entitlement 检查覆盖率(计费端点/总端点);流失预警准确率(回测校准);续约率提升;客户 ROI 卡片使用率。
dependencies: PP-01 死信重试(「告警闭环率」指标依赖告警链路完整);运营/客户成功定义健康度权重(非技术拍板);跨租户聚合查询性能(物化视图或离线 rollup,与举措 1 共用调度)。
举措 5 — 生态扩展预留(白标皮肤 + 开放 API)
归并: SaaS-PMP5。为 6-12 个月后渠道分销(区域代理、体检连锁白标)铺路,低成本预留而非立即变现。
rationale: 小程序已投入做完整 CSS 变量主题体系(tokens.scss + token-values.ts,原为长者/医生模式服务),稍作扩展就是白标基础设施,把已沉没成本变成未来收入入口。
phases:
- P1(白标皮肤,1-2w,与安全解耦可并行先做): 抽象
tenant.branding_json(logo_url, primary_color, app_name, login_bg_url)存tenant.settings(零新表);Web 侧 Ant Design ConfigProvider runtime 切 theme token;小程序已有var(--tk-*)读取后动态注入 CSS 变量。 - P2(开放 API,3-4w,严格 gate 在安全修复后): 现有 14 FHIR 端点旁新增
GET /api/v1/open/patients等;tenant_api_keys表(scope 字段控制可访问资源);速率限制复用 rate_limit 中间件但独立配额;API 调用写入举措 1 的metering_daily(为「API 调用收费」埋点)。
effortEstimate: 4-6 周(P1 与 P2 可拆分,P1 不依赖安全修复)
expectedImpact: 渠道分销/白标能力预留;ISV 生态接入基础;API 调用计费埋点。
kpis: 白标皮肤落地租户数;开放 API 接入 ISV 数;API 调用计量覆盖率。
dependencies: P2 必须在 PP-03 Redis 凭据轮换 + PP-07 RLS FORCE + PP-08 连接池修复完成之后(开放 API 扩大攻击面);API Key 管理需吊销/轮换/审计(否则成为持续安全债务);白标需明确「皮肤级」vs「独立实例」边界(避免过度承诺触碰多租户架构边界)。
四、速赢(1-2 周可落地)
- 白标皮肤 P1(branding_json + 主题注入) —
tenant.settings已存在(m000001:28),小程序var(--tk-*)已就绪,Web ConfigProvider runtime 切换零新依赖。1-2 周可演示,与安全修复解耦可立即推进。把已沉没成本变成销售演示亮点。 - 计量埋点 P1(metering_daily 表 + 5 模块 Meter::record 挂载) — 复用
usage.rs:110aggregate_daily模式 + EventBus,独立连接池避免 RLS 串扰。2 周可让首批租户的 AI/上传/咨询/告警/FHIR 用量进入统一账本,为定价提供真实数据,无需等价格表。 - 积分 decay 参数化 + 行为事件订阅扩充 —
expire_points(event.rs:772)已实现,只需运营定义过期曲线 + 在event/points.rs加 BLE 上传/连续达标规则。1-2 周,零新表。
五、主题级风险
- 计量精度争议:漏计/重复计引发客户争议。需幂等 rollup(
period+metric_key唯一索引)+ 对账报表。device_active_count依赖 PP-02 分区先修好,否则 2026-09 起计量数据全断。 - 配额硬上限阻断医疗业务:
hard_cap402 若误配会拦截critical_alert/article推送等安全相关事件。必须设白名单不参与配额(这会让配额体系出现「holes」,是真实产品权衡)。 - preset 与 schema 漂移:preset
seed_dataJSON 与迁移 schema 版本漂移风险高,需schema_version+ 增量 patch + 启动校验。导出标杆配置可能含敏感数据(阈值/药品字典),需白名单 + PII 过滤。 - AI Provider 成本线性增长:主动关怀 worker 接通后,AI 成本随租户数线性增长,必须配额+降级(
chat_handlerfallback chain)+ 质量门禁(最小可读长度+引用校验,防 AI 输出空/think 块伤害患者体验)。 - 医疗转介绍合规红线:《医疗广告管理办法》禁止诱导就医,积分必须针对「健康行为」而非「就诊消费」——表述上避免「拉新返现」。HMS 已有
consent拦截器 +phone_hash盲索引是做合规转介绍的天然优势,但需医务审核行为定义。 - entitlement 漏检=收入损失:feature 检查点散落各 handler,漏检=免费用户白嫖付费功能。需集中中间件而非散落调用。
- 连接池分片过度设计争议:架构师会质疑
tenant_scoped_pool(按 tenant_id 分片)过度设计,主张SET LOCAL IN TRANSACTION。折中:仅 top-N 活跃租户分片,长尾走 SET LOCAL;但医疗场景间歇性跨租户泄漏哪怕 0.01% 是合规红线。 - 开放 API 安全债务:API Key 若无吊销/轮换/审计会成为持续安全债务,且必须 PP-03/07/08 修复后才能开放,否则放大攻击面。
六、调和专家分歧后的最终取舍
分歧 1:商业化 vs 基础设施修复的优先级
- SaaS-PMP/增长专家:主张计量/onboarding 优先,商业化倒逼测试投入。
- 测试/安全专家:主张 PP-10 测试 5.5、PP-01/02/07 等 P0 阻塞项必须先修,否则商业化是空中楼阁。
- 最终取舍:并行非串行。Phase 0(上线前 2 周)只做 4 CRITICAL 拆炸弹;Phase 1(1-3 月)计量埋点 + entitlement 抽象与测试门禁、可观测性并行推进。商业化(尤其计量埋点与 onboarding)确实能带来收入和客户压力倒逼投入,但 402 硬上限/配额中间件/开放 API 等「可阻断业务」的商业化能力严格 gate 在 PP-01/02/07/08 之后。埋点可先做(只读,无阻断风险)。
分歧 2:连接池分片 vs SET LOCAL
- 商业化架构师:主张
tenant_scoped_poolper-tenant 分片。 - 架构师:主张
SET LOCAL IN TRANSACTION即可。 - 最终取舍:折中方案——top-N 活跃租户分片 + 长尾 SET LOCAL。医疗场景跨租户泄漏是合规红线,分片工程成本可接受;但全量分片会显著增加 PG
max_connections压力,需 PgBouncer transaction pooling 前置。不追求一步到位。
分歧 3:积分通胀(decay)是否伤害体验
- 增长专家:主张积分 12 个月过期制造兑换压力。
- 产品/医疗专家:可能认为过期伤害用户体验。
- 最终取舍:保留 decay 但分层。基础积分(签到/上传)可较长过期或不过期;行为奖励积分(连续达标/转介绍)设较短过期(6-12 月)+ 高价值权益兑换(优先挂号/咨询时长)拉动兑换紧迫性。
expire_points已实现,调参即可。医疗合规上 decay 不得诱导「为积分过度检查」,需医务审核。
分歧 4:计量计费层是否独立为 erp-billing crate
- 架构师:会反驳计量污染业务模块边界,应独立 crate。
- SaaS-PMP:主张先在 erp-core 抽 trait + erp-server 轻量 rollup,避免过早引入新 crate(项目已 17 crate)。
- 最终取舍:先 trait 后 crate。Phase 1 在
erp-core定义EntitlementChecker/Metertrait +erp-server做 rollup 调度,验证商业模式后再视复杂度拆erp-billingcrate。不过早增加模块化复杂度。
分歧 5:开放 API 时机
- 安全专家:强烈反对 PP-03/07/08 未修复前推进开放 API。
- SaaS-PMP:主张 P5 第一步「白标皮肤」与安全风险解耦可并行先做。
- 最终取舍:拆分 P5。白标皮肤(branding_json)Phase 1 可立即推进(与安全无关);开放 API 严格 gate 在 PP-03 Redis 轮换 + PP-07 RLS FORCE + PP-08 连接池修复之后(Phase 2-3)。
核心立场(SaaS-PMP 提出且被采纳)
SaaS 定价模型一旦随首批医疗客户固化(合同周期长、改价难),后续调整成本极高。必须在签第 2-5 个客户前确立计量与分层的数据基础——这是从交付到 SaaS 成败的分水岭。因此计量埋点(举措 1 P1)+ entitlement 抽象(举措 4 P1)必须在首批客户签约前完成,即便 V1 尚未完全稳定。这是商业时间窗口驱动的,不是技术就绪度驱动的。
七、路线(与决策简报 00-INDEX.md 四阶段对齐)
| 阶段 | 时间 | 本主题交付 |
|---|---|---|
| Phase 0 | T-0 ~ T+2w | 不阻塞上线。仅可做白标皮肤 P1(branding_json)作销售演示。所有计费/onboarding 推迟。 |
| Phase 1 | T+1M ~ T+3M | 举措 1 P1-P2(计量埋点 + 配额中间件 + 账单导出);举措 3 P1-P2(队列消费者 MVP + 三种触达);举措 4 P1-P2(EntitlementChecker + 套餐定义);举措 2 P1(蓝图表)。与测试门禁/可观测性并行。 |
| Phase 2 | T+3M ~ T+6M | 举措 2 P2-P3(provision 端点 + 导出标杆);举措 3 P3-P4(积分行为经济 + 转介绍);举措 4 P3(健康度 + ROI);举措 5 P2(开放 API,安全修复后)。 |
| Phase 3 | T+6M ~ T+12M | 套餐矩阵成熟 + 渠道分销试点 + ISV 生态接入 + 量到价的迭代(基于真实账单数据调价)。连接池分片 top-N 方案落地(配合高可用)。 |
本章节所有论断均经代码核实(文件路径:行号见正文),无臆测。核心增量判断:HMS 的商业化基础设施零件(计量/配额/积分/队列/主题/事件总线)都已存在但未缝合,本主题的工作是「接线」而非「造零件」,因此工作量集中在 trait 抽象、中间件、rollup 调度与运营配置,不涉及大规模重写。