- data-model.md:约定、租户隔离落地、按模块的表清单、额度流水语义、 清单项与检查的建模、删除流程、对象存储布局 - schema-draft.sql:40 张表的建表草案(PostgreSQL 16+) - schema-draft-test.sql:租户隔离、额度流水、审计、删除等 16 项行为测试 - 回写架构 §3.2/§3.11/§9/§12、05 §3、FR-M2-05、FR-M3-03 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
7.2 KiB
7.2 KiB
04 · 领域模型草案
这是需求层面的概念模型,不是数据库设计。字段只列出决定业务规则的那些;物理模型见
docs/architecture/data-model.md。 核心是 PRD 第 5 章说的「项目检查清单」:M2 产出它,M3 拿它做核对,V1 的 M4 拿它做生成约束,M5 也挂在它上面。
1. 实体关系
erDiagram
Tenant ||--o{ Membership : "成员"
User ||--o{ Membership : "成员身份"
User ||--o{ LoginIdentity : "登录方式"
Project ||--o{ ProjectMember : "项目成员"
Tenant ||--o{ Subscription : "订阅"
Tenant ||--|| QuotaAccount : "额度账户"
QuotaAccount ||--o{ QuotaEntry : "流水"
Tenant ||--o{ Qualification : "资质库"
Tenant ||--o{ Project : "投标项目"
Project ||--o{ Lot : "包/标段"
Project ||--o{ SourceDocument : "招标文件/补遗/投标文件"
SourceDocument ||--o{ ParseJob : "解析任务"
SourceDocument ||--o{ Citation : "被引用"
Project ||--|| Checklist : "项目检查清单"
Checklist ||--o{ ChecklistItem : "清单项"
ChecklistItem }o--o{ Citation : "出处"
ChecklistItem }o--o| Lot : "所属包(空=通用)"
Project ||--o{ CheckRun : "检查批次"
CheckRun ||--o{ Finding : "问题"
Finding }o--|| ChecklistItem : "对应清单项"
Finding }o--o{ Citation : "双方出处"
Finding |o--o| Finding : "沿用自上次"
CheckRun ||--o| Report : "检查报告"
QuotaEntry }o--o| ParseJob : "关联任务"
QuotaEntry }o--o| CheckRun : "关联任务"
所有业务实体都带 tenant_id,按租户隔离(PRD 7)。User 和 LoginIdentity 例外,是全局的(技术架构 §3.14)。
2. 实体说明
| 实体 | 关键字段 | 说明 |
|---|---|---|
| Tenant 企业主体 | 名称、统一社会信用代码(可空)、当前套餐 | 额度和数据的归属单位(PRD 4.3:额度绑定企业主体) |
| User 用户 | 显示名、状态 | 一个自然人,不属于某个租户;不做物理删除 |
| LoginIdentity 登录方式 | 来源(手机号 / 飞书 / 企业微信 / 账号密码 / OIDC / LDAP)、外部组织编号、外部用户编号 | 一个人可以有多种登录方式 |
| Membership 成员身份 | 用户、租户、企业角色、状态 | MVP 一个人只属于一个企业、一个企业一个成员(所有者);团队版放开成多席位(技术架构 §3.14) |
| ProjectMember 项目成员 | 项目、用户、项目角色(负责人 / 编标 / 只读) | MVP 只有建项目的人,自动成为负责人 |
| Subscription 订阅 | 套餐、起止日期、来源(注册赠送 / 人工开通 / 线上支付)、席位数 | MVP 席位数是 1 |
| QuotaAccount / QuotaEntry 额度 | 单位(解析 / 检查 / 生成 / 查重)、类型(发放 / 预扣 / 结算 / 退回 / 过期 / 调整 / 免扣)、数量、关联任务、原因 | 只追加、不修改;余额由流水算出来 |
| Qualification 资质 | 名称、类型、等级、证书号、发证机构、有效期、附件 | MVP 最小资质库 |
| Project 投标项目 | 名称、编号、采购人、代理机构、采购方式、法律体系、截止时间、状态、所投包 | 基本信息来自 FR-M2-03,用户可以改 |
| Lot 包 / 标段 | 包号、名称、预算、最高限价、是否投标 | 没有分包时只有一个默认包 |
| SourceDocument 文档 | 角色(招标文件 / 补遗 / 澄清 / 投标分册)、分册名、版本号、原始文件、规范化 PDF、页数、解析状态 | 所有文件都转成规范化 PDF,作为出处页码的唯一依据 |
| ParseJob 解析任务 | 状态、阶段、模型与提示词版本、耗时、失败原因 | 一份文档可以有多次任务(重试) |
| Citation 出处 | 文档、页码、原句、坐标范围 | 「可复核」的载体;清单项和问题共用 |
| Checklist 检查清单 | 状态(草稿 / 已确认)、版本号、确认人、确认时间 | 每个项目一份;每次确认生成新版本 |
| ChecklistItem 清单项 | 类别标签(可以多个)、标题、要求原文、重要性(★ / ▲ / 一般)、所属包、证明材料要求、比较方式与要求值(参数类)、来源(AI / 人工 / 补遗 N)、状态(待确认区 / 正式 / 已删除)、置信度 | 见 05 §3 |
| CheckRun 检查批次 | 清单版本、投标文件版本集合、规则版本、状态、是否扣点 | 可以复现「当时根据什么做的判断」 |
| Finding 问题 | 类型(未响应 / 负偏离未说明 / 疑似不满足 / 形式 / 资质 / 报价形式 / 人工核对)、级别、说明、出处、处理状态、忽略原因、处理人、处理时间、沿用来源 | |
| Report 报告 | 文件、生成时间、生成人 | 生成后不再改动;重新导出就生成新报告 |
| AuditEvent 审计事件 | 操作人、动作、对象、修改前、修改后、时间 | 不在上图中,所有实体都会写 |
| Feedback 反馈 | 对象(问题 / 清单)、类型(误报 / 漏报)、说明、处理状态 | 进运营后台 |
3. 状态机
3.1 项目
stateDiagram-v2
[*] --> 跟进中: 新建
跟进中 --> 编制中: 首份招标文件解析成功
编制中 --> 已检查: 完成首次检查
已检查 --> 已检查: 复查
已检查 --> 已递交: 用户标记
已递交 --> 已检查: 撤销递交(留痕)
已检查 --> 已归档: 用户归档
已递交 --> 已归档: 用户归档
已归档 --> 已检查: 撤销归档
已归档 --> 已递交: 撤销归档(原状态为已递交)
「就绪 / 未就绪」是项目上单独的一个标记,不是状态:只要最近一次检查批次里还有「待处理」的致命问题,就是未就绪。
3.2 解析任务
stateDiagram-v2
[*] --> 排队中: 发起(预扣1次)
排队中 --> 解析中
排队中 --> 已取消: 用户取消(退回)
解析中 --> 成功: 结算
解析中 --> 失败: 退回
解析中 --> 已取消: 用户取消(退回)
失败 --> 排队中: 重试(重新预扣)
3.3 问题(Finding)
stateDiagram-v2
[*] --> 待处理
待处理 --> 已确认无误
待处理 --> 已修改
待处理 --> 已忽略: 必填原因
已确认无误 --> 待处理: 撤销
已修改 --> 待处理: 撤销
已忽略 --> 待处理: 撤销
note right of 待处理
复查时:问题仍在 → 沿用状态(已修改改回待处理)
问题消失 → 本次已解决
end note
4. 关键设计约束
- 出处统一用规范化 PDF 的页码:Word 没有稳定的页码,必须先转成 PDF。转换结果存下来,以后不要重新生成,否则老的出处会对不上。
- 清单有版本:检查批次引用的是清单的某个版本,后面再改清单,不影响历史报告。
- 额度流水只追加:账户余额由流水算出来,所以「失败不扣点」可以从流水验证。
- AI 产出记录模型和提示词版本:解析任务、检查批次都要记,这样漏报复盘时能知道是哪个版本出的问题。
- 租户隔离:所有查询都必须带租户条件;私有化(P2)时一个部署就是一个租户,模型不需要改。