3.5 KiB
3.5 KiB
F02 本地配置与租户额度读取证据
范围
本证据只覆盖单 Dispatcher、单 Agent、单 Asterisk、单 Cell、单租户的项目内 v0.1 实现与本地 Mock。它不代表 SaaS/management 外部签收、真实 Agent/Asterisk 已加载、真实部署或真实线路验收。
实现事实
- 配置客户端读取并严格校验 SIP、任务发现页、任务配置、租户额度四条只读 GET;核对 Dispatcher、任务、tenant_id、原值 tenant_key 与 SaaS 所有的队列路由身份。游标过期时可请求完整发现快照首响应;多页聚合、持久水位与重启恢复由 F03 完成。
- Dispatcher 仅在四个完整响应都验证通过且 SIP applied-status verifier 通过后发布配置快照。每个响应原始 JSON、版本、内容 SHA-256、获取时间和失效时间写入 SQLite;版本回退或同版本内容变化拒绝。内存快照按 tenant_id/task_id 索引;SIP/发现快照在任务间共享,租户额度在同租户任务间共享。失败或过期不使用旧缓存准入。
- tenant_id 与 tenant_key 在本 Dispatcher 内一对一绑定。租户/任务额度更新与完整响应持久化同事务;额度降级不清理已有 reserved/unknown 占用。
- 接纳
call.execute时,tenant 与 task 两个额度范围、任务行、执行配置原始快照、reservation、inbox、command receipt 和 outbox 在一个 SQLite 事务内提交。额度不足时持久化quota_exceeded拒绝,不创建任务/占用;额度未配置或事务失败时拒绝 ACK。相同 command_id 重投复用原 receipt,不重复占额。 - 新配置读取必须通过 Agent applied-config 核验:部署指定的 Agent/Cell 身份需匹配;
applied_configs恰有一条kind="sip",且state="applied"、十进制 revision、SHA-256 与配置响应中的获批 SIP artifact 精确一致,并有正的observed_at_unix_ms。缺失、重复或不匹配均 fail-closed。此处是项目内 Agent 协议规则;Mock status 不证明真实 Asterisk 已加载。 - 配置刷新持写锁,命令接纳持读锁;刷新失败清空可用于新接纳的内存快照,避免旧配置与新版本竞态。
验证结果
python3 scripts/validate-local-contracts.py:四个本地 Schema、正反例和 19 个 manifest SHA-256 项通过。go test ./internal/configread ./internal/contract ./internal/store ./internal/dispatcher -count=1:通过。go test -race ./internal/configread ./internal/contract ./internal/store ./internal/dispatcher -count=1:通过。go test ./... -count=1:通过。go vet ./...:通过。go build ./...:通过。go test -cover ./internal/configread ./internal/contract ./internal/store ./internal/dispatcher -count=1:覆盖率依次为 75.0%、73.3%、65.1%、71.4%,F02 涉及包均不低于 65%。- 当前
go test -cover ./...总覆盖率为 49.5%;全项目 65% 门禁仍由 F09 验证,不能将 F02 包覆盖率当作全项目通过。
Mock 覆盖配置断连、过期、身份/路由不匹配、版本冲突、额度降级、同租户多任务共享额度、并发额度竞争、刷新与接纳竞态,以及 Agent applied-config 缺失/重复/不匹配。
未验证与后续边界
- 未连接真实 SaaS、management、云、供应商或 SIP 线路;没有真实拨号、真实 Agent status 或真实 Asterisk 加载证据。
- F02 组件及本地测试已交付,但 v3 队列消费/应用启动集成仍属于 F03;当前旧 MQ v2 主入口尚未切换。
- F09 其他工作包、真实部署/切换和生产验收未由本证据覆盖。