Skip to content

Servify 验收清单

这份清单的目标不是证明“看起来差不多做完了”,而是防止把“代码里有入口”误判成“功能已经可交付”。

验收时,每个功能项都必须同时具备以下 4 类证据,否则一律不算完成:

  1. 代码入口:路由、命令或调用入口明确存在。
  2. 自动化测试:至少有相关单测、集成测试或命令级验证。
  3. 运行证据:服务真实启动,接口可访问,请求与响应符合预期。
  4. 数据证据:涉及数据库、状态流转、文件或外部依赖时,能看到前后状态变化。

状态定义

  • 未验:只确认代码入口存在,没有实际跑通。
  • 部分通过:编译或单测通过,但关键业务链路、异常路径或数据落库未验。
  • 通过:具备代码、测试、运行、数据四类证据。
  • 阻塞:缺配置、依赖、权限、环境或数据,暂时无法验。

使用方式

先准备运行环境:

bash
make migrate DB_HOST=localhost DB_PORT=5432 DB_USER=postgres DB_PASSWORD=password DB_NAME=servify
make run-cli CONFIG=./config.yml
make run-knowledge-provider CONFIG=./config.weknora.yml
make run-weknora CONFIG=./config.weknora.yml
# `run-knowledge-provider` 是通用 alias;两者都仅用于 WeKnora compatibility / mock 验收
# 默认知识库 provider 仍以 Dify 为主

常用基础验证命令:

bash
make build
make build-knowledge-provider
make build-weknora
make test
go test -tags weknora ./apps/server/cmd ./apps/server/internal/handlers ./apps/server/pkg/weknora/...

每个条目都按下面模板记录:

字段内容
功能项例如“创建工单”
入口路由 / CLI / 页面
前置条件数据库、配置、鉴权、依赖服务
操作步骤明确到请求参数或操作动作
预期结果状态码、返回体、状态变化
自动化证据相关测试文件或命令
人工证据curl 结果、截图、日志、DB 查询结果
状态未验 / 部分通过 / 通过 / 阻塞

当前已确认的最小事实

这些是当前已经实际验证过的,不代表“全量功能完成”:

项目证据状态
Knowledge provider compatibility CLI 可构建make build-knowledge-providermake build-weknora 通过通过
WeKnora 相关 handler/pkg 基础测试go test -tags weknora ./apps/server/cmd ./apps/server/internal/handlers ./apps/server/pkg/weknora/... 通过通过
本地最小环境检查make local-check 通过通过
发布前最小自检make release-check CONFIG=./config.yml 通过;当前默认根配置路径已通过临时 SQLite 库完成迁移、启动、/health/ready/metrics 烟测,不再依赖本机预装 Postgres 才能复现这条最小发布自检通过
客服主链路聚焦自动化验证`go test -tags integration ./apps/server/internal/handlers -run 'Test(WorkspaceHandler_GetOverview_.*StatisticsHandler_Dashboard_And_TimeRange
主链路人工运行验证当前阻塞该条记录保留为历史人工验收事实:当时 nc -z localhost 5432 返回非零;go -C apps/server run ./cmd/server --port 18080 实际报错 dial tcp 127.0.0.1:5432: connect: connection refusedredis-cli -h localhost -p 6379 ping 返回 Connection refused;当前本机 Docker daemon 也不可用。补充说明:这不再阻塞默认 config.yml 下的 make release-check,因为发布前最小自检现已具备 SQLite 临时库回退路径阻塞
主链路人工运行验证第二轮本机已拉起 redis-serverpostgresql@15make migrate 完成;go -C apps/server run ./cmd/server --port 18080 启动成功;curl http://localhost:18080/health 返回 healthy;scripts/seed-data.sh http://localhost:18080 完成;随后已实际完成 admin / admin123 登录、Dashboard 查询、Workspace 查询、Ticket 列表/详情查询、补建 agent 实体后完成 Ticket assign,并通过 WebSocket 向 g1-session-1 写入消息再经 /api/omni/sessions/g1-session-1/messages 读回部分通过
主链路人工运行验证第三轮本机以 DB_USER=cui DB_NAME=servify 完成 make migrate;启动 SERVIFY_JWT_SECRET=dev-secret DB_USER=cui DB_NAME=servify go -C apps/server run ./cmd/server --port 18080curl http://localhost:18080/health 返回 healthy;更新后的 scripts/seed-data.sh http://localhost:18080 会创建 agent 实体并自动置为 online;随后已实际完成 admin / admin123 登录、/api/statistics/dashboard/api/omni/workspace/api/omni/sessions/g1-session-2/api/ticketsPOST /api/tickets/30/assign,并确认工单详情 agent_id 已更新为 4通过
AI 主链路人工运行验证第一轮admin / admin123 登录后,实际完成 GET /api/v1/ai/statusPOST /api/v1/ai/queryGET /api/v1/ai/metrics;其中 status 返回 type=orchestrated_enhancedfallback_enabled=truequery 返回 strategy=fallback,证明在外部 knowledge provider 不可用时主链路仍可响应;当前脚本留档也已覆盖 ai-query-after-disable.jsonai-metrics-after-fallback.json,用于补充 fallback 响应与指标证据通过
AI 控制面人工运行验证第二轮使用启用外部 knowledge provider 的临时配置启动服务,实际完成 PUT /api/v1/ai/knowledge-provider/enablePUT /api/v1/ai/knowledge-provider/disablePOST /api/v1/ai/circuit-breaker/reset;同时确认 GET /api/v1/ai/status 返回 knowledge_provider_enabled=trueknowledge_provider=<active-provider>、`knowledge_provider_healthy=truefalse,且 disable -> status -> enable -> status的状态切换能被证据文件留档,说明控制路由已暴露且运行时能清楚标识当前知识源健康度;本轮另已补scoped AI handler` 状态保持回归,覆盖 enable/disable 之后后续请求仍能看到同一 runtime 开关状态
AI 知识链路人工运行验证第三轮本机启动临时知识库 provider 测试环境后,以启用外部 knowledge provider 的临时配置启动服务;随后实际完成 POST /api/v1/ai/knowledge/uploadPOST /api/v1/ai/knowledge/sync,并确认 GET /api/v1/ai/status 返回 knowledge_provider_enabled=true、当前激活 knowledge_provider 以及 knowledge_provider_healthy=true,说明 Servify 到外部知识源的上传 / 同步协议路径已跑通;当前另已补自动化回归,锁定 enable 之后 UploadKnowledgeDocument 会真正进入 provider 路径而不是被错误地判成 knowledge provider is not enabled,且 SyncKnowledgeBase() 在 provider 未启用时不再返回假成功部分通过
配置加载口径修复回归验证新增 TestLoadConfigFindsRepoRootConfigFromNestedDir,确认从 apps/server 这类嵌套目录启动时,LoadConfig() 仍能读到仓库根 config.yml通过
运营高价值链路人工运行验证第一轮admin / admin123 登录后,实际完成 POST /api/customersGET /api/customers/:idPUT /api/customers/:idPOST /api/customers/:id/notesPUT /api/customers/:id/tagsGET /api/customers/statsGET /api/agentsPOST /api/agents/:id/onlinePUT /api/agents/:id/statusGET /api/agents/onlineGET /api/agents/statsGET /api/security/users/:idPOST /api/security/users/:id/revoke-tokensGET /api/security/users/:id/sessionsGET /api/audit/logs?action=customers.createGET /api/audit/logs/:idGET /api/audit/logs/:id/diffGET /api/audit/logs/export?action=customers.create&limit=5;其中审计查询在默认限流下触发过一次 429,随后使用白名单 X-API-Key: internal-test-key 验证通过部分通过
system 级 DailyStats 作用域回归`go test -tags integration ./apps/server/internal/services -run 'TestStatisticsService_(UpdateDailyStats_NewRecordUpdateDailyStats_IgnoresRequestScopeForSystemAggregate)$'go test -tags integration ./apps/server/internal/modules/analytics/infra -run 'TestGormRepositoryScoped(DashboardIgnoresGlobalDailyStats
审计保留与轻量导出约束自动化回归go test ./apps/server/internal/platform/audit -run 'TestGormRetentionServiceCleanup'、`go test ./apps/server/internal/handlers -run 'TestAuditHandlerExportCSV(ClampsLimitRejectsInvalidFilters)$'通过;已覆盖created_at < cutoff保留边界与导出limit最大值5000` 的服务端截断行为
scoped config rollback / verify 治理链路自动化回归`go test ./apps/server/internal/handlers -run 'TestScopedConfigHandler(RollbackRestoresSnapshotRollbackRequiresConfirmation
session risk 环境级策略与 Geo/IP provider 管理面回归`go test -tags integration ./apps/server/internal/handlers -run 'TestUserSecurityHandler_ListUserSessionsUses(ScopedRiskPolicyEnvironmentRiskProfile
HTTP Geo/IP provider 契约回归`go test ./apps/server/internal/handlers -run 'TestHTTPSessionIPIntelligenceDescribeIP(SupportsNestedDataPayloadUsesCustomAuthHeaderWithoutBearerPrefix
WeKnora 验收脚本 guard 与证据输出回归`go test ./scripts -run 'TestWeKnoraIntegrationScript(RealModeRejectsLocalHostMockModeWritesEvidence)$'通过;已锁定real模式对本地/私网 WeKnora 地址的拒绝策略,并覆盖mock模式的summary.txtai-status.jsonknowledge-upload.jsonknowledge-sync.json` 等关键证据文件输出
Dify 验收脚本 guard 与证据输出回归`go test ./scripts -run 'TestDifyIntegrationScript(RealModeRejectsLocalHostMockModeWritesEvidence)$'通过;已锁定real模式对本地/私网 Dify 地址的拒绝策略,并覆盖mock模式的summary.txtdify-dataset.jsonai-status.jsonknowledge-upload.jsonknowledge-sync.jsonai-metrics.json` 等关键证据文件输出
Knowledge provider 验收统一入口回归make dify-acceptancemake weknora-acceptancemake knowledge-provider-acceptance 已接入统一入口;CI script-checks 也已执行对应 go test ./scripts 门禁,确保脚本 guard 与证据输出能力不会回退通过
远程协助产品叙事文档对齐已统一更新 README文档首页remote-assistance.md;现在一致强调”远程协助 = 实时指导/联合排查/人工接管/工单闭环中的产品能力”,并明确区分当前已具备的实时基础与尚未承诺的完整 co-browsing 工作台通过
v0.1.0 blocker 修复验收1) AI/Knowledge 路由始终注册(router.go 移除 externalKnowledgeProviderEnabled 条件)2) make test 正确失败(移除 `
远程协助现状入口盘点已新增 remote-assistance-current-state.md,盘点了服务端现有会话、转接、assist、voice、WebSocket/WebRTC 入口,以及管理端 /conversation/routing/voice/ticket/detail/security 相关页面;同时明确当前缺口在“缺统一产品入口、缺状态机、缺最小演示链路”,而不是基础 runtime 缺失通过
远程协助 MVP 链路与验收口径已新增 remote-assistance-mvp.md,把最小可交付链路定义为“Web 会话 -> 人工接管 -> 转派/实时协作基础 -> 工单闭环”,并明确了对应页面、API 和人工演示步骤;当前不再把缺少独立 co-browsing 工作台误判成“没有远程协助产品方向”通过
staging 口径 release readiness 演练已新增 config.staging.example.yml,并实际通过 make security-check CONFIG=config.staging.example.ymlmake observability-check CONFIG=config.staging.example.ymlmake release-check CONFIG=config.staging.example.yml;同时已在 operator-runbook.mddeployment.md 回写 staging 基线与执行步骤通过
生产模板与告警阈值对齐已补齐 config.production.secure.example.yml 中显式的 metrics_path / tracing 基线,并把 deploy/observability/alerts/rules.yaml 中的 10 条告警阈值同步回写到 operator-runbook.mddeployment.mdobservability operational runbook通过
demo/mock/in-memory 资产边界清点已新增 demo-and-mock-boundaries.md,明确盘点 apps/demoapps/demo-sdkscripts/demo-setup.shscripts/seed-data.shinfra/compose/weknora-mockscripts/test-weknora-integration.sh、进程内 event bus、voice mock provider、Telegram/WeChat stub 的保留原因、prod-safe 判断与退出条件;现已能区分“可保留的演示/回归资产”和“不可误判为正式能力的占位实现”通过
运营高价值链路人工运行验证第二轮本机以 DB_USER=cui DB_NAME=servify go run ./apps/server/cmd/server --port 18081 启动服务,并继续使用 admin / admin123 登录;随后实际完成 POST /api/sla/configs 创建 urgent 配置、POST /api/sla/configs 创建 high 配置、GET /api/sla/configs/:idGET /api/sla/configs?page=1&page_size=20PUT /api/sla/configs/:idDELETE /api/sla/configs/:idGET /api/sla/configs/priority/urgentPOST /api/sla/check/ticket/22GET /api/sla/violations?page=1&page_size=20POST /api/sla/violations/1/resolveGET /api/sla/stats;其中 ticket 22 基于新建 urgent 配置命中 resolution 违约,resolve 后统计中的 unresolved_violations 变为 0;同时补充回归测试,确保 CheckTicketSLA 首次创建和重复返回违约时都会带上真实 ticket / sla_config 关联数据通过
公开入口与实时入口人工运行验证第一轮本机继续以 DB_USER=cui DB_NAME=servify go run ./apps/server/cmd/server --port 18081 启动服务;未登录访问 GET /public/portal/config 返回 brand_name=Servify 等公开配置;以 admin / admin123 登录后创建并显式发布知识文档 G1-4 Public KB,随后 GET /public/kb/docs?search=G1-4&page=1&page_size=10GET /public/kb/docs/16 可公开读取;补充说明:当前公开知识库已收紧为“仅暴露显式 is_public=true 的文档”,管理端新建文档默认保持内部可见;使用 Node ws 客户端连到 ws://127.0.0.1:18081/api/v1/ws?session_id=g1-4-ws 后成功收到同会话回显消息,且在连接存活期间 GET /api/v1/ws/stats 返回 connected_clients=1。补充说明:当前 /api/v1/ws 仍为公开 realtime 入口,但已要求显式传入 session_id,不会再为缺失参数的请求自动生成匿名会话;同时通过插入一条缺失的 customers.user_id=6 扩展记录,实际完成 GET /public/csat/g1-4-public-csat-tokenPOST /public/csat/g1-4-public-csat-token/respond,确认公开问卷可读取并可提交,提交后再次读取可见 status=completed;Voice 基础路径方面,已实际完成 GET /api/voice/protocolsPOST /api/voice/recordings/startGET /api/voice/recordings/:recordingIDPOST /api/voice/recordings/stopPOST /api/voice/transcriptsGET /api/voice/transcripts?call_id=g1-4-call、`POST /api/voice/protocols/sip/call-events/inviteanswer

说明:

  • 上述结果只能证明构建链和部分测试是通的。
  • 不能据此推出所有 API、权限、迁移、前端、数据链路都已完成。
  • G1-1 曾受本地 Postgres/Redis 环境阻塞,但该阻塞已在后续验证轮次解除。
  • 当前 G1-1 已补到一轮完整真实运行证据,原先暴露出的 3 个缺口里:
    • scripts/seed-data.sh 固定 customer_id 导致用户关联错位,已修复为基于真实注册返回的用户 ID 建票。
    • scripts/seed-data.sh 未创建 agent 实体,已修复为自动创建 /api/agents 记录。
    • /api/omni/sessions/:id 曾在仅有消息落库时返回 conversation not found,已补最小会话读模型兜底。
  • 当前 G1-2 已拿到 AI 主链路、fallback、控制接口以及基于本地 provider mock 的知识上传 / 同步协议证据。
  • 当前 G1-2 仍未拿到“真实 Dify 主路径 + WeKnora 兼容路径”的完整双路径运行证据;现阶段已证明 Servify 对外部 knowledge provider API 的调用路径可用,并已分别补齐 Dify 主路径与 WeKnora 兼容路径的验收脚本入口,但这仍不等同于真实生产级外部环境已完成验收。
  • 当前 knowledge-docs 管理接口已具备持久化 CRUD,且 Create/Update 已开始自动 upsert 当前外部 knowledge provider;但 Delete 仍受 provider 能力约束,现阶段仅能做到“支持删除则同步删,不支持则显式失败并保留本地文档”。因此知识文档管理与 AI 外部检索的一致性边界已比之前清晰,但仍不能视为完整闭环能力已完成验收。
  • 当前已开始持久化内部知识文档与外部 provider document_id 的映射,knowledge-docs 删除链路也会优先使用外部 ID;其中 Dify 已恢复为可基于外部 document_id 执行精准删除,但 WeKnora 仍缺真实删除实现,因此目前只有 Dify 可以对外声明 deletion capability 已恢复,WeKnora 仍不可以。
  • 当前已补 scripts/test-weknora-integration.sh 的证据输出能力:可通过 WEKNORA_ACCEPTANCE_MODE=mock|realEVIDENCE_DIR=... 生成 summary.txtai-status.jsonai-query.jsonknowledge-provider-disable.jsonai-status-after-disable.jsonai-query-after-disable.jsonai-metrics-after-fallback.jsonknowledge-provider-enable.jsonai-status-after-enable.jsoncircuit-breaker-reset.jsonknowledge-upload.jsonknowledge-sync.json 等验收留档;其中 real 模式当前主要服务于 WeKnora 兼容路径,会把 “WeKnora 健康可用 + AI 服务具备外部 knowledge provider 能力 + 控制面切换成功 + fallback 查询成功 + upload/sync 成功” 作为硬性通过条件。
  • 当前已新增 scripts/test-dify-integration.sh:可通过 DIFY_ACCEPTANCE_MODE=mock|realEVIDENCE_DIR=... 生成 summary.txtdify-dataset.jsonai-status.jsonai-query.jsonknowledge-upload.jsonknowledge-sync.jsonai-metrics.json 等主路径验收留档;其中 real 模式要求当前激活 provider 为 dify,且 Dify dataset 健康、主路径 upload/sync 成功。
  • 当前 real 模式还会主动拒绝 localhost / 私网地址,以及健康检查中显式暴露 service=weknora-mock 的上游,避免把本地 mock 环境误填成真实 WeKnora 兼容路径运行证据。
  • LoadConfig() 现已补默认搜索 ...../..,避免从 apps/server 启动时读不到仓库根配置,导致验收口径和实际部署口径漂移。
  • 当前仍不能据此推出 G1-2G1-4 已完成,它们需要各自独立验收与证据回填。

一票否决项

以下任何一项失败,都不能对外宣称“已完成”:

  • 服务无法启动。
  • 数据库迁移失败。
  • 核心路由返回 500 或返回结构与契约不符。
  • 创建后无法查询,或更新后状态不变化。
  • 鉴权与权限中间件失效。
  • 外部 knowledge provider 不可用时没有回退或错误不可控。
  • 关键流程只有 happy path,没有异常路径验证。

全量验收矩阵

以下清单按代码实际暴露的功能面整理,主要依据:

1. 基础运行与可观测性

代码入口:

功能项入口验收步骤预期结果自动化证据状态
健康检查GET /health服务启动后直接请求200 且返回健康信息health_enhanced_test.go通过
就绪检查GET /ready在依赖就绪后请求200;依赖异常时不应误报健康health_enhanced_test.go通过
Prometheus 指标GET <metricsPath>启动后访问 metrics返回文本指标;包含 runtime/AI/DB 指标ai_handler.go通过
安全基线严格校验make security-check CONFIG=...使用部署配置执行校验无 warning 时返回 0;有高风险配置时非零退出check_security_baseline_test.go通过
可观测性基线严格校验make observability-check CONFIG=...使用部署配置执行校验metrics/tracing 配置与 dashboard/alert/runbook/collector 资产齐备时返回 0check_observability_baseline_test.go通过
发布前最小自检make release-check CONFIG=./config.yml执行统一自检脚本local/security/observability/focused Go tests 全部通过check-release-readiness.sh通过
CLI 标准构建make build执行构建生成二进制,无编译错误make build通过
CLI knowledge provider compatibility 构建make build-knowledge-provider执行构建生成二进制,无编译错误make build-knowledge-provider通过
本地最小环境检查make local-check执行环境校验脚本所有关键依赖通过Makefile通过

2. 实时能力

代码入口:

功能项入口验收步骤预期结果自动化证据状态
WebSocket 建连GET /api/v1/wssession_id 建立连接成功升级协议,可收发消息websocket_test.go通过
WebSocket 统计GET /api/v1/ws/stats建连前后各请求一次client 数量正确变化websocket_processing_test.go通过
WebRTC 统计GET /api/v1/webrtc/stats建立会话后请求返回连接统计webrtc_stats_test.go通过
WebRTC 连接列表GET /api/v1/webrtc/connections建立多连接后请求返回当前连接列表webrtc_test.go通过
平台消息路由统计GET /api/v1/messages/platforms模拟不同平台消息后请求平台维度统计正确router_stats_test.gomessage_handler_test.go通过

3. AI 与外部知识库

代码入口:

功能项入口验收步骤预期结果自动化证据状态
AI 查询POST /api/v1/ai/query发起普通问题请求返回回答,结构稳定ai_handler_comprehensive_test.go通过
AI 状态GET /api/v1/ai/status请求状态接口返回 AI 服务当前状态ai_handler_test.go通过
AI 指标GET /api/v1/ai/metrics调用多次查询后请求query count、latency 等可见ai_handler_comprehensive_test.go通过
知识上传POST /api/v1/ai/knowledge/upload上传合法文档上传成功并返回任务或文档信息ai_handler_comprehensive_test.goai_scoped_handler_test.go部分通过
知识同步POST /api/v1/ai/knowledge/sync触发同步返回同步结果,无 500ai_handler_comprehensive_test.goai_scoped_handler_test.go部分通过
启用 Knowledge ProviderPUT /api/v1/ai/knowledge-provider/enable启用外部知识增强能力状态切换成功ai_handler_comprehensive_test.go通过
禁用 Knowledge ProviderPUT /api/v1/ai/knowledge-provider/disable禁用外部知识增强能力状态切换成功ai_handler_comprehensive_test.go通过
熔断器重置POST /api/v1/ai/circuit-breaker/reset先制造失败再重置熔断状态恢复ai_handler_comprehensive_test.go通过
外部 Knowledge Provider 不可用回退AI 查询主链路关闭当前 knowledge provider 或制造超时系统进入 fallback,而不是整体不可用orchestrated_ai_fallback_integration_test.go通过
pgvector 自建知识库knowledge.provider=pgvector配置 pgvector 并执行查询向量检索正确返回结果pgvector_provider_test.go未验

3A. 认证与会话

代码入口:

功能项入口验收步骤预期结果自动化证据状态
登录与 refresh token 轮转POST /api/v1/auth/login POST /api/v1/auth/refresh登录后刷新 token,再尝试复用旧 refresh token返回 access/refresh token,新 token 生效,旧 refresh token 失效;真实留档已生成 manifest.jsonauth-refresh.jsonauth-refresh-reuse-old.jsonauth_service_test.goauth_handler_test.gotest_auth_session_acceptance_test.gomanifest.json通过
当前会话列表GET /api/v1/auth/sessions登录后查看当前用户会话返回会话列表、当前会话标记和基础风险字段;真实留档已生成 auth-sessions-before.jsonauth-sessions-after-logout-others.json,证明退出其它会话前后状态变化auth_handler_test.gotest_auth_session_acceptance_test.gomanifest.json通过
退出当前会话/其它会话POST /api/v1/auth/sessions/logout-current POST /api/v1/auth/sessions/logout-others执行自助登出当前或其它会话被正确失效;真实留档已生成 auth-logout-others.jsonauth-logout-current.jsonauth-sessions-after-logout-current.json,覆盖其它设备注销与当前 token 失效反证auth_handler_test.goauth_service_test.gotest_auth_session_acceptance_test.gomanifest.json通过

4. 客户管理

代码入口:customer_handler.go

功能项入口验收步骤预期结果自动化证据状态
创建客户POST /api/customers提交合法客户资料创建成功,返回 IDcustomer_handler_test.go通过
客户列表GET /api/customers创建若干客户后查询支持列表和筛选customer_handler_test.go未验
客户统计GET /api/customers/stats准备不同客户样本后查询返回统计信息正确customer_service_test.go通过
客户详情GET /api/customers/:id查询已存在客户返回正确详情customer_handler_test.go通过
更新客户PUT /api/customers/:id更新字段后重新查询数据被持久化customer_handler_test.go通过
活动轨迹GET /api/customers/:id/activity产生客户相关活动后查询轨迹完整、排序正确customer_handler_test.go未验
添加备注POST /api/customers/:id/notes添加备注后重查备注被记录customer_handler_test.go通过
更新标签PUT /api/customers/:id/tags更新标签后重查标签覆盖或合并符合设计customer_handler_test.go通过

5. 客服管理

代码入口:agent_handler.go

功能项入口验收步骤预期结果自动化证据状态
创建客服POST /api/agents提交合法资料创建成功agent_handler_test.go未验
客服列表GET /api/agents创建后查询返回客服列表agent_handler_test.go通过
在线客服列表GET /api/agents/online切换在线离线状态后查询仅返回在线客服agent_handler_extended_test.go通过
客服统计GET /api/agents/stats准备不同负载样本后查询统计值正确agent_service_more_test.go通过
查找可用客服GET /api/agents/find-available准备多个客服状态返回最合适客服agent_service_assignment_test.go未验
更新状态PUT /api/agents/:id/status更新在线/忙碌状态状态持久化agent_handler_test.go通过
上下线切换POST /api/agents/:id/online POST /api/agents/:id/offline调用接口并重查状态切换正确agent_handler_test.goagent_handler_extended_test.goagent_service_more_test.go通过
会话分配/释放POST /api/agents/:id/assign-session POST /api/agents/:id/release-session分配后查看客服负载负载变化正确agent_service_assignment_test.go未验

6. 工单

代码入口:ticket_handler.go

功能项入口验收步骤预期结果自动化证据状态
创建工单POST /api/tickets提交合法工单创建成功,返回 IDticket_handler_test.go通过
批量更新工单POST /api/tickets/bulk批量更新多个工单返回批量结果,数据一致ticket_handler_test.gocommand_service_test.go通过
工单列表GET /api/tickets创建后查询支持筛选和分页query_service_test.goticket_handler_test.go通过
导出工单 CSVGET /api/tickets/export准备样本后导出下载成功,字段完整ticket_handler_test.go通过
工单统计GET /api/tickets/stats准备不同状态工单后查询统计值正确query_service_test.gohandler_adapter_test.go通过
工单详情GET /api/tickets/:id查询已存在工单返回正确详情ticket_handler_test.go通过
更新工单PUT /api/tickets/:id更新标题、优先级、状态数据被持久化ticket_handler_test.gocommand_service_test.go通过
指派工单POST /api/tickets/:id/assign指派给客服负责人变化正确ticket_handler_test.go通过
添加评论POST /api/tickets/:id/comments添加评论后重查评论可读出ticket_handler_test.gocommand_service_test.go通过
关闭工单POST /api/tickets/:id/close关闭后重查状态变为关闭,关闭时间正确ticket_handler_test.gocommand_service_test.go通过

6A. 会话工作台

代码入口:

功能项入口验收步骤预期结果自动化证据状态
会话详情GET /api/omni/sessions/:id查询已存在会话返回正确会话详情与状态conversation_workspace_handler_test.go部分通过
消息列表GET /api/omni/sessions/:id/messages查询会话消息返回按时间顺序排列的消息列表conversation_workspace_handler_test.go部分通过
发送消息POST /api/omni/sessions/:id/messages在工作台发送消息消息写入持久层并触发 realtime 推送conversation_workspace_handler_test.go部分通过
指派会话POST /api/omni/sessions/:id/assign指派客服接管返回成功并更新会话归属conversation_workspace_handler_test.go部分通过
转接会话POST /api/omni/sessions/:id/transfer转接到另一位客服返回成功并更新转接结果conversation_workspace_handler_test.go部分通过
关闭会话POST /api/omni/sessions/:id/close关闭当前会话会话状态切为 closedconversation_workspace_handler_test.go部分通过

7. 会话转接

代码入口:session_transfer_handler.go

功能项入口验收步骤预期结果自动化证据状态
转人工POST /api/session-transfer/to-human发起 AI 到人工转接进入等待或转接成功session_transfer_handler_test.go未验
指定客服转接POST /api/session-transfer/to-agent指定客服转接记录目标客服并更新状态session_transfer_handler_test.go未验
查询转接历史GET /api/session-transfer/history/:session_id转接后查询历史历史完整可追溯session_transfer_handler_test.go未验
查询等待队列GET /api/session-transfer/waiting制造排队后查询返回等待记录session_transfer_handler_test.go未验
取消等待POST /api/session-transfer/cancel取消等待记录队列移除成功session_transfer_handler_test.go未验
处理排队POST /api/session-transfer/process-queue触发处理有可用客服时完成派发session_transfer_handler_test.go未验
自动转接检查POST /api/session-transfer/check-auto构造触发条件后执行符合策略的会话被处理session_transfer_handler_test.go未验

8. 满意度与公开问卷

代码入口:

功能项入口验收步骤预期结果自动化证据状态
创建满意度记录POST /api/satisfactions提交评价创建成功satisfaction_handler_test.go未验
满意度列表GET /api/satisfactions创建后查询返回列表和筛选结果satisfaction_handler_test.go未验
满意度统计GET /api/satisfactions/stats准备多样本后查询聚合结果正确satisfaction_handler_test.go未验
调查列表GET /api/satisfactions/surveys查询调查任务返回调查清单satisfaction_handler_test.go未验
重发调查POST /api/satisfactions/surveys/:id/resend重发问卷任务状态更新satisfaction_handler_test.go未验
查看满意度详情GET /api/satisfactions/:id查询单条记录返回正确详情satisfaction_handler_test.go未验
更新满意度PUT /api/satisfactions/:id修改评分或备注数据更新成功satisfaction_handler_test.go未验
删除满意度DELETE /api/satisfactions/:id删除后重查记录不可再读satisfaction_handler_test.go未验
按工单查询满意度GET /api/tickets/:id/satisfaction工单已有评价时查询返回对应满意度satisfaction_handler_test.go未验
公开问卷查看GET /public/csat/:token使用有效 token 访问返回问卷内容csat_public_handler.go通过
公开问卷提交POST /public/csat/:token/respond提交问卷响应返回成功并持久化csat_public_handler.go通过

9. 工作台、宏、集成、自定义字段

代码入口:

功能项入口验收步骤预期结果自动化证据状态
工作台概览GET /api/omni/workspace请求工作台概览返回聚合视图workspace_handler_test.goworkspace_service_test.go通过
宏列表/创建/更新/删除/应用/api/macros 系列依次执行 CRUD 与 apply规则可持久化且可实际应用macro_handler_test.go未验
应用集成列表/创建/更新/删除/api/apps/integrations 系列执行 CRUD集成配置生效并可回读app_market_handler_test.go未验
自定义字段列表/详情/创建/更新/删除/api/custom-fields 系列执行 CRUD字段定义持久化并可用于工单等实体custom_field_handler_test.go未验

10. 统计、SLA、排班

代码入口:

功能项入口验收步骤预期结果自动化证据状态
仪表盘统计GET /api/statistics/dashboard准备样本数据后查询返回聚合概览statistics_handler_test.gostatistics_service_test.go通过
时间范围统计GET /api/statistics/time-range指定日期范围查询返回按时间切片聚合statistics_service_test.gostatistics_handler_test.go通过
客服绩效统计GET /api/statistics/agent-performance准备客服样本后查询返回绩效排序statistics_service_test.go未验
工单分类统计GET /api/statistics/ticket-category准备不同分类工单分类聚合正确statistics_handler_test.go未验
工单优先级统计GET /api/statistics/ticket-priority准备不同优先级工单优先级聚合正确statistics_handler_test.go未验
客户来源统计GET /api/statistics/customer-source准备不同来源客户来源聚合正确statistics_handler_test.go未验
每日统计更新POST /api/statistics/update-daily指定日期触发更新更新成功且可被后续查询读到statistics_service_test.go未验
SLA 配置 CRUD/api/sla/configs 系列执行配置增删改查配置生效并可回读sla_handler_test.go通过
SLA 优先级配置查询GET /api/sla/configs/priority/:priority查询指定优先级返回正确规则sla_handler_test.go通过
SLA 违约列表GET /api/sla/violations准备违约工单后查询返回违约记录sla_handler_test.go通过
SLA 违约解决POST /api/sla/violations/:id/resolve解决违约后重查状态变化正确sla_handler_test.go通过
SLA 统计GET /api/sla/stats准备样本后查询返回 SLA 统计视图sla_handler_test.go通过
工单 SLA 检查POST /api/sla/check/ticket/:ticket_id对指定工单执行检查返回 SLA 判定结果sla_handler_check_ticket_test.go通过
排班 CRUD 与统计/api/shifts 系列创建、查询、更新、删除、统计排班记录和统计正确shift_handler_test.go未验

10A. 审计与安全

代码入口:

功能项入口验收步骤预期结果自动化证据状态
用户安全态查询GET /api/security/users/:id查询指定用户安全状态返回 user_idrolestatustoken_version 等字段user_security_handler_test.go通过
用户 token 失效POST /api/security/users/:id/revoke-tokens触发旧 token 失效token_version 增加,后续状态可回读user_security_handler_test.go通过
用户会话列表GET /api/security/users/:id/sessions查询指定用户会话返回会话列表或空列表,结构稳定user_security_handler_test.go通过
审计日志列表GET /api/audit/logs按 action 等条件查询返回审计记录列表及分页信息audit_handler_test.go通过
审计日志详情GET /api/audit/logs/:id查询单条审计记录返回指定审计记录audit_handler_test.go通过
审计日志差异预览GET /api/audit/logs/:id/diff查看变更 diff返回变更路径或明确无差异audit_handler_test.go通过
审计日志导出GET /api/audit/logs/export导出过滤后的日志返回 CSV 内容audit_handler_test.go通过

11. 自动化、知识库、辅助建议、激励

代码入口:

功能项入口验收步骤预期结果自动化证据状态
自动化触发器列表/创建/删除/api/automations 系列执行 CRUD触发器生效并可管理automation_handler_test.go未验
自动化运行记录GET /api/automations/runs触发自动化后查询可查看运行结果automation_service_more_test.go未验
自动化批量运行POST /api/automations/run触发批量运行返回执行结果,失败项可见automation_service_more_test.go未验
知识文档 CRUD/api/knowledge-docs 系列执行 CRUD文档可持久化;在已启用且支持对应能力的 knowledge provider 下,创建/更新会同步外部索引,删除若不支持则显式失败knowledge_doc_handler_test.goservice_test.go部分通过
公开知识库查询/public/kb/docs 系列访问公开知识文档可读且权限边界正确knowledge_doc_handler_test.go通过
辅助建议GET /api/assist/suggest POST /api/assist/suggest传入上下文获取建议返回建议结果suggestion_handler_test.go未验
激励排行GET /api/gamification/leaderboard准备积分样本后查询排名正确gamification_handler_test.go未验

12. 语音

代码入口:voice_handler.go

功能项入口验收步骤预期结果自动化证据状态
协议列表GET /api/voice/protocols请求协议列表返回已注册协议voice_handler_test.go通过
协议信令事件POST /api/voice/protocols/:protocol/call-events/:event发送 invite/answer/hangup 等事件事件被正确映射和处理voice_handler_integration_test.go通过
协议媒体事件POST /api/voice/protocols/:protocol/media-events/:event发送媒体事件媒体状态正确更新voice_handler_integration_test.go通过
开始录音POST /api/voice/recordings/start启动录音返回 recording IDservice_test.go通过
停止录音POST /api/voice/recordings/stop停止录音后查询录音状态完成recording_service_test.go通过
获取录音GET /api/voice/recordings/:recordingID查询录音详情返回录音元数据recording_service_test.go通过
转写追加POST /api/voice/transcripts追加语音转写片段转写被保存transcript_service_test.go通过
转写列表GET /api/voice/transcripts追加后查询返回转写内容transcript_service_test.go通过

权限与异常路径必须额外验

即使主流程通过,也不能直接判定完成,还必须补下面这些:

  • 未登录访问 /api/* 是否被正确拦截。
  • 权限不足访问不同资源是否返回正确错误。
  • 非法参数是否返回 400 而不是 500
  • 查不存在 ID 是否返回 404 或明确错误。
  • 外部依赖失败时是否有降级、重试或熔断行为。
  • 重复提交、并发操作、幂等等是否符合预期。

相关入口见 router.go 中的鉴权与资源权限中间件注册。

建议的验收执行顺序

  1. 环境级:make migratemake buildmake build-knowledge-provider、服务启动。
  2. 存活级:/health/ready、metrics。
  3. 核心业务级:客户、客服、工单、会话转接。
  4. 增值能力级:AI、知识库、自动化、统计、SLA。
  5. 扩展能力级:语音、公开问卷、公开知识库。
  6. 负向与权限级:未授权、非法参数、外部依赖失效。

对外宣称“已完成”的最低门槛

至少满足以下条件,才能说“该模块完成验收”:

  • 核心路由的 happy path 与异常路径都跑通。
  • 自动化测试能覆盖该模块主要读写路径。
  • 数据落库、状态流转、导出或副作用经过实际核验。
  • 对应条目在本清单中被逐项标记为 通过,并附证据。

否则,最多只能说:

  • “代码入口已存在”
  • “构建已通过”
  • “部分测试已通过”
  • “功能仍待联调/待验收”