diff --git a/docs/evidence/saas-dispatcher-implementation.md b/docs/evidence/saas-dispatcher-implementation.md index 63adf20..cc75705 100644 --- a/docs/evidence/saas-dispatcher-implementation.md +++ b/docs/evidence/saas-dispatcher-implementation.md @@ -144,6 +144,8 @@ - 旧本地 Schema/示例归档:新增 `TestCurrentContractDirectoryExcludesHistoricalGenerations`,先在 `contracts/local/v0.1–v0.4` 上预期失败;将共 17 个历史 JSON 文件逐字节移到 `docs/archive/contracts-local-history/v0.1–v0.4`,逐文件 SHA-256 与移动前一致、Git 基线为 `91d23a1`。`contracts/local/` 现在只保留当前无代次合同与示例,`contracts.Files` 原有嵌入规则未扩大;运行时拒绝旧本地合同的现有负例与目录检查均通过。`docs/contracts/local-contract-manifest-v0.6.json` 引用的是另一路径的历史原件,没有改写;本次也没有触碰上游来源、历史计划 hash 或现存 SQLite/恢复文件。历史文件不作为真实外部验收或配置回退。旧未使用夹具和测试对旧配置示例的直接依赖仍待移除,此批不宣布 P07 完成。 +- 普通时段测试不再读取旧方案示例:`TestEvaluateApprovedTaskAndLineConfigShape` 改用 `contracts.Files` 嵌入的当前 task/SIP 正例;TDD 先验证旧 `trunk_details` 在当前 `trunks` 响应下产生预期失败,再绑定当前字段,周一 `09:30` 的允许终点为 `20:00`。`contracts.ReadCurrent` 只允许顶层 Schema/拓扑而**不**允许例子,这是原有严格边界,不为测试扩张;测试只读嵌入的当前正例。删除无人引用、带旧 `schema_version` 和 `agent_version_id` 字段的 `internal/testfixture/execute.go`,不清理数据、日志或上游历史原件。受影响模块 `go test -race`、全仓 `make check`(含三项实际 PASS 的隔离 MQ 测试)、`make release-check-local` 通过。本批仍需完成全仓残留/例外总账与 P08,外部验收未运行。 + ## 验收台账 P01–P06 的项目内隔离证据见上;P07 全仓命名与唯一入口尚在清理,A01–A12 和 K01–K16 的最终对照仍待 P08。不得用本地 Mock 冒充外部签收。 diff --git a/internal/callwindow/policy_test.go b/internal/callwindow/policy_test.go index e382ce0..52ab966 100644 --- a/internal/callwindow/policy_test.go +++ b/internal/callwindow/policy_test.go @@ -2,10 +2,11 @@ package callwindow import ( "encoding/json" - "os" "strings" "testing" "time" + + "git.ipao.vip/rogee/go-sip/contracts" ) func week(windows ...Window) map[string][]Window { @@ -45,10 +46,10 @@ func TestEvaluateTaskAndLineIntersectionAtBoundaries(t *testing.T) { } } -func TestEvaluateActualTaskAndLineConfigShape(t *testing.T) { - readSchedule := func(path string, dest any) { +func TestEvaluateApprovedTaskAndLineConfigShape(t *testing.T) { + readSchedule := func(name string, dest any) { t.Helper() - body, err := os.ReadFile(path) + body, err := contracts.Files.ReadFile("local/" + name) if err != nil { t.Fatal(err) } @@ -59,18 +60,18 @@ func TestEvaluateActualTaskAndLineConfigShape(t *testing.T) { var task struct { Schedule TaskSchedule `json:"schedule"` } - readSchedule("../../docs/contracts/examples/config-read-task-v0.1.json", &task) + readSchedule("examples/config-read-task-asr.json", &task) var sip struct { - TrunkDetails []struct { + Trunks []struct { Schedule WeeklySchedule `json:"schedule"` - } `json:"trunk_details"` + } `json:"trunks"` } - readSchedule("../../docs/contracts/examples/config-read-sip-v0.1.json", &sip) - if len(sip.TrunkDetails) != 1 { - t.Fatalf("line sample count=%d", len(sip.TrunkDetails)) + readSchedule("examples/config-read-sip.json", &sip) + if len(sip.Trunks) != 1 { + t.Fatalf("line sample count=%d", len(sip.Trunks)) } - end, err := Evaluate(task.Schedule, sip.TrunkDetails[0].Schedule, atShanghai(t, "2026-09-21T09:30:00+08:00")) - if err != nil || !end.Equal(atShanghai(t, "2026-09-21T11:00:00+08:00")) { + end, err := Evaluate(task.Schedule, sip.Trunks[0].Schedule, atShanghai(t, "2026-09-21T09:30:00+08:00")) + if err != nil || !end.Equal(atShanghai(t, "2026-09-21T20:00:00+08:00")) { t.Fatalf("actual task and line schedules: end=%v err=%v", end, err) } } diff --git a/internal/testfixture/execute.go b/internal/testfixture/execute.go deleted file mode 100644 index 87e76cd..0000000 --- a/internal/testfixture/execute.go +++ /dev/null @@ -1,42 +0,0 @@ -// Package testfixture provides protocol fixtures for repository tests only. -package testfixture - -import ( - "encoding/json" - - "git.ipao.vip/rogee/go-sip/contracts" -) - -const DispatcherID = "c046b893-8628-4589-ae50-619d049248a6" - -// Execute supplies the current V1 external envelope with the stable identifiers -// used by scheduler tests. -func Execute() ([]byte, error) { - raw, err := contracts.Read("examples/call-execute.json") - if err != nil { - return nil, err - } - var envelope map[string]any - if err := json.Unmarshal(raw, &envelope); err != nil { - return nil, err - } - envelope["schema_version"] = "2.0" - envelope["dispatcher_id"] = DispatcherID - envelope["tenant_id"] = "tenant-demo" - envelope["tenant_key"] = "tenant-demo-key" - envelope["issued_at"] = "2026-09-11T08:00:00Z" - envelope["not_after"] = "2099-09-11T08:05:00Z" - payload := envelope["payload"].(map[string]any) - payload["execution_id"] = "exec_demo_001" - payload["task_id"] = "task-demo" - payload["task_item_id"] = "item_demo_001" - payload["callee"] = "18601013734" - payload["route_policy_id"] = "route_policy_test" - payload["caller_profile_id"] = "caller_profile_test" - payload["agent_version_id"] = "agent_v1" - payload["ring_timeout_ms"] = float64(30000) - payload["max_call_duration_ms"] = float64(180000) - return json.MarshalIndent(envelope, "", " ") -} - -func InboundKey(tenantKey string) string { return "d." + DispatcherID + ".t." + tenantKey + ".in" }