# AI 合同平台 V2 Phase 3 Slice 3.1 合同版本表实施记录 日期:2026-06-30 ## 本次范围 本次按 Phase 3 schema 硬化设计评审的 Slice 3.1 实施 `contract_versions`。 已完成: - 新增 Contract API Alembic migration:`20260630_0019_add_contract_versions.py`。 - 新增 SQLAlchemy model:`ContractVersionModel`。 - Runtime schema check 核心表清单加入 `contract_versions`。 - 合同创建时写入初始版本。 - 合同正文更新时写入新版本。 - 条款推荐/一键修订应用后写入新版本。 - `/api/v1/contracts/{contract_id}/versions` 改为读取真实版本表。 - `/api/v1/contracts/{contract_id}/versions/version-current-{contract_id}` 保留当前版本别名兼容。 - `contracts.body_content` 继续保留为兼容缓存,没有删除旧字段。 - 补充合同版本历史和租户隔离测试。 未做: - 未删除 `contracts.body_content`。 - 未进入审批模型、风险项结构化、资产发布快照等后续 Phase 3 slice。 ## 数据模型 新增表:`contract_versions` 核心字段: - `id` - `tenant_id` - `contract_id` - `version_no` - `version_label` - `body_content` - `body_hash` - `source_type` - `source_id` - `created_by` - `change_summary` - `metadata` - `created_at` - `published_at` 核心约束: - `tenant_id + contract_id + version_no` 唯一。 - `tenant_id + contract_id + created_at` 索引。 - `contract_id + version_no` 索引。 - `source_type + source_id` 索引。 ## 兼容策略 本次仍保持 `contracts.body_content` 作为当前正文缓存: - 详情接口继续返回 `ContractDetail.body_content`。 - 前端合同详情、编辑、版本对比无需改 API path。 - 版本列表返回真实历史版本。 - 旧的 `version-current-{contract_id}` 仍作为当前正文别名保留。 ## 验证结果 已通过: ```powershell python -m compileall -q yuqei-contract-platform/services/contract-api/src/yuqei_contract_api python -m compileall -q yuqei-contract-platform/services/contract-api/migrations python -m pytest yuqei-contract-platform/services/contract-api/tests/test_contract_workflow.py::test_contract_versions_endpoint_returns_current_persisted_body yuqei-contract-platform/services/contract-api/tests/test_tenant_isolation.py::test_tenant_isolation_contract_versions -q python -m pytest yuqei-contract-platform/services/contract-api/tests -q ``` Alembic head 检查: ```text 20260630_0019 ``` 本地临时 SQLite 空库迁移到 head 已通过,并确认 `contract_versions` 表存在。 权威 V2 smoke PostgreSQL / Docker 环境验收已通过: ```powershell $env:SSHPASS='' powershell.exe -NoProfile -ExecutionPolicy Bypass -File yuqei-infra\scripts\deploy-v2-smoke-docker.ps1 -UseSshpass -AllowDirtyWorktree -KeepRemoteBackup -SkipSmoke ``` 部署结果: - 远端环境:`192.168.3.90:/opt/apps/ai-contract-platform-v2-smoke` - Compose project:`yuqei-contract-v2-smoke` - 部署产物:`project-docs/qa-artifacts/v2-smoke-docker-deploy/2026-06-30T12-26-13` - 脚本结果:`V2_SMOKE_DOCKER_DEPLOY_PASS` - Contract API:`http://192.168.3.90:18100` healthy - Contract Web:`http://192.168.3.90:13000` healthy - AI Platform API:`http://192.168.3.90:18101` healthy Runtime schema check 抽样: ```text status=ok database=yuqei_contract backend=PostgreSQL actual=20260630_0019 expected_head=20260630_0019 core_tables checked_count=17 ``` 远端 PostgreSQL 抽样: ```text contract_api_alembic_version = 20260630_0019 contract_versions exists = true contract_versions total = 12007 smoke contract versions: smoke-phase3 | contract-d4854c4bd1ec | 1 | v1 | contract_create smoke-phase3 | contract-d4854c4bd1ec | 2 | v2 | contract_update ``` 版本 API 抽样: ```text POST /api/v1/contracts PATCH /api/v1/contracts/{contract_id} GET /api/v1/contracts/{contract_id}/versions GET /api/v1/contracts/{contract_id}/versions/version-current-{contract_id} contract_id=contract-d4854c4bd1ec version_total=2 latest version=v2 initial version=v1 latest body matches patched body=true current alias body matches patched body=true ``` ## 下一步 Slice 3.1 已完成本地和权威 V2 smoke PostgreSQL 验收。建议下一步进入 Phase 3 Slice 3.2:正式审批模型 `approval_instances` / `approval_steps` / `approval_actions` 的设计确认与第一片迁移实现。