张胜宇
e0992c663e
feat(demo): 新增演示一键启动脚本(demo.ps1 + 启动演示.bat)
...
演示真正要做的事只有一件:**把要看的前端页面按顺序打开,并确认环境真的就绪**。
原先只有 `start.ps1`(起服务),演示前还得手工跑行情刷新与五项自检,容易漏。
本次新增:
- `start.ps1`:不动(它已经幂等,缺什么补什么,重复执行不会起第二个 API/Worker)。
- `demo.ps1`:在 start.ps1 之上补三件事 ——
① **刷新行情**:下单要求行情快照落在 15 分钟有效期内(`trade_service.MAX_QUOTE_AGE`),
过期后所有委托直接 503,而系统没有自动刷新机制;
② **五项自检**:口径与 `客服agent/D2.5` §1 完全一致(容器三件套 / 向量库三集合计数 /
Worker 在跑 / 行情有效期 / `milvus_local_uri` 开关为空);
③ **打开演示页面**:访客页(客服浮窗主战场)+ 客户登录页。
另把「**登录限流 10 次 / 60 秒**,不要反复登录」这条最容易造成假故障的提醒印在「开讲前必看」。
- `启动演示.bat`(GBK,与本仓库既有 .bat 同编码):双击即用,参数透传给 demo.ps1。
实测(本机):`启动演示.bat -SkipStart -NoBrowser` 与完整路径(含调用 start.ps1)
均 **五项自检全过、退出码 0**。
排错留痕(避免后人改回去):Milvus 探测代码原本用 `& $Python -c $probe` 传参,
Windows PowerShell 5.1 传原生命令参数时会把内嵌双引号吞掉(报 `unterminated string literal`)
⇒ 改为经 **stdin** 传给 python,并在脚本里写明原因。
2026-09-20 15:02:53 +08:00
张胜宇
e5b4d02b0d
merge: 集成投顾组 3 个提交(解除与「投顾模块清除」的冲突)+ 客服 Agent 重构收口
...
## 为什么要合并
远端 `origin/qyqy_develop` 领先 3 个提交(`5607751` / `2fe7d0c` / `74b7d00`:投顾需求与架构文档、
客户主动申报投顾方案 + 受理自动出草稿、方案交付落点与推荐依据 LLM 增强),而本地 `5d0becb`
按 `D4.4` / `D4.5`(CS-PURGE-2026-012/013)把投顾模块整体清除了。**两个目标不可兼得**:
远端新代码反向 import 已被清除的模块(`app.model.investment_goal`、
`app.service.product_recommendation_service`、`app.service.advisor_rollout_service`),
强行推进只会让两边都跑不起来。
**裁定:投顾组的新功能 > 本地的投顾清除。** 依据是 `D4.4` §0-②③ 自己写下的风险
——按名字清投顾会同时拆掉产品数据底座与 MVP 硬阻断,并失去"改 6 个底座文件时的对照组"。
本次合并因此**恢复投顾模块**;就代码面而言,`D4.4` / `D4.5` 的清除结果被本次合并取代
(留痕见 `开发文档\D1.6` §4.37)。
## 冲突怎么解的(12 处)
- **8 处 modify/delete 取远端**:`recommendations.py` / `product_recommendation_service.py` /
`employee-advisor/dashboard/{actions-module.js,dashboard.css,dashboard.js,index.html}` /
`tools/{check_portal_modules.py,grant_advisor_role.py}` —— 即"我删、远端改",保留投顾文件。
- **3 处内容冲突取远端**:`app/main.py`(投顾 import 与 `include_router`)、
`common/api-client.js`(投顾端点表)、`tests/unit/api/test_portal_frontend.py`(4 条投顾前端契约)。
- **1 处取远端 + 保留我方**:`app/main.py` 解除冲突的同时,保留本轮的
`/customer-service-test` 挂载移除(该联调页与用例已随重构作废)。
## 因"取消清除"而必须回滚的语义改动(否则恢复出来的投顾代码跑不动)
- `app/service/agent/bootstrap.py`:恢复 `AdvisorAgent` 与 5 个投顾工具注册
(`query_investment_goal` / `analyze_portfolio` / `generate_asset_allocation` /
`recommend_products` / `compare_products`);客服 Agent 注释按本轮口径保留。
- `app/core/config.py`:恢复 `advisor_rollout_enabled` / `advisor_rollout_customer_ids`。
- `app/static/portal/common/layout/app-shell.js`:恢复投顾工作台导航与 `advisor` 角色名。
- `tools/seed_test_rbac.py`:恢复"admin 取全量元组"的授权模型(保留远端新增的
9070-9074 权限码与客户侧 9071/9072 绑定)。
- `tools/portal_api_check.py`:恢复投顾实测用例(AD003/AD005/AD011/A047 与 `advisor_t` 登录),
并**新增判定**:被渲染的集合为空(0 条)时判 `SKIP` 而不是 `FAIL`
—— "没有行"与"字段没带"是两回事,混报会把排查方向带偏。
- `app/static/portal/common/api-client.js`:以远端为基准,重新叠加本轮的
**访客令牌 `Authorization` 优先**修复(浮窗访客身份稳定性)。
## 数据库夹具同步(代码恢复 ⇒ 夹具也要恢复)
- `tools/grant_advisor_role.py`:新建 `advisor` 角色并授权(实测 34 项权限)。
- `tools/create_test_user.py --id 9020 --username advisor_t --role advisor`:重建演示账号。
## 集成期发现并修掉的过期断言
- `tests/unit/test_advisor_migration_contract.py`:alembic 末端钉死值仍是
`20260914_baseline_auto_increment`,而远端新增了 `20260916_advisor_service_request`
⇒ 这条断言**在远端分支上本身就是红的**。本次把它更新到新末端并补了注释。
## 验证(本机实测)
| 门禁 | 结果 |
|---|---|
| `pytest -q`(全量,含集成) | **1909 passed / 3 skipped / 0 failed** |
| `ruff check app tools tests` | 20(远端分支 22,本地仅客服线基线 19) |
| `mypy app` | 2(= 既有基线) |
| `tools/portal_api_check.py` | 40 项:通过 35 / 失败 0 / 跳过 5 |
| `tools/e2e_smoke_test.py --read-only` | 31/31 |
| `_eval_harness/http_probe.py` | 11/11 succeeded |
| `_consistency.py` | GATE PASS |
| `_fe_boundary_http.py`(前端入参边界真机) | 全部符合预期 |
## 未做(如实登记)
- **投顾演示数据未灌**:`AD011` / `A047` 需要 `advisor_product_suitability_reference`
这类带 `source_url` + `document_sha256` 的证据行,而披露文件不在仓库里;
`tools/seed_advisor_demo.py` 明确"不编证据"(fail closed),故这两条按空集 SKIP。
- **客服线文档目录仍未入库**:`客服agent/`、`开发文档/`(权威副本在本机)与
`_chunks_report.txt`(本地构建产物)依旧排除在提交之外。
2026-09-20 14:52:35 +08:00
张胜宇
5d0becb67d
客服 Agent 重构收口:五出口决策链 + 知识库档位隔离 + 前端入参边界(答辩演示版本)
...
一、客服 Agent 智能增强(正面回应"不智能、动不动就转人工")
- 决策链由 2 个出口扩到 5 个:E1 澄清 / E2 计算型 / E3 知识直返 / E4 证据约束生成 / E5 分级回退
- 转人工从"默认动作"降为最后一档 E5c,只保留 4 类白名单:
P0 反诈 / P1 账户与个人数据 / P2 写操作与争议 / 用户明确要求人工
- 46 条金标实测(修复前 → 修复后):
转人工率 43.5% → 10.9%;出口准确率 45.7% → 100%;事实正确率 69.6% → 100%
禁忌违反 1 → 0;档位越权 / 无出处数字 / 误拒 四项零容忍全 0
- 安全不变量 INV-1~INV-5;零容忍规则未删,改的是挂载点
(输出侧字面黑名单 → 检索层档位隔离 + 判定层合规词表 + 输出守护)
二、知识库:档位单点化与物理隔离
- 新增 app/core/knowledge_tier.py 作为档位规则唯一落点(G-03),
knowledge_contracts.py 原定义块改为显式再导出(X as X,非副本)
- 档位过滤由 bool 默认值(fail-open)改为 tiers 必填集合(缺参即 TypeError)
- Milvus 侧四集合按 visibility 分区键物理隔离;双 schema 收敛为一套
- 新增 app/core/actor.py:访客三元组与匿名判定的唯一构造/判定点(G-01/G-01b)
- 新增 app/core/fund_fee_rules.py:费率计算纯函数
三、前端入参边界对齐(本轮 W11 新修,4 处"校验宽于存储")
- message 加 max_length=8000(与浮窗 widget.js 的 maxlength 一致)
- session_id 加 1—64;idempotency_key 上限 128 → 64(对齐列宽 String(64))
- feedback_type 加 max_length=32(对齐列宽 String(32))
- 8 条路径参数补 min_length=1 + max_length=64 + 字符集正则
({session_id} / {run_id} / {handover_id})
- 改前超限值会落到 MySQL 才失败(500);改后一律 422 AGENT_INPUT_INVALID + 字段级定位
- 新增 tests/unit/api/test_frontend_boundaries.py(33 例),含"端点表 ↔ OpenAPI 全量对照"
四、投顾模块整体清除(D4.4 / D4.5)
- 删除投顾相关 controller / schema / model / repository / service 及门户页面
- tools/portal_api_check.py 同步作废 AD003/AD005/AD011/A047 四条用例与 advisor_t 登录
(端点与账号均已不存在,此前稳定报 3 条假红)
五、验证(提交前实测)
- pytest -q:1856 passed / 2 skipped / 0 failed
- ruff check app tools tests:19(= 基线);mypy app:2(= 基线)
- 前端接口契约体检 portal_api_check.py:38 项,通过 34,失败 0,跳过 4
- 全链路冒烟 e2e_smoke_test.py --read-only:31/31
- HTTP 全链路探针 http_probe.py:11/11 succeeded
- 跨文档一致性 _consistency.py:GATE PASS
- 真机边界复验 12 条:12/12 符合预期
六、纪律与文档
- 可改文件白名单 A-09(docs/46)与底座会签申请单 A-10(docs/47,组 1—组 4 全部受理)
- 零 DDL:未新增/修改任何表结构,89 张业务表与基线一致
- 证据留痕:docs/evidence/**(含 46 条金标 score、快照、清除与重建记录)
- 未提交(刻意排除,见提交说明):仓库内 客服agent/ 与 开发文档/ 是 2026-09-16 前的
过期副本(Todolist 440 行 vs 权威 D2.1 1167 行),权威正本在仓库外;
_chunks_report.txt 是 tools/build_knowledge_chunks.py 生成的本地产物
2026-09-20 14:33:30 +08:00
张胜宇
3134fe5dd0
Merge branch 'qyqy_develop' of http://47.106.207.27:3000/AI260626/group_fqcd_jr into qyqy_develop
2026-09-14 01:45:47 +08:00
张胜宇
f5d1b24618
merge qyqy_develop and retain risk review updates
2026-09-14 01:41:02 +08:00
张胜宇
5929eb151b
merge: integrate latest qyqy_develop changes
2026-09-13 23:10:46 +08:00
张胜宇
3325232e2a
feat(portal): complete advisor workspace operations
2026-09-13 23:04:35 +08:00
张胜宇
aa4b9bf367
Merge remote-tracking branch 'origin/qyqy_develop' into qyqy_develop
2026-09-13 19:26:31 +08:00
张胜宇
e3c316aafb
Enforce trading authorization and suitability checks
2026-09-13 19:24:59 +08:00
张胜宇
b9aafce120
Merge remote-tracking branch 'origin/qyqy_develop' into qyqy_develop
2026-09-13 18:33:34 +08:00
张胜宇
e740a58e9d
前端2
2026-09-13 18:31:38 +08:00
张胜宇
e38ece32bf
前端提交
2026-09-13 15:56:54 +08:00
张胜宇
0ee3e894e7
merge: integrate latest qyqy_develop + push docs/41
2026-09-12 17:14:36 +08:00
张胜宇
ebc3fe4cbe
feat(§T): 账户看板 + 场内模拟交易 9 端点(用户自助首版)
...
新增 §T 用户自助段(docs/05 §19 新号段 7 个 = A×40/C×7/K×4/M×4/O×3/R×4/T×9):
- T001 GET /api/v1/users/me/account/dashboard — 账户/资金/持仓/盈亏汇总
- T002 POST /api/v1/users/me/orders — 委托提交(首版 market 立即全额成交)
- T003 / T004 / T005 委托列表/详情/撤单
- T006 GET /api/v1/users/me/holdings — 持仓列表(含市值/盈亏/当日盈亏)
- T007 / T008 成交记录列表/详情
- T009 GET /api/v1/users/me/cash-ledger — 资金账本
要点(与 docs/00 §6.6 一致):
- 首版市价委托立即全额成交,不实现撮合队列/部分成交;T005 撤单首版对任何在场委托返回 ORDER_NOT_CANCELLABLE (409)
- 价格来源复用 base FundQuoteService;service 层不二次封装(满足 AGENTS 第 2 条)
- 首版风控 3 条硬性:产品可交易、客户适当性、持仓比例上限(fin_market_price 缺失或过期 → 拒绝买入)
- 数据库零修改:10 张 fin_* 表全部 docs/00 既定,本批 PR 改列类型与可空性均 0;底座实际偏差(id 无 AUTO_INCREMENT、所谓'生成列'是普通 NOT NULL)由 service _next_id / 业务派生值补偿
注册 API:9 端点均注册进 app.main;user=9001(cust)'s id 写账
权限码(tools/seed_test_rbac.py 同步登记 + CUSTOMER 全量):
9047 account:read:self
9048 trade:order:create
9049 trade:order:read
9050 trade:order:cancel
9051 holding:read:self
9052 trade:txn:read
错误码(app/core/errors.py + docs/05 §3.6 + tests/unit/core/test_errors.py DOCUMENTED 三方同步):
404 ACCOUNT_NOT_FOUND / ORDER_NOT_FOUND
409 ORDER_NOT_CANCELLABLE
422 INSUFFICIENT_FUNDS / INSUFFICIENT_HOLDING / HOLDING_RATIO_EXCEEDED / SUITABILITY_MISMATCH / PRODUCT_NOT_TRADABLE
503 FUND_QUOTE_UNAVAILABLE(可重试)
新增:app/api/controllers/trading.py / app/api/schemas/trading.py / app/service/trade_service.py / tools/seed_sim_account_demo.py / tests/unit/service/test_trade_service.py(unit×8) / tests/contract/test_trading_endpoint_contract.py(contract×11)
修改:app/main.py(挂载 controller) / app/core/errors.py(10 新异常类) / tools/seed_test_rbac.py / docs/05-接口文档.md(§19 T001-T009 + §3.6 9 新码) / tests/unit/core/test_errors.py(DOCUMENTED 同步)
门禁:pytest tests/unit tests/contract 1313 passed (+19 新增) / ruff all clean / 三道守卫全过
2026-09-12 15:50:37 +08:00
张胜宇
c5adf01603
test: 补端点编号守卫与权限判定的 HTTP 层用例
...
补两道守卫,覆盖 2026-09-12 那次合并评审暴露出来的两个盲区。
一、`docs/05` §19 端点编号唯一性(新增 `tools/check_docs_endpoint_ids.py`)
- 背景:`tools/check_authoritative_docs.py` 只校验 `docs/` 的**文件名编号**,不校验
§19 的**端点编号**。两条线各自新增端点时都占了 `A034`/`A035`,合并后 §19 同时
存在两个 `A034` 与两个 `A035`,而文档守卫照样通过 —— 编号复用会静默遗留。
- 口径要点:**不枚举前缀白名单**,前缀从数据里归纳后连同数量一起输出。同一件事上
还踩过一次"扫描正则写成 `[AMKCS]`,漏掉 `O`/`R` 两段,把 62 个端点报成 55 个"——
漏掉的号段一旦被复用,脚本仍会报"重复 0"。所以覆盖报告会打印
`62 个端点编号 / 6 个号段(A×40、C×7、K×4、M×4、O×3、R×4)`,让漏扫本身可见。
- 只读、不依赖任何环境变量(纯解析文档),可在裸检出环境直接跑。
二、端点权限判定的 HTTP 层用例(新增 `tests/unit/api/test_permission_enforcement.py`)
- 背景:既有用例都通过 `build_request_context` 覆写注入**已经带好权限**的上下文,
只覆盖"有权限能通",覆盖不到"缺权限必须被拒"。而"权限码在库里根本不存在"这类
环境数据问题(本次三个新权限码)恰恰只会在这一层暴露:权限判定发生在身份解析之后,
服务层测试自己构造 `RequestContext`,权限字段由测试塞入,所以全绿也照样漏。
- 覆盖客服二期三个权限码对应的 5 个端点:
`handover:read`(工单列表/详情)、`memory:candidate:review`(候选列表/审核)、
`memory:candidate:confirm`(用户确认)。
- 正反双向断言:缺权限 → 必须 403 且错误码为 `AGENT_PERMISSION_DENIED`;
带权限 → **不能**再是 403(这一条把端点要求的权限码钉住,改动即红)。
- 只替换两处边界:`build_request_context`(跳过 JWT 与身份库)与
`AuthorizationService` 的审计落库(内存替身);真实路由、真实权限判定与真实 403 信封。
- 已做反向验证:给一个不存在的权限码时,5 个端点全部被拒(403),确认正向断言非空过。
验证(隔离 worktree,基线 `origin/qyqy_develop` = 4d8edb4):
pytest tests/unit tests/contract -> 1294 passed, 2 skipped, 0 failed;
ruff check app tests tools alembic 全通过;mypy app 244 源文件 0 错;
check_authoritative_docs(50 份文档无撞号)与本脚本均通过。
2026-09-12 12:57:16 +08:00
张胜宇
f68b052a69
fix: 端点编号去重与 milvus-lite 降为可选依赖
...
按 qyqy 在 PR #7 评审中的要求处理两项:
- docs/05-接口文档.md §19:客服画像候选的两个端点由 A034/A035 改为 A039/A040。
原编号与 qyqy 侧登录 / RBAC 只读接口(A034-A038)重复;docs 守卫脚本只校验
文档文件名编号、不校验 §19 端点编号,因此该重复会静默遗留。改后全表 55 个
端点编号唯一。
- pyproject.toml / requirements.txt:milvus-lite 由主 dependencies 挪到
[project.optional-dependencies] dev;requirements.txt 只保留说明性注释,
不再作为生效依赖。理由:它仅用于本地开发(Docker Milvus 未运行时的本地
持久化向量库),进主依赖会让生产环境多背一个包。
验证:pytest tests/unit tests/contract -> 1275 passed, 2 skipped, 0 failed;
ruff check app tests tools alembic 通过;mypy app 通过(244 个源文件)。
2026-09-12 11:53:35 +08:00
张胜宇
9aaacc242f
chore: 清理违反底座规则的死代码并修正接口文档编号
...
- 删除生产死代码 app/service/knowledge_tool_service.py 与
app/infrastructure/milvus_knowledge_adapter.py:后者硬编码 Milvus 字段名,
违反 AGENTS.md §E,且仅被前者引用;生产检索链路实际走
knowledge_search_tool -> KnowledgeSearchService -> knowledge_schema 运行时探测。
- 删除上述两模块的单测,以及依赖 legacy 位置参数构造的
tests/unit/service/test_knowledge_retrieval.py。
- app/service/knowledge_retrieval_service.py 整文件回退底座版本,
移除 legacy 双构造与重复检索实现。
- docs/05-接口文档.md:客服画像候选改登记为 §8.5,恢复 §8.2 解析知识引用;
既有 §8.1-§8.4 编号全部保持,修复此前出现两个 8.3 的问题。
- app/model/profile.py:current_customer_id 改为普通可空列映射,与
alembic/baseline_generated.sql 及真实库一致;原 Computed 声明会让 ORM 把该列
从 INSERT 中排除,与「必须显式写入」的实际 schema 不符。
- 新增 docs/客服Agent接入底座扩展说明_v1.md,供集成分支评审逐项确认。
验证:pytest tests/unit tests/contract -> 1275 passed, 2 skipped, 0 failed;
ruff check app tests tools alembic 通过;mypy app 通过(244 个源文件)。
2026-09-12 11:15:24 +08:00
张胜宇
e85989b344
merge: integrate latest qyqy_develop (auth login + RBAC read) into ZSY branch
...
Incremental merge on top of ef701c8 , which already integrated the earlier qyqy base bbf623a . qyqy_develop only added commits on top of bbf623a , so this merge is conflict-free. Incoming: account/password login (POST /api/v1/auth/tokens), RBAC read-only query API, rate limit dependency, login test console and user management tools. Additive changes in app/main.py, requirements.txt and pyproject.toml from both sides are all preserved. ZSY side capabilities (visitor tokens, customer service agent, knowledge retrieval, profile projection) are unchanged.
2026-09-12 10:37:53 +08:00
张胜宇
ef701c844c
merge: integrate ZSY customer service and profile capabilities
2026-09-11 22:31:51 +08:00
张胜宇
cbcf7c7444
feat: add milvus profile projection
2026-09-11 20:45:50 +08:00
张胜宇
50a611274a
feat: target memory sync event replay
2026-09-11 20:26:05 +08:00
张胜宇
5e848f5690
feat: wire neo4j projection into worker
2026-09-11 20:19:34 +08:00
张胜宇
6c605ec3c1
feat: add memory sync outbox worker
2026-09-11 20:07:55 +08:00
张胜宇
f167390a8a
feat: add neo4j profile projection adapter
2026-09-11 19:54:46 +08:00
张胜宇
5777f0f86e
feat: include memory sources in profile sync events
2026-09-11 19:37:18 +08:00
张胜宇
2de1735673
docs: define profile projection protocol
2026-09-11 19:24:57 +08:00
张胜宇
1eb04f28b1
test: fix mysql profile snapshot cleanup
2026-09-11 18:09:36 +08:00
张胜宇
27174b9ce2
feat: generate approved profile snapshots
2026-09-11 17:58:46 +08:00
张胜宇
a769130658
feat: add profile candidate review workflow
2026-09-11 17:47:06 +08:00
张胜宇
3a21afa847
feat: add customer profile candidate flow
2026-09-11 17:16:43 +08:00
张胜宇
ef098e6a4b
feat: complete customer service safety and handover flow
2026-09-11 16:11:30 +08:00
张胜宇
0059701509
fix: persist visitor handover tickets anonymously
2026-09-11 11:57:48 +08:00
张胜宇
9220b7b47c
feat: integrate customer service agent into ZSY develop
...
# Conflicts:
# app/core/config.py
# app/main.py
# app/service/agent/bootstrap.py
2026-09-11 10:46:56 +08:00
张胜宇
a229ec276e
docs: add phase one integration gate
2026-09-11 10:27:29 +08:00
张胜宇
c76b763101
feat: configure local customer service knowledge runtime
2026-09-11 10:13:48 +08:00
张胜宇
bc2f521c2e
feat: add guarded knowledge publication tool
2026-09-10 22:08:15 +08:00
张胜宇
24f75636a0
feat: add knowledge import preflight
2026-09-10 20:22:53 +08:00
张胜宇
e9b3d272f0
feat: add governed customer service agent
2026-09-10 19:51:08 +08:00
张胜宇
511a8ca18f
feat: add governed public knowledge retrieval
2026-09-10 18:42:44 +08:00
张胜宇
ba22a2220f
feat: preserve isolated visitor agent runtime
2026-09-10 17:36:39 +08:00
张胜宇
8e36a9941d
merge: preserve existing business features on new foundation
2026-09-10 17:26:52 +08:00
张胜宇
a789872c79
test: record pre-migration workspace evidence
2026-09-10 17:11:52 +08:00
张胜宇
d0793355fc
docs: add foundation migration implementation plan
2026-09-10 16:59:53 +08:00
张胜宇
5ebed374c4
docs: add safe foundation migration design
2026-09-10 16:36:36 +08:00
张胜宇
ad7172367a
feat: add limited visitor tokens
2026-09-10 13:56:08 +08:00
张胜宇
c6be99078e
chore: ignore local worktrees
2026-09-10 13:33:59 +08:00