本域总览见《账号计费中心 · 结构大纲》。本文为该域完整设计:定位与边界 / 角色与依赖 / 数据模型 / 核心流程 / 接口契约 / 关键约束与验收标准。
定位:用量与金额的事实底座。回答四个问题——「一次调用产生了多少用量」(量)、「这些用量归谁」(归属维度)、「这些用量应付多少钱」(金额)、「上报的量与实扣的钱对得上吗」(对账)。
本域是唯一的用量落库方与对账判定方:所有通道的用量汇聚到同一张日聚合底座,所有对账结论由本域给出。按「先事实结构、再运行路径、后对外投影」的次序组织:第 3 节给出底座结构,第 4 节给出结构之上的写入/查询/对账路径,第 5 节给出这些路径的对外投影。
核心口径
| 口径 | 内容 |
|---|---|
| 量价分离 | 应付金额由计量方按自身计价规则即算即传;本侧只入账不计价,不读计价规则、不做二次换算 |
| 覆盖式 | 同一维度组合同一统计日重复上报 = 覆盖,不是累加;量可重算,对账重跑不双计 |
| 归属六元组 | 组织 / 组 / 成员 / 模型 / 密钥展示前缀 / 统计日期 |
| 日粒度 | 按统计日期聚合的日粒度底座,非实时明细;日期一律按 Asia/Shanghai 归日 |
| 金额口径 | 元、6 位小数、字符串传输;列级精度与资金侧口径对齐 |
| 对账容差 | 默认 0,即精确比对(两侧同源同值) |
| 差异方向 | 差异 = 计费额 − 计量额:为正即多扣(计费额大于计量额),为负即缺扣 |
| 债务口径 | 对账差异只落处置台账与告警,不构成欠费判定依据(欠费只认现金余额为负,判定在钱包与账务域) |
边界(不管什么)
本域在多域中的位置
参与角色
| 角色 | 身份 | 在本域的能力 |
|---|---|---|
| 实例计量侧 | 服务间调用方 | 按窗口聚合后推送用量行(覆盖式),随行带应付金额 |
| 数据面网关计量侧 | 服务间调用方 | 推送账户密钥通道的用量行(密钥展示前缀与实例侧不同源) |
| 计费路由计量侧 | 服务间调用方 | 推送中转通道的用量行;组标识与成员标识可能来自另一命名空间 |
| 运营面 | 运营人员(持运营范围令牌) | 查看对账差异报表、手动触发对账扫描 |
| 组织管理者 | 工作区 Owner / Admin | 查看组织透视用量(任意维度组合、导出) |
| 个人用户 | 门户用户 | 查看本人透视用量、账期账单 |
能力矩阵
| 操作 | 实例 / 网关 / 路由计量侧 | 运营面 | 组织管理者 | 个人用户 |
|---|---|---|---|---|
| 推送用量行 | ✓ | ✗ | ✗ | ✗ |
| 账期汇总读取 | ✗ | ✓ | ✗ | ✗ |
| 对账差异报表 | ✗ | ✓ | ✗ | ✗ |
| 手动触发对账扫描 | ✗ | ✓ | ✗ | ✗ |
| 组织透视用量 | ✗ | ✗ | ✓(Owner / Admin) | ✗ |
| 本人透视用量 / 账期账单 | ✗ | ✗ | ✗ | ✓ |
上游依赖
下游被引用(谁引用本域)
| 引用方 | 引用内容 | 语义 |
|---|---|---|
| 钱包与账务域 | 用量日聚合 | 账期账单的用量侧数据源 |
| 发票域 | 账期汇总 | 开票数据源(按周期聚合后的用量与金额) |
| 风控与合规域 | 用量日聚合 | 用量突增的阈值与环比判定输入;台账表由该域拥有 |
| 通知与触达域 | 站内信记录 | 对账异常与量级突增的送达(本域只借写站内信行) |
| 用户自助与门户 | 聚合函数与口径 | 门户用量页、组织透视页、账单页复用同一聚合入口与分页口径 |
访问边界
三条弱引用线均为非同一域内的归属关系:本域刻意不为它们建外键(见 3.4 第 4 条)。
| 表 | 归属 | 职责 | 关键字段 |
|---|---|---|---|
usage_daily |
本域自有 | 维度化用量日聚合底座(覆盖式) | organization_id / group_id / user_id / model / key_display / stat_date / requests / input_tokens / output_tokens / amount / quoted_amount / updated_at |
risk_events |
风控与合规域,本域借写 | 对账差异与量级突增的处置台账 | rule_id / organization_id / group_id / customer_id / trigger_tokens / threshold_tokens / action / triggered_at |
notifications |
通知与触达域,本域借写 | 对账异常与量级突增的站内信送达 | customer_id / type / group_id / title / content / read_at |
usage_daily 是唯一自有表;台账与站内信两表的表结构属他域,本域仅在对账扫描时写入行,故列为「借写」,不重复展开其设计。uq_usage_daily_dims 覆盖(工作区、组、成员、模型、密钥展示前缀、统计日期);一切写入路径都必须命中该约束做覆盖,不得追加。user_id 列可空,但写入方在无法归因到人时一律归一为哨兵标识——空值在唯一约束下互不相等,直接写空会破坏覆盖式语义,使同一维度同一天分裂成多行。key_display 只是可读标识,仅承载展示与归属切分;实例通道与账户通道的前缀来源不同,天然分属不同唯一行,从而两写者互斥、不双计。amount 与 quoted_amount 均为元、固定 6 位小数;未计价时为空,覆盖写入按「新值优先、空值不清旧值」处理。stat_date 只接受 [今天 − N, 今天](Asia/Shanghai),N 由 usage_stat_date_backfill_days 给定、默认 90 天;越界整批拒绝。usage_daily 不提供删除路径,覆盖是唯一更新方式;updated_at 记录最后一次覆盖时刻,可据此判断窗口是否被重推。ix_usage_daily_stat_date 支撑按日期区间的全量聚合;ix_usage_daily_group_date 支撑对账的按组 × 统计日聚合。usage_stat_date_backfill_days 取值需覆盖计量采集的迟到重推与对账重跑跨度;越界拒绝的理由是:未来日期污染长期报表,任意历史日期污染已封账账期。(组织, 组, 统计日期):量与钱都按同一归日口径聚合(Asia/Shanghai),不随数据库会话时区漂移。reconcile_tolerance_amount 默认 0,即精确比对;两侧同源同值,无例外。reconcile_scan_window_days 默认 1,即只扫「昨天」这一已完结窗口,避免在途数据误报。reconcile_tolerance_amount(默认 0)才判异常;同组在 reconcile_dedupe_hours(默认 24 小时)内不重复命中。reconcile),平台级、首次需要时创建;台账行以该规则为外键,动作固定为通知类。account_reconcile_scan_enabled、account_reconcile_scan_interval_seconds 控制;多副本同时运行不产生重复台账——去重键为「同规则 × 组织 × 组」,重复扫描不重复落行。reconcile_waiver_spike_min_count(默认 10,小样本豁免)且 > 前一窗口计数 × reconcile_waiver_spike_ratio(默认 5);倍数设为 0 或下限设为 0 即关闭该项。waiver_spike。/internal/usage)| 方法 | 路径 | 语义 |
|---|---|---|
| POST | /internal/usage/bulk |
批量推送用量行(1..500 行):覆盖式 UPSERT,返回实际落库行数;日期越界返回 stat_date_out_of_range,命中本域组但工作区不一致返回 group_org_mismatch |
/internal/usage、/internal/reconcile)| 方法 | 路径 | 语义 |
|---|---|---|
| GET | /internal/usage/summary |
账期汇总:按(组, 统计日)聚合的用量 + 流水按类型/组的聚合(发票与账单数据源);结束日期早于开始日期返回 end_date_before_start |
| GET | /internal/reconcile/check |
对账差异报表:周期内每(组 × 统计日)的量/钱 + 交叉校验结果 + 汇总 |
| POST | /internal/reconcile/scan |
手动触发对账异常检测(幂等):量钱差异与免计费量级突增一并扫描,返回新建台账数 |
/api/account/ops)| 方法 | 路径 | 语义 |
|---|---|---|
| GET | /api/account/ops/reconcile/check |
对账差异报表(运营面入口,与内部实现共用同一实现,不做双轨) |
| POST | /api/account/ops/reconcile/scan |
手动触发对账扫描(幂等),并写运营操作留痕 |
/api/account)| 方法 | 路径 | 语义 |
|---|---|---|
| GET | /api/account/usage |
本人透视用量:按(统计日期、模型、密钥展示前缀)聚合分页,默认最近 30 天;返回总数与分页参数 |
| GET | /api/account/org/usage |
组织透视用量:维度组合可配(默认组 × 日期),返回列表 + 全量汇总 + 总数;导出时返回同源 CSV |
| GET | /api/account/bills |
账期账单:用量日汇总 + 按模型聚合 + 流水按类型聚合 |
invalid_dimensions,日期反序返回 end_date_before_start。| # | 验收口径 |
|---|---|
| 1 | 同一六元组连续推送两次且量不同:底座只有一行,取后一次的值(覆盖而非累加) |
| 2 | 同一批内含重复维度:请求成功,落库行数等于去重后的行数,不出现整批失败 |
| 3 | 成员维度为空的上报:写入归一为哨兵,重复上报仍覆盖同一行(不分裂成多行) |
| 4 | 实例通道与账户密钥通道各推一行、其余维度相同:底座两行并存、互不覆盖,合计等于两行之和 |
| 5 | 统计日期超出 [今天 − N, 今天]:整批拒绝并返回越界原因,底座无任何新增行 |
| 6 | 组标识命中本域组但工作区不一致:整批拒绝;组标识未命中:放行且产生一条结构化告警 |
| 7 | 覆盖写入时金额传空:原有金额保留(不被抹成空);首次上报即带金额:正常落值 |
| 8 | 个人透视查询:只返回本人成员维度的行,总数与分页正确,翻页不改变汇总数字 |
| 9 | 组织透视任意维度组合:总数等于聚合后分组行数,汇总等于过滤范围内全量合计(不随当前页变化) |
| 10 | 量与钱完全一致时报表全行为一致;仅钱多时标为多扣、仅钱少时标为缺扣,差异额等于两者之差 |
| 11 | 无组归属的入账流水不出现在对账报表行内;纯入账日不产生核对行 |
| 12 | 连续两次扫描同一窗口:第二次不产生新台账;多副本同时扫描亦不产生重复台账 |
| 13 | 免计费留痕金额恒为 0 且不计入量钱等式;当前窗计数相对前一窗口超过倍数且不低于下限时产生台账与站内信,低于下限时不产生 |
| 14 | 突增倍数设为 0 或下限设为 0 时,免计费突增扫描不产生任何台账 |
| 15 | 对账异常落台账后,工作区余额与账户状态均不发生任何变化 |
| 16 | 内部写入与汇总端点无内部令牌不可访问;运营面对账端点无运营范围不可访问 |