13 KiB
AI 合同平台 V2 数据库与代码重构决策
日期:2026-06-28
结论
当前 V2 的总体方向是正确的:代码已经拆成合同平台、AI 中台、基础设施三块,文档和 compose 也已经把数据库目标收口为 yuqei_contract、yuqei_ai、yuqei_ops 三库。
但当前落地状态还没有达到“最佳长期方案”的要求,主要问题不是功能是否能跑,而是环境权威性、数据库边界、代码模块边界和模型长期可维护性还不够清晰。继续新增业务功能前,应该先做一轮非破坏性的治理和重构准备。
本轮不建议删除任何数据库,也不建议继续临时新建数据库。下一步应该先确定唯一权威 V2 环境,再迁移、验证、归档临时库。
已核验的当前状态
文档目标状态
V2 数据库最终边界:
| 数据库 | 归属 | 主要内容 | 连接变量 |
|---|---|---|---|
yuqei_contract |
yuqei-contract-platform |
合同、审批、附件元数据、审查任务业务结果、合同事件、模板/条款/规则管理 | CONTRACT_API_DATABASE_URL |
yuqei_ai |
yuqei-ai-platform |
模型配置、Prompt、知识库、RAG、向量、AI Trace、质量评测、配置执行 | AI_PLATFORM_DATABASE_URL、YUQEI_WORKER_DATABASE_URL |
yuqei_ops |
yuqei-infra |
发布记录、备份记录、运行审计、监控扩展预留 | 后续运维服务独立配置 |
这比 V1 的单库模型更合理。V1 中合同业务、AI、知识库、商业化、治理、发票、审批等全部堆在 ai_contract_platform 这类单体库里,不适合作为 V2 长期生产模型。
远端 192.168.3.90 当前状态
只读检查结果显示:
| 位置 | 数据库/环境 | 状态判断 |
|---|---|---|
宿主机 PostgreSQL 5432 |
ai_contract_platform |
旧版/历史单体库,47 张表,迁移头为 20260619_0045,有 generated_contracts,没有 V2 contracts |
宿主机 PostgreSQL 5432 |
yuqei_contract |
临时 V2 合同测试库,12 张表,迁移头为 20260628_0017,有 contracts 和 legal_change_impact_scans |
宿主机 PostgreSQL 5432 |
yuqei_ai |
不存在 |
宿主机 PostgreSQL 5432 |
yuqei_ops |
不存在 |
| Docker smoke | yuqei-contract-v2-smoke-* |
容器和卷存在,但当前停止;Postgres 映射端口为 15432,卷为 yuqei-contract-v2-smoke_postgres-data |
因此不能把宿主机 5432/yuqei_contract 直接认定为完整 V2 数据库。它只是合同平台部分测试库,缺少 V2 目标中的 yuqei_ai 和 yuqei_ops。
当前设计问题
1. 数据库环境权威性不清
现在同时存在:
- V1/旧单体库:
ai_contract_platform - 临时 V2 合同测试库:
yuqei_contract - 停止状态的 V2 Docker smoke 环境
风险是开发者不知道本地/测试/准生产应该连哪一个库,后续迁移可能打到错误环境。最危险的不是“多了一个库”,而是没有一个明确登记表说明每个库的身份、用途、负责人、迁移头和是否允许写入。
2. 三库目标没有在宿主机 5432 上完整落地
宿主机只看到 yuqei_contract,没有 yuqei_ai、yuqei_ops。这说明如果当前本地后端连的是宿主机 5432,它只验证了合同 API 的一部分,没有验证 AI 中台和 worker 的真实 PostgreSQL 数据边界。
3. 本地 Contract API 示例仍默认 SQLite
yuqei-contract-platform/services/contract-api/.env.example 和 README 仍把 SQLite 放在默认示例里。SQLite 可以保留用于轻量单测,但对 V2 当前阶段来说,开发联调和验收应该默认指向 PostgreSQL,否则很容易出现“本地能跑,PostgreSQL 才暴露问题”的情况。
4. 健康检查不足以证明数据库结构正确
当前健康接口更多检查配置和后端类型,不足以证明:
- 连接的是不是预期数据库名。
- Alembic version 是否等于当前 head。
- 核心表是否存在。
- PostgreSQL 扩展
pg_trgm、vector是否就绪。
这也是之前容易误判“后端已启动但模板/法律资产数据为空”的原因。
5. 合同平台代码模块过大
当前核心文件规模:
yuqei_contract_api/contracts.py:约 7300 行。yuqei_contract_api/main.py:约 1500 行。
contracts.py 同时承载 Pydantic schema、SQLAlchemy model、内存仓储、SQLAlchemy 仓储、demo seed、模板生命周期、法律资产生命周期、文件、审批、审计、备份、权限、通知等多个领域。
这已经不适合继续叠功能。短期能跑,长期会让迁移、测试、审查和性能优化变慢。
6. AI 平台仓储也过于集中
当前核心文件规模:
yuqei_ai_platform_api/repository.py:约 6100 行。yuqei_ai_platform_api/main.py:约 1200 行。
AI 平台已经有知识库、Prompt、Provider、AI Trace、质量闭环、worker runtime、pgvector 检索等能力,但仓储层仍集中在一个大文件里。继续扩展法规库、黄金样本、质量评测和运营后台时,应拆成独立领域模块。
7. 部分数据库模型仍偏 MVP
合同库仍有一些不适合长期作为事实字段的列:
status_labelstatus_tonenext_actionnext_actions
这些更适合由 API serializer/BFF/前端根据状态和角色推导。数据库应保存事实状态,例如 lifecycle_status、review_status、approval_status、signing_status、archive_status。
review_tasks.risk_items、citations、primary_sources、法律影响扫描 payload 等 JSON 字段可以作为快照,但高频筛选、统计、排序和权限判断字段应逐步结构化。
8. 合同生命周期表还不完整
V2 已经补了模板、条款、规则、审查推荐、法律影响扫描等功能,但合同生命周期的长期模型还没有完全稳定:
- 缺少正式
contract_versions表承载正文版本。 - 审批仍主要依赖 timeline,缺少
approval_instances、approval_steps、approval_actions。 - 合同正文仍在
contracts.body_content,后续应迁到版本表或对象存储快照。 - 软删除、创建人、更新人、部门、组织等字段还没有在全部核心表统一。
9. 安全与数据治理仍需硬化
需要继续补齐:
- PostgreSQL RLS 或至少数据库层租户隔离策略。
- 合同库与 AI 库使用不同账号和最小权限。
- Provider/OCR/API key 入库加密或改由密钥服务托管。
- 审计事件 append-only 约束和篡改检测。
- AI Trace 脱敏、保留周期、归档策略。
推荐的目标方案
数据库权威方案
推荐将 V2 数据库环境分成三类,避免混用:
| 环境 | 目的 | 推荐状态 |
|---|---|---|
| 本地单测 | 快速单元测试 | 可继续 SQLite/fake repository,但只覆盖纯逻辑 |
| 本地/远端联调 | Codex 浏览器和开发调试 | 必须 PostgreSQL,连接明确登记的 V2 dev/smoke 三库 |
| 准生产 smoke | 发布前验收 | 使用 Docker smoke 环境或正式 staging PostgreSQL,必须同时存在 yuqei_contract、yuqei_ai、yuqei_ops |
当前最稳妥的选择:
- 先把
yuqei-contract-v2-smokeDocker 环境启动并只读核验其三库状态。 - 如果 smoke 卷中三库和迁移历史完整,将它登记为当前 V2 准生产 smoke 权威环境。
- 宿主机
5432/yuqei_contract标记为“临时合同测试库”,不要继续作为权威环境扩展。 ai_contract_platform标记为“V1/旧单体历史库”,只读保留,用于资产映射和行为对照。- 若后续决定不用 Docker smoke,而改用宿主机 5432 作为正式 V2 dev/staging,则必须一次性补齐
yuqei_contract、yuqei_ai、yuqei_ops三库和独立账号,再把 smoke 作为可重建环境。
代码重构目标结构
Contract API 建议拆分为:
yuqei_contract_api/
api/
contracts.py
files.py
review_tasks.py
templates.py
legal_assets.py
legal_fulltext.py
approvals.py
audit.py
admin.py
domain/
contracts.py
review.py
templates.py
legal_assets.py
approvals.py
persistence/
models.py
session.py
repositories/
contracts.py
files.py
review_tasks.py
templates.py
legal_assets.py
audit.py
services/
contract_lifecycle.py
template_lifecycle.py
clause_recommendation.py
legal_change_impact.py
audit_integrity.py
seed/
demo_data.py
AI Platform 建议拆分为:
yuqei_ai_platform_api/
api/
providers.py
prompts.py
knowledge.py
ai_runs.py
quality.py
workers.py
domain/
providers.py
prompts.py
knowledge.py
ai_runs.py
quality.py
persistence/
models.py
session.py
repositories/
providers.py
prompts.py
knowledge.py
ai_runs.py
quality.py
workers.py
services/
retrieval.py
trace.py
quality_gate.py
ingestion.py
拆分原则:
- API 层只负责路由、鉴权、参数和响应。
- service 层负责业务编排。
- repository 层只负责数据库读写。
- domain/schema 层不依赖 FastAPI。
- migration 只从 persistence models 或明确 migration 脚本演进,不从大杂烩文件隐式生成。
重构执行顺序
Phase A:数据库环境治理
目标:先消除“连错库”的风险。
任务:
- 新增 V2 数据库环境登记表,记录每个库的用途、连接入口、迁移头、是否权威、是否允许写入。
- 新增只读检查脚本,能输出远端 DB 清单、表数量、Alembic head、核心表存在性。
- 启动并核验 Docker smoke 环境,确认
15432下是否存在yuqei_contract、yuqei_ai、yuqei_ops。 - 决定权威开发/准生产库。
- 本地后端只连接权威 V2 PostgreSQL,不再用临时 SQLite 作为功能验收依据。
验收标准:
- 文档中明确唯一 V2 dev/smoke 权威库。
ai_contract_platform标记为旧库,不再作为 V2 写入目标。- 临时
5432/yuqei_contract有归属说明,未确认前不继续扩展。 - 健康/检查脚本能显示当前连接数据库名和迁移头。
Phase B:运行时安全检查
目标:应用启动和健康检查能发现错误数据库。
任务:
- Contract API 增加
/api/v1/runtime/schema-check。 - AI Platform API 增加
/api/v1/runtime/schema-check。 - 检查项包括数据库名、Alembic version、核心表、PostgreSQL 扩展。
- staging/production 环境禁止 SQLite,禁止 auto create,禁止 demo seed。
验收标准:
- 连接旧
ai_contract_platform时 schema check 必须报错。 - 连接缺表或迁移头落后的库时 schema check 必须报错。
- Docker smoke 健康检查从“服务 alive”升级为“服务 alive + schema ready”。
Phase C:代码模块化拆分
目标:先拆结构,不改接口行为。
任务:
- 将
contracts.py中 SQLAlchemy model 移到persistence/models.py。 - 将 Contract API repository 按合同、文件、审查、模板、法律资产、审计拆分。
- 将路由从
main.py拆到api/*,由create_app注册。 - 将 AI Platform repository 按 Provider、Prompt、Knowledge、AI Run、Quality、Worker 拆分。
- 保持现有 API path、响应结构和测试不变。
验收标准:
- 拆分后功能测试全通过。
- 单文件不再继续承载多个领域。
- 新增功能只能落到对应领域模块,不再向大文件继续堆。
Phase D:数据库模型硬化
目标:把 MVP 表逐步收敛到生产模型。
任务:
- 新增
contract_versions,合同正文版本化。 - 新增正式审批模型:
approval_instances、approval_steps、approval_actions。 - 将 UI 展示字段从长期事实表中逐步迁出或转为派生字段。
- 为核心表补齐
tenant_id、created_by、updated_by、deleted_at。 - 将高频 JSON 查询字段结构化,JSON 只保留快照和扩展。
- AI 库补齐
tenant_id、保留周期、归档策略和敏感字段加密策略。
验收标准:
- 合同列表、审批待办、统一搜索、AI Trace、知识库检索不依赖 JSON 全表扫描。
- 合同正文修改有版本历史。
- 审批动作可追溯到步骤、人员、时间、结果。
- 数据库字段表达事实,不表达 UI 文案。
Phase E:V1 资产迁移策略
目标:吸收 V1 优秀资产,但不复制 V1 单体结构。
任务:
- 模板、条款、规则、黄金样本、精选法律全文通过导入脚本迁入 V2 新模型。
- 每类资产都保留 V1 source id、导入批次、版本、hash。
- V1 表结构不直接搬入 V2。
- V1 数据库只读保留,作为迁移源和行为对照。
验收标准:
- V2 可独立从空库迁移到 head,再导入 V1 精选资产。
- 导入可重复执行,具备幂等性和差异报告。
- V1 与 V2 数据边界清楚,不出现一半沿用旧表、一半新表的混合状态。
立即不做的事
- 不删除
ai_contract_platform。 - 不删除或覆盖
5432/yuqei_contract。 - 不继续新建第三个、第四个 V2 候选库。
- 不把 V1 的单体 schema 复制到 V2。
- 不在未确认权威库前继续向数据库写入新业务数据。
下一步建议
优先执行 Phase A:
- 写数据库环境登记表。
- 写只读 DB 检查脚本。
- 启动并检查 Docker smoke 数据库三库状态。
- 决定权威 V2 dev/smoke 库。
这个阶段完成后,再开始代码模块化和 schema 硬化。这样重构不是边跑边猜,而是有清晰的数据库落点和验收门槛。