Files
ai-contract-platform/project-docs/V2-phase3-formal-approval-model-implementation-2026-06-30.md
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

6.0 KiB
Raw Permalink Blame History

AI 合同平台 V2 Phase 3 Slice 3.2 正式审批模型实施记录

日期:2026-06-30

本次范围

本次按 Phase 3 schema 硬化设计评审的 Slice 3.2 实施正式审批模型。

已完成:

  • 新增 Contract API Alembic migration:20260630_0020_add_formal_approval_tables.py。
  • 新增 SQLAlchemy model:
    • ApprovalInstanceModel
    • ApprovalStepModel
    • ApprovalActionModel
  • Runtime schema check 核心表清单加入:
    • approval_instances
    • approval_steps
    • approval_actions
  • 从旧 approval_timeline_items 回填正式审批实例、步骤、动作。
  • 审批提交、退回、重新提交、审批通过写入正式审批表。
  • 现有 approval_timeline_items 继续作为展示/兼容时间线。
  • 现有审批 API path 和响应结构保持不变。
  • 补充正式审批表写入和租户隔离测试。

未做:

  • 未把工作台待办切换为读取 approval_steps。
  • 未新增审批实例/步骤/动作的外部 API。
  • 未实现会签、或签、加签、转交、多级审批。
  • 未删除或替换 approval_timeline_items。
  • 未进入治理字段、软删除、UI 字段派生等后续 Phase 3 slice。

数据模型

新增表:approval_instances

核心字段:

  • id
  • tenant_id
  • contract_id
  • status
  • started_by
  • started_at
  • completed_at
  • current_step_id
  • metadata

新增表:approval_steps

核心字段:

  • id
  • tenant_id
  • approval_instance_id
  • step_no
  • step_type
  • assignee_role
  • assignee_user_id
  • status
  • due_at
  • completed_at
  • metadata

新增表:approval_actions

核心字段:

  • id
  • tenant_id
  • approval_instance_id
  • approval_step_id
  • action
  • actor_user_id
  • actor_name
  • comment
  • created_at
  • metadata

第一片状态约定:

  • approval_instances.status:pending、approved、rejected
  • approval_steps.status:pending、approved、rejected
  • approval_actions.action:submit、resubmit、approve、reject

兼容策略

本次仍保留 approval_timeline_items 作为展示和兼容层:

  • 合同详情继续返回 approval_timeline。
  • 审批提交/驳回/重新提交/通过继续写 timeline 和 audit。
  • 同一审批状态迁移中同步写 approval_instances、approval_steps、approval_actions。
  • 工作台待办仍按现有合同状态逻辑读取,后续再单独评审是否切到 approval_steps。

回填策略:

  • 提交审批 和 退回后重新提交 生成新的审批实例和第一步。
  • 审批通过 和 退回修改 关闭最近一个 pending 实例和步骤。
  • 如果历史数据只有审批结果、缺少提交动作,则生成一个带 implicit=true metadata 的兼容实例。

验证结果

已通过:

python -m compileall -q yuqei-contract-platform/services/contract-api/src/yuqei_contract_api yuqei-contract-platform/services/contract-api/migrations
python -m pytest yuqei-contract-platform/services/contract-api/tests/test_contract_workflow.py::test_submit_reject_resubmit_and_approve_workflow yuqei-contract-platform/services/contract-api/tests/test_contract_workflow.py::test_approval_workflow_writes_formal_approval_records yuqei-contract-platform/services/contract-api/tests/test_tenant_isolation.py::test_tenant_isolation_formal_approval_records -q
python -m pytest yuqei-contract-platform/services/contract-api/tests -q
python -m alembic -c yuqei-contract-platform/services/contract-api/alembic.ini upgrade head
python -m alembic -c yuqei-contract-platform/services/contract-api/alembic.ini downgrade 20260630_0019
python -m alembic -c yuqei-contract-platform/services/contract-api/alembic.ini upgrade head

本地临时 SQLite 空库迁移到 head 已通过,并确认新增三张正式审批表存在。

approval_instances exists = true
approval_steps exists = true
approval_actions exists = true
table_count = 21

权威 V2 smoke PostgreSQL / Docker 环境验收已通过:

$env:SSHPASS='<remote-root-password>'
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-58-05
  • 脚本结果: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 抽样:

status=ok
database=yuqei_contract
backend=PostgreSQL
actual=20260630_0020
expected_head=20260630_0020
core_tables checked_count=20

远端 PostgreSQL 抽样:

contract_api_alembic_version = 20260630_0020
approval_instances exists = true
approval_steps exists = true
approval_actions exists = true

approval_instances = 27000
approval_steps = 27000
approval_actions = 27000

approval_actions by action:
  approve = 9000
  reject = 9000
  submit = 9000

审批 API 抽样:

POST /api/v1/contracts
POST /api/v1/contracts/{contract_id}/approval/submit
POST /api/v1/contracts/{contract_id}/approval/decision

tenant_id=smoke-phase3-approval
contract_id=contract-5aa6920c50de
submitted_status=approval_pending
approved_status=approved
latest_audit_event_type=approval_approved

抽样合同正式审批表记录:

approval_instances:
  approval-instance-460dd6950e21 | smoke-phase3-approval | contract-5aa6920c50de | approved | Smoke Business | completed=true

approval_steps:
  approval-step-c3c9808cbd58 | approved | approver | completed=true

approval_actions:
  submit  | Smoke Business | Submit formal approval smoke
  approve | Smoke Approver | Approve formal approval smoke

下一步

Slice 3.2 已完成本地和权威 V2 smoke PostgreSQL 验收。建议下一步进入 Phase 3 Slice 3.3:治理字段和软删除设计确认与第一片迁移。