lzf_0626
|
076d786bc6
|
补齐客服转人工工单流:从"只能看"到"能推进"(基线状态机,不自行发明)
## 问题
`svc_handover_ticket` 的 DDL 与状态机在 `docs/02` §7.2 早就定好了
(pending → assigned → processing → resolved → closed,未解决可 cancelled),
但平台**只有 handover:read(只读队列)**:没有任何入口能改状态、assigned_to /
accepted_at / resolved_at / closed_at / resolution 五列**全库 0 非空**,
于是 40 张工单永远停在 pending —— 用户看到的就是"工单全都长一样"。
## 改了什么
后端:
- 新增 `app/service/customer_service_handover_action_service.py`:五个动作
(分配/接单/解决/关闭/取消),`SELECT ... FOR UPDATE` 锁单后判状态;
接单允许从 pending 自助接管(同时记受理人);取消不写 closed_at(该列属 closed 状态);
每次流转写一条 interaction_audit(handover.assigned/accepted/resolved/closed/cancelled);
非法流转 409、坐席不存在 422、工单不存在 404;回包不含 customer_id/session_id。
- 只读服务保持只读(读侧与写侧是两条边界,单测守着"读侧不许长出写方法"),
但列表支持 `?status=` 六态筛选、详情补上受理人与流转时间(坐席侧路由信息,非客户数据)。
- `app/api/controllers/admin.py`:五个 action 端点 A049–A053
(assignments / acceptances / resolutions / closures / cancellations),
走 `ApiTransactionService.execute_in` —— 幂等记录与业务写入同事务、重复键回放。
- 权限:新增 `handover:write`(9069,只授 admin),已并进种子
`tools/seed_test_rbac.py`;配套幂等脚本 `tools/grant_handover_write_permission.py`。
前端(管理员工作台 · 转人工工单页):
- 按状态给按钮(待处理→分配/直接接单、已分配→接单、处理中→解决、已解决→关闭、
未解决都可取消),加了状态筛选与"刷新";摘要弹窗补上受理人与四个时间点、处置结论。
- api-client 注册五个端点;workspace.js 的 api-client 引用与页面自身的 ?v= 一并升版,
避免浏览器拿旧缓存(旧缓存里没有这些端点)。
冒烟与测试:
- `tools/e2e_smoke_test.py`:B 段建的测试工单由 F 段走完 分配→接单→解决→关闭 收尾
—— 既不再把测试件堆在 pending 队列里(此前每次冒烟攒一张),又让每次冒烟都覆盖一遍状态机。
总数 40 → 44 项,实测 44/44 全绿。
- 新增单测 24 条(状态机合法/非法路径、越权、坐席不存在、审计、视图不泄漏客户标识)
与一条真机集成用例(HTTP 十步 + 数据库侧审计证据 + 自动清理)。
- 读侧那条"详情不得返回 assigned_to"的旧断言按新口径更新,并写清为什么。
## 验证
- `pytest tests/unit tests/contract` → 1489 passed, 2 skipped, 0 failed
- 新增集成用例通过;`tests/integration` 全量跑时
`test_memory_extraction` / `test_run_cancellation_mysql` 两条偶发红 —— 单独跑都通过,
是 AGENTS.md 已登记的"常驻 Worker 抢队列"(跑验收前须先停 Worker)
- `tools/portal_api_check.py` → 41 项通过 39、失败 0
- `tools/e2e_smoke_test.py` → 44/44 全通过
- `python tools/check_rbac_seed_consistency.py` → 通过(种子 63 条权限)
- 真机 HTTP 实测:分配→接单→解决→关闭四步 200 且时间戳齐全;取消路径 200 且 closed_at 为空;
同键重发回放不二次推进;对已关闭工单再分配 409;风控账号处置 403
## 文档
`docs/44-演示流程.md`(场景 4/8 + 命令 + 44 项)、`docs/演示用/后端接口文档`(新增 §11.4b 与
A049–A053)、`docs/演示用/全功能流程-大白话版.md`(工单页签改"读写"+ 已知偏差)、
`AGENTS.md`(9066-9069 号段演进 + 冒烟 44 项)
|
2026-09-15 00:41:59 +08:00 |
|
lzf_0626
|
daf73a2865
|
fix(portal): 照接口逐条核对前端,修掉 5 处「照着表结构写、看着像对」的缺陷
做法:把前端 `api-client.js` 注册的端点**按前端完全相同的方式**(同样的路径、参数、
身份)逐个调用,再拿真实返回去核对前端 render 用到的字段。
**这类问题纯读代码看不出来** —— 只有把真实返回和期望字段摆在一起才会暴露。
## 1. 知识库功能实际是坏的(K002 / K003 是裸信封)
`K002` 的成功体是 `{knowledge_ids, filename, chunk_count}`、`K003` 是 `{items, count}`,
**都没有 `data` 信封**。而 `request()` 默认取 `payload.data`(undefined),于是:
- 上传后前端显示「已入库 **0** 块」,而库里其实切了 23 块;
- 列表永远显示「知识库为空」。
端点表里标 `raw: true` 后(与 `V001` 同一做法)两者都正常。
实测:上传 4805 字符的产品手册 → 切 23 块并出现在列表里。
## 2. 委托/成交详情页有 5 行永远显示「--」
前端按 `fin_sim_order` / `fin_transaction` 的**建表字段**写了 `quote_source`、
`nav`、`fee_rate_snapshot`、`confirmed_at`、`auto_confirmed` ——
但这些字段**接口的返回视图没有带**(表里有、返回里没有)。已按实际返回重写字段表,
并在注释里写明"以接口返回为准,不要照表写"。
## 3. 配置项与路由规则的**编辑功能不可能成功**(接口缺口)
`PUT` 硬性要求 `If-Match`,校验的是该行内容的 digest;而这两个资源是 `detail=False`
—— **没有任何端点能返回这个 digest**(列表的 `meta` 只有 trace_id)。
乐观并发在"读不到版本"的前提下等于死锁:**首次编辑必然 409**。
(配置发布能用,是因为它有详情端点 `A003`。)
- 新增详情端点 `A048` / `A049`(`detail=True`),已登记 `docs/05` §19;
- 前端编辑前先 GET 详情取 etag,再带 `If-Match` 提交。
- 实测:编辑配置项与路由规则均 200;**不带 `If-Match` 仍返回 409**,
说明乐观并发没有被削弱。
## 4. 路由规则表单**必然提交失败**
前端固定写 `max_attempts: 2` 且 `fallbacks: []`,而后端要求
`max_attempts ≤ 端点总数`(主 + 兜底)→ 422「重试次数超过端点数量」。
改为 `1` 并注明约束。
## 5. 主端点手填 ID 会 422
后端对不存在/未激活的 `primary_endpoint_id` 直接 422「模型端点不存在或未激活」。
把输入框改成**下拉**,只列 `status='active'` 的端点(数据复用已有的端点列表)。
## 顺带
- `apiClient` 增加 `del()` / `put()`:发出的方法一直由端点表决定,所以 `post('K004')`
也能发 DELETE —— 语义太绕,现在意图与行为一致。
- 清理了测试期间上传的 31 条知识残留(客服会检索到它们),库内恢复到 23 条产品手册。
## 关于"逐条核对"的方法论
前两轮跑出来的 9 个和 5 个"失败"里,**多数是我测试脚本自己的假设错了**,不是前端问题:
`T001` 是 `{account, summary}` 嵌套、`RK002` 的字段叫 `risk_level`、
`RK002/RK004/RK005` 的 limit 上限是 5/10/10(前端传的正是 5/10/10)、
`AD011/A002/A047` 的 data 是裸 list。每一处都回到前端源码确认后才下结论 ——
**先把"我以为"改成"代码里写的"**,否则报告出去的就是假 bug。
验证:unit+contract **1397 passed**;integration **110 passed**;ruff 通过;
mypy 251 文件 0 错;§19 现 93 个端点无重复;e2e 冒烟 **40/40**。
前端等价测试:只读 31 项全绿、写操作(含 ETag 链路)9 项 8 绿 1 项因测试数据过短。
|
2026-09-14 01:19:22 +08:00 |
|
张胜宇
|
ef701c844c
|
merge: integrate ZSY customer service and profile capabilities
|
2026-09-11 22:31:51 +08:00 |
|
张胜宇
|
a769130658
|
feat: add profile candidate review workflow
|
2026-09-11 17:47:06 +08:00 |
|
Windows
|
852bafb374
|
feat: add profile drift governance workflow
|
2026-09-11 16:42:31 +08:00 |
|
张胜宇
|
ef098e6a4b
|
feat: complete customer service safety and handover flow
|
2026-09-11 16:11:30 +08:00 |
|
Windows
|
13bb4f257d
|
feat: add allocation backtest evidence
|
2026-09-11 15:08:37 +08:00 |
|
lzf_0626
|
6516ccb385
|
feat: 第二版——接口契约对齐 docs/05,修复静默故障与数据库基线
相对第一版 46fc976 的完整变更。组员迁移对照表见 docs/20。
一、对外契约对齐 docs/05(破坏性,共 4 处,组员需按 docs/20 调整)
1) 配置发布端点改为文档规定的复数资源名:submit→validations、
approve→reviews(需 body decision)、activate→activations、
rollback→rollbacks;第一版这 4 个动词式路径 docs/05 从未定义过。
2) 错误码由 8 个笼统码改为 15 个具体语义码(FORBIDDEN→AGENT_PERMISSION_DENIED、
UNAUTHORIZED→AUTHENTICATION_REQUIRED、CONFLICT→RESOURCE_VERSION_CONFLICT、
RESOURCE_NOT_FOUND→RUN_NOT_FOUND/SESSION_NOT_FOUND 等),
输入类错误状态码 400→422。
3) POST /api/v1/agent-runs 与 GET /api/v1/agent-runs/{run_id} 统一为
{data, meta} 信封(data 内字段名与语义未变)。
4) 错误响应体统一为 {error:{code,message,retryable,field_errors}, meta:{trace_id}},
不再返回 FastAPI 默认的 {"detail": ...}。
二、数据库基线与约束
新增 39 张表的基线迁移(链根)与联合唯一键纠偏(4 张表、删 8 增 4,幂等收敛);
撤下 config_release 的双人复核 CHECK(应用层已允许自审,审核节点保留,
自审如实写入 reviewer_id);记忆 active key 生成列与唯一键;
activate 开始记录 supersedes_release_id 使版本链可追溯。
docs/00 基线未修改,未重命名或删除任何表与字段。
三、修复会静默出错或无报错的缺陷
- 跑完集成测试后平台会静默失去生效配置:清理只删自己创建的版本,却没有恢复被它
顶成 superseded 的原生效版本,且审计一并删除因而完全无痕,表现为所有工具被拒
但没有任何报错。已修清理逻辑并加恢复。
- Worker 单轮异常导致进程退出;记忆抽取调用方的“事务已开始”异常;
召回缓存丢失 degraded 标记;连接时区未生效导致 created_at/updated_at 差 8 小时;
.env 与 os.getenv 密钥来源分裂导致“没有可用的已批准模型端点”。
- 记忆信号识别漏判与跨键误命中;SSE 未带 Accept 的协商行为。
四、功能补齐
记忆链路 P1/P2/P3(抽取、受控词表、召回与缓存、生命周期级联及投影事件)、
fin_* 场内交易只读 ORM 层、agent_intent_config 状态流转并在运行期真正生效、
限流(Redis 固定窗口、故障一律放行)、游标校验、trace_id 中间件、
示例业务 Agent fund_query_demo 与一键端到端验证脚本,以及审计/指纹/迁移状态工具。
五、文档与验证
新增 docs/19(业务 Agent 接入实操)、docs/20(第一版迁移指南)与 docs/evidence 证据;
docs/01/02/06/08/09/17 同步实现现状。
验证结果:ruff 通过、mypy 103 文件无错、unit+contract 447 passed、
integration 29 passed、acceptance_check --production 7 PASS、
demo_agent_e2e 9/9 PASS(含失败关闭反证)。
|
2026-09-10 15:55:54 +08:00 |
|
Codex
|
b1497fd2c6
|
chore: initialize project repository
|
2026-09-09 21:55:37 +08:00 |
|