| 项 | 值 |
|---|---|
| 文档名称 | 企业预付费余额预警 PRD(一期实施 + 二期规划) |
| 版本 / 日期 | v6 · 2026-09-20 |
| 适用范围 | 一期试点实施(第二至九章);二期规划(第十章) |
| 变更记录 | v5 重构为标准 PRD 结构 → v6 圈人依据升级:由"有无授信配置记录"改为"当前可用信用"动态判定(背景:资金处理方式字段一经授信即写死、不可回退,而授信状态会流转,详见 FR-01 与附录 A) |
预付费企业客户余额耗尽即停服,目前系统没有任何前置提醒机制,客户处于"被停了才知道"的被动状态,直接影响客户业务连续性与平台口碑。
授信企业(额度 + 账期)余额常为负、另有账期与自动冻结机制,属另一套管理逻辑,本 PRD 不涉及,后续单独立项。
- 短期(一期):建立静态阈值预警能力,先发内部运营(钉钉群)试点验证判定准确性,再切客户短信,做到"客户停服前必有提醒"。
- 中期(二期):开放企业自助配置(警戒线、接收人),增加动态预警(按消耗速度预估可支撑天数)。
| 指标 | 目标值 | 度量口径 |
|---|---|---|
| 漏报 | 0 | 余额耗尽(≤ 0 / 停服)的企业,此前 7 天内必有 WARN/CRITICAL 记录 |
| 误报率 | < 10% | 运营复核 FALSE_ALARM 占全部试点记录的比例 |
| 提前量 | 平均 ≥ 3 天 | 触发时点距余额耗尽的平均时长 |
| 打扰控制 | 同企业同档位单日 ≤ 1 条 | 无重复轰炸 |
| 能力 | 一期(本期实施) | 二期(一期转正后启动) |
|---|---|---|
| 提醒线 | 平台统一规则,仅两条自动规则:充值型 = 上次充值 × 5%;纯赠额 = 固定线(全局参数,试点期可调) | 企业后台自定义警戒线;未设置时回落一期默认规则 |
| 接收人 | 试点发内部运营;转正后发企业绑定手机号 | 后台自助管理:默认自动带出企业绑定手机号,可增删多个 |
| 预警类型 | 静态阈值(余额低于线即提醒) | 增加动态预警(勾选开启):按近期消耗速度预估可支撑天数,不足 7 天即提醒——覆盖"余额看着还行、但按当前烧钱速度几天就没了"的场景 |
| 激增提醒 | 不做 | 可选:单日用量异常升高提醒(详见 10.3) |
| 配置维护方 | 运营(平台侧,仅全局参数与开关,无企业级手工阈值) | 企业自助 + 平台兜底(紧急档企业不可关) |
| 上线方式 | 内部试点 → 切客户短信 | 直接面向客户,依赖一期转正 |
划分原则:一期把判定引擎、防骚扰、发送开关这些底座做对,二期只加"配置入口 + 一种新判定维度",不动底座。二期所需新字段随企业自助配置入口一并引入(字段跟着入口走),仅轻量加列,无表结构大迁移。
| 项 | 说明 |
|---|---|
| ✅ 只做 | 预付费企业 = 当前无可用信用的企业账户(按 FR-01 动态判定,不依赖后台"资金处理方式"展示字段——该字段一经授信即写死,无法回退为预付费) |
| ❌ 不做 | 授信企业(额度 + 账期)——余额常负、有账期与自动冻结机制,属另一套管理逻辑,后续单独立项 |
| ❌ 不做 | 个人账户(ba_personal_*),只针对 type='enterprise' |
| ❌ 不做(一期) | 运营手工固定阈值配置——一期只保留两条自动提醒线规则,个案走运营人工预案(见 5.2 已知局限) |
| 术语 | 定义 |
|---|---|
| 预付费企业 | 当前无可用信用的企业账户,余额耗尽即停服;授信失效(暂停 / 清零 / 到期)后自动回归此类 |
| 授信企业 | 当前存在可用信用的企业账户(余额耗尽进入信用垫付、不停服),不在本需求范围 |
| 可用信用 | 授信配置满足 status='ACTIVE' 且 limit_usd>0 且在有效期内的状态;每轮判定动态重查,不依赖任何写死的身份字段 |
| 提醒线(阈值) | 触发预警的余额下限,按第 5.2 节规则计算 |
| WARN(预警档) | 余额跌破提醒线,提示及时充值 |
| CRITICAL(紧急档) | 余额跌破提醒线一半或 ≤ 0,提示即将停服 |
| 防抖状态机 | 记录企业当前预警状态(NORMAL / WARN / CRITICAL),配合回滞与限频防止反复打扰 |
| 回滞解除 | 余额回升到提醒线 × 1.5 以上才恢复正常状态,避免在线附近来回触发 |
| send_mode | 全局发送开关:OFF(只落库)/ PILOT(发内部运营钉钉群)/ CUSTOMER(发企业短信) |
| voucher_threshold_usd | 纯赠额固定提醒线的全局参数(当前 20 元),试点期可调 |
| 角色 | 诉求 | 对应场景 |
|---|---|---|
| 预付费企业客户 | 账户余额不足前收到提醒,避免业务中断 | 收到 WARN 短信后充值;收到 CRITICAL 短信后立即充值 |
| 纯赠额体验客户 | 体验额度将尽时收到转化提示 | 收到"体验额度即将用完"文案,引导充值转正 |
| 内部运营(试点期) | 验证判定准确性、复核误报、跟进个案客户 | 钉钉群接收试点告警,逐条标注 OK / FALSE_ALARM;对高频小额充值客户走人工跟进预案 |
| 平台客服/一线 | 能回答客户"为什么收到这条短信" | 通过告警记录的余额/阈值快照回溯触发原因 |
核心用户故事:作为预付费企业客户,我希望在余额不足以支撑业务时提前收到提醒,以便及时充值、避免服务中断。
判定与发送整体解耦:FR-01 ~ FR-03 为判定引擎(产出告警记录),FR-04 为发送路由(决定发不发、发给谁),FR-05 为通知内容。
需求描述:每轮批处理首先圈出全部预付费企业账户。
业务背景:后台"资金处理方式"是写死的展示口径——企业一经授信即固定标记为授信用户,无法回退为预付费;而授信状态本身会流转(暂停 / 额度清零 / 到期 / 恢复)。若按"授信过没有"圈人,授信已失效、实际靠余额运转的企业(余额耗尽即停服)将被永久漏掉。因此判定依据不看"身份",看"当前可用信用":每轮动态重查,授信失效的企业自动落回预警池,恢复授信自动离开,不依赖人工改身份。
实现逻辑:
SELECT a.id
FROM billing_accounts a
WHERE a.type = 'enterprise'
AND a.status = 'active'
AND a.deleted_at IS NULL
AND NOT EXISTS ( -- 存在"可用信用"即视为授信客户,跳过
SELECT 1 FROM billing_account_credit_configs c
WHERE c.billing_account_id = a.id
AND c.status = 'ACTIVE'
AND c.limit_usd > 0
AND (c.effective_at IS NULL OR c.effective_at <= now())
AND (c.expires_at IS NULL OR c.expires_at > now())
-- 现状核查(2026-09-20):当前全部 3 条配置 effective_at / expires_at 均为空(无限期模式),
-- 有效期条件为前瞻兼容写法,覆盖未来填了有效期的配置
);验收标准:
- 圈选结果只包含
type='enterprise'、active、未删除、当前无可用信用的企业; - 授信配置被暂停(SUSPENDED)、额度清零或已过期的企业自动进入圈选(事实预付费,余额耗尽即停服);
- 授信恢复(重新 ACTIVE 且额度 > 0)后,企业自动离开圈选;
ba_personal_*个人账户不出现在结果中。
需求描述:按企业入账情况自动确定提醒线。一期仅两条自动规则,不提供任何手工阈值配置入口。
| 企业情况 | 提醒线 | 说明 |
|---|---|---|
| 有充值记录 | 最后一笔 RECHARGE 金额 × 5% | 语义:上次充的钱快用完了。线自动跟随客户充值习惯,大客户线高、小客户线低 |
| 只有赠额、无充值 | 固定金额 20 元(已评审确认;取值落点为全局参数 voucher_threshold_usd,试点期可调),文案走转化口径 |
赠额一般 100~200,×5% 只剩几块钱没有提前量,改用固定线 |
| 既无充值也无赠额 | 跳过 | 预付费无余额即无消耗,不会出现"有消耗但无入账" |
业务规则:
- 自动切换:纯赠额企业发生首笔充值后,下一轮起自动改按"上次充值 × 5%"。
- 分母不会被赠额污染:已查生产库验证,赠额走
ADJUST入账(description 带voucher:<券ID> admin:<操作人>),与 RECHARGE 完全分离。 - 上次充值取法:
SELECT DISTINCT ON (billing_account_id)
billing_account_id, amount_usd, created_at
FROM balance_transactions
WHERE type = 'RECHARGE'
ORDER BY billing_account_id, created_at DESC;已知局限(一期接受,不提供手工阈值兜底能力):频繁小额充值的企业(如每周充 100)提醒线会很低、提前量短。一期不在平台侧提供企业级手工固定阈值配置。个案临时处理预案:由运营人工跟进——客服触达提醒充值,或引导客户提高单次充值金额(提醒线随充值额自动抬高);根治方案为二期企业自定义警戒线(见 10.1)。
验收标准:
- 充值型企业提醒线 = 最后一笔 RECHARGE × 5%,随新充值自动更新;
- 纯赠额企业提醒线 = 全局参数
voucher_threshold_usd(当前 20 元);首笔充值后下一轮自动切换为充值型规则; - 赠额入账(ADJUST)不参与"上次充值"计算;
- 系统不存在企业级手工阈值入口,全部企业只走两条自动规则。
需求描述:挂接现有 15 分钟批处理频率,逐企业比对余额与提醒线,按两档规则产出告警,并严格执行防骚扰三规则。
⚠️ 工程依赖:批处理挂载点(现有 15 分钟任务)待工程二次核对后确定,不影响本节判定逻辑。
档位定义:
| 档位 | 条件 | 动作 |
|---|---|---|
| WARN(预警) | 余额 < 提醒线 | 发预警短信 |
| CRITICAL(紧急) | 余额 < 提醒线 × 1/2,或 余额 ≤ 0(已查库证实会发生:最后一笔扣费可穿过 0,现存 -0.04、-0.59 实例) | 发紧急短信 |
防骚扰三规则(必须,15 分钟一轮 = 一天 96 轮,缺一条就会打爆客户):
- 记状态:掉到线以下记为"进入提醒状态",存于配置表
current_state; - 回滞解除:余额回升到 提醒线 × 1.5 以上才恢复"正常",防止在线附近来回晃荡反复触发;
- 限频:同一档位每天最多 1 条(查当日
balance_alert_records已发送记录);CRITICAL 持续未充值,隔 3 天重复提醒(已评审确认,试点期可视数据微调)。
状态机转移表:
| 当前状态 | 触发条件 | 下一状态 | 是否发送 |
|---|---|---|---|
| NORMAL | 提醒线 × 1/2 ≤ 余额 < 提醒线 | WARN | 是(WARN,当日限 1 条) |
| NORMAL | 余额 < 提醒线 × 1/2,或余额 ≤ 0 | CRITICAL | 是(CRITICAL,当日限 1 条) |
| WARN | 余额 < 提醒线 × 1/2,或余额 ≤ 0 | CRITICAL | 是(档位升级) |
| 任意 | 余额 ≥ 提醒线 × 1.5 | NORMAL | 否(状态复位,下次触发重新计数) |
充值到账 → 余额回升过线 × 1.5 → 状态自动复位,下次再触发重新计数。
验收标准:
- 判定结果与档位定义完全一致,含余额 ≤ 0 直接落 CRITICAL 的边界;
- 余额在提醒线附近波动时(未回升至 × 1.5),不重复进入提醒状态、不产生新告警;
- 同一企业同一档位当日发送 ≤ 1 条;CRITICAL 持续未充值时第 4 天起重复提醒(间隔 3 天);
- 充值复位后,再次跌破线时可正常重新触发。
需求描述:判定引擎只产出告警记录;发不发、发给谁,由全局开关 send_mode 决定。
每15分钟批处理 发送路由(读全局开关)
┌──────────────────┐ ┌─────────────────────────┐
│ 圈预付费企业 │ 告警记录 │ send_mode = OFF │
│ 算余额/线/防抖 │ ──────────→ │ 只落库不发 │
│ 写 alert_records │ │ send_mode = PILOT │
└──────────────────┘ │ 发内部运营(钉钉群) │
│ send_mode = CUSTOMER │
│ 发企业绑定手机号(短信) │
└─────────────────────────┘
业务规则:
- 试点 → 转正 = 切开关,判定逻辑零改动;
- 试点期 OFF/PILOT 模式下记录照常落库,即为运营核查样本。
验收标准:
- 三种模式下判定引擎产出完全一致,仅发送行为不同;
- OFF 模式落库不发送;PILOT 模式只发钉钉群;CUSTOMER 模式只发企业绑定手机号短信;
- 模式切换无需改代码、无需重启判定逻辑。
文案(占位符以实际签名为准):
| 场景 | 文案 |
|---|---|
| WARN(充值型) | 【签名】{企业名}您好,您的账户余额为{余额}元,为避免影响业务调用请及时充值。 |
| CRITICAL | 【签名】{企业名}您好,您的账户余额已耗尽/即将耗尽,服务即将暂停,请立即充值恢复。 |
| 纯赠额(转化口径) | 【签名】{企业名}您好,您的体验额度即将用完,充值后可继续使用服务。 |
试点期通道:PILOT 模式不使用短信,推钉钉群消息:企业名 / 当前余额 / 提醒线 / 档位,一行一条。
通道验证(上线前置条件):短信签名与模板需提前向通道报备;切换 CUSTOMER 前,先用运营手机号实测三条模板的真实发送与到达,确认无误后再切(已评审确认)。
验收标准:
- 三条模板均完成通道报备并通过实机收发验证;
- 钉钉试点消息包含企业名、当前余额、提醒线、档位四要素;
- 纯赠额企业命中时发送转化口径文案,充值型与紧急档文案不混用。
字段风格对齐现有库:text 主键、金额
numeric带_usd后缀(历史惯例:字段名带 usd,实际按账户币种 CNY 计价)、timestamp without time zone。
-- 1) 告警配置 + 状态(一期仅存防抖状态,无企业级阈值配置字段;
-- 二期随企业自助配置入口引入 threshold_mode(AUTO/CUSTOM)、threshold_fixed_usd、receivers、dynamic_enabled 字段)
CREATE TABLE balance_alert_configs (
billing_account_id text PRIMARY KEY,
enabled boolean NOT NULL DEFAULT true,
current_state text NOT NULL DEFAULT 'NORMAL', -- NORMAL / WARN / CRITICAL(防抖状态机)
state_since timestamp, -- 进入当前状态时间
last_alert_at timestamp, -- 最近一次发送时间(限频辅助)
created_at timestamp NOT NULL DEFAULT now(),
updated_at timestamp NOT NULL DEFAULT now()
);
-- 2) 告警记录(判定快照 + 发送流水 + 试点复核)
CREATE TABLE balance_alert_records (
id text PRIMARY KEY,
billing_account_id text NOT NULL,
level text NOT NULL, -- WARN / CRITICAL
balance_usd numeric NOT NULL, -- 触发时余额快照(排查"为什么收到短信")
threshold_usd numeric NOT NULL, -- 触发时提醒线快照
threshold_mode text NOT NULL, -- LAST_RECHARGE_5PCT / VOUCHER_FIXED
send_mode text NOT NULL, -- OFF / PILOT / CUSTOMER(当时的全局模式)
status text NOT NULL, -- SENT / SKIPPED_COOLDOWN / FAILED
channel text, -- SMS / DINGTALK / EMAIL
receiver text,
sent_at timestamp,
operator_review text, -- 试点期运营标注:OK / FALSE_ALARM(转正后闲置)
created_at timestamp NOT NULL DEFAULT now()
);
CREATE INDEX ON balance_alert_records (billing_account_id, created_at DESC);
-- 3) 全局配置(单行)
-- balance_alert_settings (send_mode text, pilot_receivers text[], voucher_threshold_usd numeric)
-- send_mode: OFF → PILOT → CUSTOMER
-- voucher_threshold_usd: 纯赠额固定提醒线(当前 20 元),全局参数,试点期可调
⚠️ 工程依赖:两张新表的落库归属(建议随计费库ruidong_billing)与 id 生成规则(对齐现有 text 主键惯例)待工程二次核对。
| 类别 | 要求 |
|---|---|
| 运行频率 | 判定挂接现有 15 分钟批处理(96 轮/天),不新增独立调度压力 |
| 幂等与防重 | 同企业同档位单日发送 ≤ 1 条,以 balance_alert_records 当日记录为准;批处理重复运行不产生重复发送 |
| 可观测性 | 每条判定(含被限频跳过 SKIPPED_COOLDOWN)均落库,保留余额/阈值快照,支撑"为什么收到/没收到短信"的排查 |
| 可切换性 | 发送行为由单行全局开关控制,试点→转正零代码改动 |
| 参数可调性 | 纯赠额固定线为全局参数 voucher_threshold_usd,试点期改参即发,无需发版 |
| 合规 | 短信签名与模板提前报备通道;CUSTOMER 切换前完成实机收发验证 |
| 兼容性 | 二期新字段随企业自助配置入口以加列方式引入,无表结构大迁移 |
OFF(只落库)→ PILOT(钉钉群)→ 验收达标 → CUSTOMER(客户短信),全程仅切开关。
- 漏报对账(必须,每日):扫当日余额 ≤ 0 或停服的预付费企业,回查过去 7 天有无 WARN/CRITICAL 记录。漏报 = 0 才可转正;
- 误报复核:运营对每条试点记录标
OK / FALSE_ALARM,统计误报率,目标 < 10%; - 提前量:触发时点距余额耗尽应平均 ≥ 3 天(阈值合理性依据)。
| 企业 | 赠额 | 已消耗 | 余额 | 用途 |
|---|---|---|---|---|
| 数商云 | 200 | 88.71 | 111.29 | 纯赠额消耗中典型样本 |
| 中国康富国际租赁 | 200 | 31.04 | 168.96 | 纯赠额消耗中典型样本 |
两家均为纯赠额消耗中的典型,可直接验证 VOUCHER_FIXED 档触发时机。
| # | 事项 | 影响 |
|---|---|---|
| 1 | 批处理挂载点(现有 15 分钟任务)待工程二次核对 | 不影响判定逻辑设计,影响工程排期 |
| 2 | 两张新表的落库归属(建议随计费库 ruidong_billing)待工程二次核对 |
影响 DDL 落位 |
| 3 | id 生成规则(对齐现有 text 主键惯例)待工程二次核对 | 影响 DDL 细节 |
| 风险 | 对策 |
|---|---|
| 高频小额充值客户提醒线过低、提前量不足(一期无手工阈值能力) | 运营人工预案:客服触达提醒充值 / 引导客户提高单次充值金额(提醒线自动抬高);二期由企业自定义警戒线根治 |
| 短信通道报备周期不确定,阻塞 CUSTOMER 切换 | 报备前置启动;PILOT 期不依赖短信通道,可先跑 |
| 参数(20 元固定线、CRITICAL 3 天间隔)与实际数据不符 | 均为已评审确认的暂定值,试点期可视数据微调;20 元线改全局参数 voucher_threshold_usd,调参无需发版 |
| 误报轰炸客户 | 防骚扰三规则 + 试点期只发内部运营,达标后才切客户 |
| 授信状态流转(暂停 / 恢复 / 失效)导致企业进出预警池,产生边界告警 | 圈人每轮动态重查;进出池由防抖状态机(回滞解除、限频)兜住,不产生重复打扰 |
| 配置项 | 行为 |
|---|---|
| 预警开关 + 自定义警戒线 | 企业管理员自设金额警戒线,替代平台统一规则,允许设得比平台默认线更高(已评审确认,仅 WARN 档生效);未设置时自动回落一期默认规则(上次充值 × 5% / 赠额固定线),保证功能开通即有默认保护 |
| 短信接收手机号 | 进入设置页自动带出企业绑定的手机号,可增删,上限 3~5 个(已评审确认,工程实现时取具体值);变更需短信验证码确认(防误改、防恶意填他人号码) |
| 动态预警 | 勾选开启(默认关),逻辑见 10.2 |
| 平台兜底 | CRITICAL(紧急档)由平台统一控制,判定线永远按平台默认规则计算(默认线的一半 / 余额 ≤ 0),不挂接企业自设线——企业把警戒线调得再低、甚至关掉 WARN,紧急档照常生效、不可关闭,防止企业误配置导致收不到停服通知 |
大白话:不看"余额还剩多少",看"按最近的用量还能烧几天"。客户可能余额看着还行,但最近放量很猛,几天就烧完——静态警戒线兜不住这种场景,动态预警补的就是这个缺口。
d7 = 近 7 天日均消耗
d3 = 近 3 天日均消耗
d = max(d3, d7) # 取大:对"突然放量"敏感,避免按旧均值低估烧钱速度
若 d = 0:跳过动态预警(最近没消耗,无可预测,只剩静态线兜底)
T = 余额 ÷ d # 可支撑天数
T < 7 天 → 提醒:"按您近 7 天的用量,余额预计约 X 天后耗尽,请及时充值"
边界:
- 余额 ≤ 0:不再算天数,直接走 CRITICAL
- 开户不足 7 天:按已有天数算日均
运行频率:每日一次即可(天级预测,无需 15 分钟);与静态预警并存但共用同一套防骚扰限频,避免一天收两条。
参数:可支撑天数阈值 7 天——已评审确认暂定值,上线前结合一期历史数据回测(见 10.5)由产品终审后生效。
单日消耗 > 3 倍前 7 天日均,且单日金额超过下限(防小额客户把几毛钱的波动也当激增)→ 发"今日用量异常升高"提醒。与余额预警独立,属增值项。倍数与下限为已评审确认的暂定值,上线前产品终审。
balance_alert_configs新增字段(随二期企业自助配置入口一并上线):threshold_mode(取值 AUTO / CUSTOM)、threshold_fixed_usd(企业自定义警戒线金额)、receivers(企业自配接收手机号)、dynamic_enabled(动态预警勾选);balance_alert_records新增列trigger_type:STATIC(静态线)/ DYNAMIC(可支撑天数)/ SURGE(激增),便于区分触发来源和统计各类型占比。
- 一期已切 CUSTOMER 且运行稳定(判定准确性通过试点验收:漏报 = 0、误报达标);
- 企业后台配置页 + 接收人变更验证码流程开发完成;
- 动态预警上线前用一期积累的历史告警记录回测一遍(用真实消耗数据验证"可支撑天数 < 7"的触发时机是否合理),避免直接上线后误报轰炸。
| 事实 | 结论 |
|---|---|
| 赠额入账类型 | ADJUST,description 前缀 voucher:<uuid> admin:<id>,与 RECHARGE 分离,分母无污染 |
| 全库流水分布 | CONSUME 170 万笔 / RECHARGE 56 笔 / ADJUST 15 笔(全为 voucher)/ REFUND 1 笔 |
| 纯赠额企业 | 4 家 enterprise 在消耗或待消耗;另 3 个 ba_personal_* 个人账户不在一期范围 |
| 余额可为负 | 存在 -0.04、-0.59 实例(最后扣费穿 0),CRITICAL 档位必要 |
| 券后充值共存 | 5 家企业既有赠额又有充值,"自动切换提醒线"必要 |
billing_accounts |
无"资金处理方式"落库字段(后台展示口径,授信后写死不可回退)→ 圈人改为按"当前可用信用"动态判定(见 FR-01) |
| 授信配置现状(2026-09-20 查) | 全库 3 家授信企业全部 ACTIVE(额度 10 万 / 1000 / 3),effective_at / expires_at 均为空;"授信过但当前无可用信用"的企业 = 0 家——身份写死问题暂无现实案例,属机制性前瞻风险,动态判定已覆盖 |
- 批处理挂载点(现有 15 分钟任务)
- 两张新表落库归属(建议随计费库
ruidong_billing) - id 生成规则(对齐现有 text 主键惯例)