11 KiB
AI 合同平台 V2 旧 UI 缓存治理策略
背景
Phase 3 Slice 3.4 已将 status_label、status_tone、next_action、next_actions 逐步从数据库缓存字段转为 domain/serializer 派生。
远端 V2 smoke PostgreSQL 环境的 runtime/schema-check 已确认:
- 检查未软删除合同记录:12010 条。
- 旧 UI 缓存与派生值不一致:8000 条。
- 当前仅报告
warning,不自动修复,不删除旧列。
治理原则
- 先评估,再 dry-run,再生成快照,最后才允许 apply。
backfill --apply必须提供 snapshot 文件,确保可以回滚。rollback --apply必须读取 snapshot 文件恢复旧值。- 不在本阶段删除
contracts.status_label/status_tone/next_action/next_actions。 - 不改变 OpenAPI 和前端字段名。
- 不重置远端 PostgreSQL 数据卷。
工具
新增治理工具:
python -m yuqei_contract_api.display_cache_governance_cli assess
python -m yuqei_contract_api.display_cache_governance_cli backfill
python -m yuqei_contract_api.display_cache_governance_cli backfill --apply --snapshot .runtime/display-cache-backfill-snapshot.json
python -m yuqei_contract_api.display_cache_governance_cli rollback --snapshot .runtime/display-cache-backfill-snapshot.json
python -m yuqei_contract_api.display_cache_governance_cli rollback --apply --snapshot .runtime/display-cache-backfill-snapshot.json
默认行为:
assess:只读评估。backfill:默认 dry-run,只返回 would_update_rows。backfill --apply:写入派生值,并保存旧值/新值快照。rollback:默认 dry-run,只返回 would_restore_rows。rollback --apply:按 snapshot 恢复旧值。
建议远端执行顺序
- 在 192.168.3.90 的 smoke 容器内执行只读评估。
- 执行
backfilldry-run,确认 would_update_rows 与 schema-check mismatch_count 一致。 - 导出 snapshot 到远端可备份目录。
- 备份 snapshot 到本地 artifact。
- 仅在确认后执行
backfill --apply --snapshot <path>。 - 复跑
/api/v1/runtime/schema-check。 - 若出现前端展示异常或抽样不通过,执行
rollback --apply --snapshot <path>。
验收标准
- dry-run 不修改数据库。
- apply 后
display_cache_consistency.mismatch_count明显下降或归零。 - rollback 后可恢复 apply 前旧缓存值。
- 合同列表、合同详情、workspace、统一搜索抽样仍返回兼容字段。
- Docker healthcheck 不因 warning 误判 unhealthy;真正的 schema
error仍会失败。
当前状态
本阶段只完成治理工具和策略,不对远端 8000 条旧缓存执行批量修复。
远端 smoke 只读验证记录
验证环境:
- 服务器:
192.168.3.90 - Compose project:
yuqei-contract-v2-smoke - Contract API:
http://192.168.3.90:18100 - PostgreSQL 数据库:
yuqei_contract - 部署 artifact:
project-docs/qa-artifacts/v2-smoke-docker-deploy/2026-06-30T17-13-39 - CLI assess artifact:
project-docs/qa-artifacts/display-cache-governance/2026-06-30T17-19-32 - CLI backfill dry-run artifact:
project-docs/qa-artifacts/display-cache-governance/2026-06-30T17-20-11
部署命令:
powershell.exe -NoProfile -ExecutionPolicy Bypass -File yuqei-infra\scripts\deploy-v2-smoke-docker.ps1 -UseSshpass -AllowDirtyWorktree -KeepRemoteBackup -SkipSmoke
部署结果:
- Docker smoke 部署:通过。
- Web、Contract API、AI Platform API health endpoints:通过。
- AI golden sample asset gate:通过,90 samples、6 suites、16 checks。
- Remote database baseline:
yuqei_contract、yuqei_ai、yuqei_ops均存在。 - Contract review worker smoke:跳过,避免本次只读治理验证额外创建 smoke 合同。
远端容器内 assess 结果:
{
"command": "assess",
"checked_rows": 12010,
"mismatch_count": 8000,
"field_counts": {
"status_label": 4000,
"status_tone": 6000
},
"samples": [
"perf-contract-000001:status_tone",
"perf-contract-000004:status_label",
"perf-contract-000005:status_tone",
"perf-contract-000006:status_label,status_tone",
"perf-contract-000007:status_tone"
]
}
远端容器内 backfill dry-run 结果:
{
"command": "backfill",
"mode": "dry-run",
"would_update_rows": 8000,
"snapshot_required_for_apply": true
}
复跑 /api/v1/runtime/schema-check 后确认:
display_cache_consistency.checked_rows:12010。display_cache_consistency.mismatch_count:8000。field_counts:status_label=4000、status_tone=6000。
结论:
- 治理工具已部署进远端 smoke
contract-api容器。 assess与schema-check统计完全对齐。backfilldry-run 的would_update_rows与mismatch_count完全对齐。- 本轮未执行
backfill --apply,未写库,未生成修复 snapshot,未重置 PostgreSQL 数据卷。
远端候选 snapshot 预生成记录
本次只生成候选 snapshot,不执行 backfill --apply。
部署 artifact:
project-docs/qa-artifacts/v2-smoke-docker-deploy/2026-06-30T17-33-50
本地备份 artifact:
project-docs/qa-artifacts/display-cache-governance/2026-06-30T17-37-24
远端容器内候选 snapshot:
/opt/apps/ai-contract-platform-v2-smoke/backups/display-cache/display-cache-backfill-candidate-2026-06-30T17-37-24.json
远端宿主机备份:
/opt/apps/ai-contract-platform-v2-smoke/backups/display-cache/host-display-cache-backfill-candidate-2026-06-30T17-37-24.json
本地备份:
project-docs/qa-artifacts/display-cache-governance/2026-06-30T17-37-24/display-cache-backfill-candidate-2026-06-30T17-37-24.json
候选 snapshot 校验:
- 文件大小:1674118 bytes。
- SHA256:
853eaaf1024e43ebeb8530ac1ed47ed91bad4a09d0b79716f0aedbe791313f76。 mode:dry-run。total_updates:8000。- values 数量:8000。
- 最后一条 contract_id:
perf-contract-012000。
候选样例:
[
{
"contract_id": "perf-contract-000001",
"old_values": {
"status_tone": "tag-primary"
},
"new_values": {
"status_tone": "tag-warning"
}
},
{
"contract_id": "perf-contract-000004",
"old_values": {
"status_label": "��ͨ��"
},
"new_values": {
"status_label": "������"
}
},
{
"contract_id": "perf-contract-000005",
"old_values": {
"status_tone": "tag-muted"
},
"new_values": {
"status_tone": "tag-success"
}
}
]
说明:样例中的乱码来自历史性能数据中的旧缓存文本/终端编码表现;结构字段、contract_id、status_tone 和候选数量均已校验。
生成后复跑 /api/v1/runtime/schema-check:
checked_rows:12010。mismatch_count:8000。field_counts:status_label=4000、status_tone=6000。
结论:
- 候选 snapshot 已生成并备份到本地 artifact。
- 本轮仍未执行
backfill --apply。 - PostgreSQL 数据未发生批量修复,schema-check 结果保持 8000 条 mismatch。
下一步如确认执行 apply,建议命令为:
cd /opt/apps/ai-contract-platform-v2-smoke
COMPOSE_PROJECT_NAME='yuqei-contract-v2-smoke'
ENV_FILE='/opt/apps/ai-contract-platform-v2-smoke/yuqei-infra/compose/.env.smoke'
COMPOSE_FILE='/opt/apps/ai-contract-platform-v2-smoke/yuqei-infra/compose/docker-compose.yml'
SNAPSHOT='/opt/apps/ai-contract-platform-v2-smoke/backups/display-cache/display-cache-backfill-candidate-2026-06-30T17-37-24.json'
docker compose -p "$COMPOSE_PROJECT_NAME" --env-file "$ENV_FILE" -f "$COMPOSE_FILE" exec -T contract-api python -m yuqei_contract_api.display_cache_governance_cli backfill --apply --snapshot "$SNAPSHOT"
如 apply 后需要回滚,建议命令为:
cd /opt/apps/ai-contract-platform-v2-smoke
COMPOSE_PROJECT_NAME='yuqei-contract-v2-smoke'
ENV_FILE='/opt/apps/ai-contract-platform-v2-smoke/yuqei-infra/compose/.env.smoke'
COMPOSE_FILE='/opt/apps/ai-contract-platform-v2-smoke/yuqei-infra/compose/docker-compose.yml'
SNAPSHOT='/opt/apps/ai-contract-platform-v2-smoke/backups/display-cache/display-cache-backfill-candidate-2026-06-30T17-37-24.json'
docker compose -p "$COMPOSE_PROJECT_NAME" --env-file "$ENV_FILE" -f "$COMPOSE_FILE" exec -T contract-api python -m yuqei_contract_api.display_cache_governance_cli rollback --apply --snapshot "$SNAPSHOT"
远端 smoke backfill apply 记录
本次已在 smoke 环境执行 backfill --apply,使用上一节确认过的 snapshot:
- Snapshot:
/opt/apps/ai-contract-platform-v2-smoke/backups/display-cache/display-cache-backfill-candidate-2026-06-30T17-37-24.json - Snapshot SHA256:
853eaaf1024e43ebeb8530ac1ed47ed91bad4a09d0b79716f0aedbe791313f76 - Apply artifact:
project-docs/qa-artifacts/display-cache-governance/2026-06-30T17-58-24 - Post-apply sample artifact:
project-docs/qa-artifacts/display-cache-governance/2026-06-30T18-01-02
Apply 输出:
{
"command": "backfill",
"mode": "apply",
"updated_rows": 8000,
"snapshot": "/opt/apps/ai-contract-platform-v2-smoke/backups/display-cache/display-cache-backfill-candidate-2026-06-30T17-37-24.json"
}
Apply 后 /api/v1/runtime/schema-check:
- 顶层状态:
ok。 display_cache_consistency.status:ok。checked_rows:12010。mismatch_count:0。- Alembic actual/head:
20260630_0021。 - PostgreSQL extension:
pg_trgm正常。
Apply 后接口抽样:
/health:ok。/api/v1/contracts?limit=5:可返回合同列表,样例包含perf-contract-000001。/api/v1/contracts/perf-contract-000001:可返回合同详情。/api/v1/search?keyword=PERF-000001&limit=5:可返回统一搜索结果,包含 contract/file/review 三类分组。
说明:
- 控制台输出中的中文乱码是 PowerShell/终端编码显示问题,接口 JSON 已保存为 UTF-8 artifact。
- 本次没有执行 rollback,因为 schema-check 已归零且列表、详情、搜索抽样可用。
- 如后续发现 smoke 展示异常,仍可使用上一节
rollback --apply --snapshot命令恢复旧缓存。
2026-07-01 完整上下文口径更新
后续排查发现,上一轮 mismatch_count=0 只代表旧缓存列与“状态默认派生值”一致,并不代表与真实用户读路径一致。
合同详情页会使用完整 ContractActionContext,纳入最新审查风险、条款修复、审批实例、履约任务和 action_hint。因此治理工具和 schema-check 已升级为同一完整上下文口径。
本次远端 smoke 复核:
- 完整上下文口径首次发现
12006条next_action/next_actions不一致。 - 已执行可回滚
backfill --apply,更新12006行。 - 回滚 snapshot:
/data/contract-files/display-cache-context-snapshot-20260701.json。 - 复跑
/api/v1/runtime/schema-check:status=ok,display_cache_consistency.mismatch_count=0,display_cache_cleanup_prestate.status=ok。 - 合同详情页
/contracts/contract-0ba3bd5b04b6抽样返回 200,推荐卡片仍展示,且本次请求后无Contract display cache mismatch日志。
详细记录见:
project-docs/V2-phase3-display-cache-context-prestate-2026-07-01.md