Files
ai-contract-platform/project-docs/V2-display-cache-governance-strategy-2026-06-30.md
T
yuqei a3bb78e06b
Security Quality Gate / npm audit, Bandit, pip-audit, detect-secrets (pull_request) Failing after 16m35s
release: freeze V2 release candidate
2026-07-12 15:32:24 +08:00

11 KiB
Raw Permalink Blame History

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,不自动修复,不删除旧列。

治理原则

  1. 先评估,再 dry-run,再生成快照,最后才允许 apply。
  2. backfill --apply 必须提供 snapshot 文件,确保可以回滚。
  3. rollback --apply 必须读取 snapshot 文件恢复旧值。
  4. 不在本阶段删除 contracts.status_label/status_tone/next_action/next_actions。
  5. 不改变 OpenAPI 和前端字段名。
  6. 不重置远端 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 恢复旧值。

建议远端执行顺序

  1. 在 192.168.3.90 的 smoke 容器内执行只读评估。
  2. 执行 backfill dry-run,确认 would_update_rows 与 schema-check mismatch_count 一致。
  3. 导出 snapshot 到远端可备份目录。
  4. 备份 snapshot 到本地 artifact。
  5. 仅在确认后执行 backfill --apply --snapshot <path>。
  6. 复跑 /api/v1/runtime/schema-check。
  7. 若出现前端展示异常或抽样不通过,执行 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 统计完全对齐。
  • backfill dry-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