docs(architecture): v0.3 为多人、多登录方式预留表结构(AR11、AR12)
团队版、企业版、飞书 / 企业微信登录都不在早期版本,但 MVP 的表结构先按 多人、多登录方式建,以后接入不用重构: - 身份拆成人 / 登录方式 / 成员身份三层,一人一企业在服务层限制 - 项目成员表、统一的权限检查点和可见范围过滤先建好 - 记录「谁」的字段指向人,人不做物理删除;订阅带席位数 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -153,5 +153,6 @@ samples/
|
||||
- 2026-11-03:UI 风格定稿(U5)。工作台经过六轮方案(`docs/design/ui-demo/explore/`),定为 D5:白色主调、墨色渐变窄侧栏、透明顶栏、圆角三档、只用功能图标、少写说明。设计规范和 `tokens.css` 升到 v0.2。
|
||||
- 2026-11-03:UI demo 全部按 v0.2 重刷(控件、表单、卡片、列表、工作台、读标)。Q1–Q12 全部按建议确认,写入设计规范;各页的共用问题收回到 `components.css`、`demo.css`、`demo.js`。Q13(流水记 0 点的「免扣」行)、U 键(撤销当前条)按建议确认。
|
||||
- 2026-11-03:MVP 原型 13 页全部按 v0.2 重刷:框架、项目头和标签页、对照布局、问题处理交互与 UI demo 一致,业务流程和红线内容不变。报告页脚与免责声明改为「本报告为辅助检查结果,仅供投标前自查参考」,规范 §7.17 和 FR-M3-09 同步,消除了「保证」字样。
|
||||
- 2026-11-03:技术架构升到 v0.3,新增 §3.14。团队版、企业版、飞书 / 企业微信登录都是以后的版本,早期不做;MVP 的表结构先按多人、多登录方式建:人 / 登录方式 / 成员身份分三层,项目成员表和统一的权限检查点先建好,以后接入不用重构(AR11、AR12)。
|
||||
- 待办:VI 手册页脚仍写「不构成……保证」,需要改 `vi-manual.html` 并重出 PDF。
|
||||
- 下一步:进入实现阶段前的工程准备(物理数据建模、接口契约、工程骨架,见 `docs/architecture/architecture.md` 第 12 节)。
|
||||
|
||||
@@ -7,7 +7,10 @@
|
||||
|
||||
```mermaid
|
||||
erDiagram
|
||||
Tenant ||--o{ User : "成员"
|
||||
Tenant ||--o{ Membership : "成员"
|
||||
User ||--o{ Membership : "成员身份"
|
||||
User ||--o{ LoginIdentity : "登录方式"
|
||||
Project ||--o{ ProjectMember : "项目成员"
|
||||
Tenant ||--o{ Subscription : "订阅"
|
||||
Tenant ||--|| QuotaAccount : "额度账户"
|
||||
QuotaAccount ||--o{ QuotaEntry : "流水"
|
||||
@@ -34,15 +37,18 @@ erDiagram
|
||||
QuotaEntry }o--o| CheckRun : "关联任务"
|
||||
```
|
||||
|
||||
所有业务实体都带 `tenant_id`,按租户隔离(PRD 7)。
|
||||
所有业务实体都带 `tenant_id`,按租户隔离(PRD 7)。User 和 LoginIdentity 例外,是全局的(技术架构 §3.14)。
|
||||
|
||||
## 2. 实体说明
|
||||
|
||||
| 实体 | 关键字段 | 说明 |
|
||||
|---|---|---|
|
||||
| **Tenant** 企业主体 | 名称、统一社会信用代码(可空)、当前套餐 | 额度和数据的归属单位(PRD 4.3:额度绑定企业主体) |
|
||||
| **User** 用户 | 手机号、所属租户、角色 | MVP 一个租户一个成员;角色字段先留着,给 V1 用 |
|
||||
| **Subscription** 订阅 | 套餐、起止日期、来源(注册赠送 / 人工开通 / 线上支付) | |
|
||||
| **User** 用户 | 显示名、状态 | 一个自然人,不属于某个租户;不做物理删除 |
|
||||
| **LoginIdentity** 登录方式 | 来源(手机号 / 飞书 / 企业微信 / 账号密码 / OIDC / LDAP)、外部组织编号、外部用户编号 | 一个人可以有多种登录方式 |
|
||||
| **Membership** 成员身份 | 用户、租户、企业角色、状态 | MVP 一个人只属于一个企业、一个企业一个成员(所有者);团队版放开成多席位(技术架构 §3.14) |
|
||||
| **ProjectMember** 项目成员 | 项目、用户、项目角色(负责人 / 编标 / 只读) | MVP 只有建项目的人,自动成为负责人 |
|
||||
| **Subscription** 订阅 | 套餐、起止日期、来源(注册赠送 / 人工开通 / 线上支付)、席位数 | MVP 席位数是 1 |
|
||||
| **QuotaAccount / QuotaEntry** 额度 | 单位(解析 / 检查 / 生成 / 查重)、类型(发放 / 预扣 / 结算 / 退回 / 过期 / 调整 / 免扣)、数量、关联任务、原因 | 只追加、不修改;余额由流水算出来 |
|
||||
| **Qualification** 资质 | 名称、类型、等级、证书号、发证机构、有效期、附件 | MVP 最小资质库 |
|
||||
| **Project** 投标项目 | 名称、编号、采购人、代理机构、采购方式、**法律体系**、截止时间、状态、所投包 | 基本信息来自 FR-M2-03,用户可以改 |
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# 技术架构设计 v0.2
|
||||
# 技术架构设计 v0.3
|
||||
|
||||
> 依据:PRD v0.9.1 第 7 章(非功能需求)、`docs/analysis/`(功能需求、领域模型、样本结论)、`docs/decisions.md`(T1 及各阶段决策)、参考项目分析 `ref-bid-engine-analysis.md`。
|
||||
> 状态:v0.2,选型已全部确认。
|
||||
> 状态:v0.3。v0.2 的选型已全部确认;v0.3 新增 §3.14:MVP 的表结构先按多人、多登录方式建,给以后的团队版、企业版、飞书 / 企业微信登录留结构(AR11、AR12,已确认)。
|
||||
> - 已确认(2026-11-03):T2–T5;AR1、AR3、AR5–AR9 按建议;AR2 改为 Vue 3 + Vite。
|
||||
> - 已确认:AR4 修订后的建议(引入 Valkey,只存可以丢的数据,§6.1);AR10 不引入带样式的 UI 框架(§4.3)。至此选型全部确认。
|
||||
> - 确认后写入 `docs/decisions.md`;构建、运行、测试命令等工程骨架搭好后回填到 AGENTS.md。
|
||||
@@ -147,7 +147,7 @@ flowchart LR
|
||||
|
||||
| 模块 | 职责 | 对应需求 |
|
||||
|---|---|---|
|
||||
| `identity` | 账号、企业主体(租户)、会话、短信验证码、登录风控 | FR-M6-04 |
|
||||
| `identity` | 人、登录方式、企业主体(租户)、成员身份、会话、短信验证码、登录风控、权限点(§3.14) | FR-M6-04 |
|
||||
| `billing` | 套餐、订阅、额度账户、额度流水 | FR-M6-03、05 |
|
||||
| `project` | 项目、分包、状态流、就绪标记 | FR-M6-01、02 |
|
||||
| `document` | 文件上传、格式识别、转换、文字层、OCR、出处定位 | FR-M2-01、06 |
|
||||
@@ -307,7 +307,7 @@ flowchart LR
|
||||
- 放在 PostgreSQL 而不是 Redis,理由见 §6.1:能持久化、能按用户列出所有会话(用来实现「同一账号异地多设备登录时提示并限制」,FR-M6-04),删除租户时也能级联清理。
|
||||
- 网页端用 HttpOnly + Secure cookie,桌面端用 Bearer 令牌并存进系统钥匙串。
|
||||
- **验证码和登录限流**:短信验证码、发送频率、登录失败次数都放在 Valkey 里,带过期时间。这些数据丢了,最多是用户重新获取一次验证码。
|
||||
- **身份来源可插拔**:SaaS 用手机号 + 短信验证码;私有化用账号密码,并预留 OIDC、LDAP 接入(P2 的 SSO)。
|
||||
- **身份来源可插拔**:SaaS 用手机号 + 短信验证码;私有化用账号密码,并预留 OIDC、LDAP 接入(P2 的 SSO);飞书、企业微信登录按同一接口扩展(§3.14)。
|
||||
- **密钥**:只从环境变量或密钥管理服务注入,代码和镜像里一律不放。启动时如果检测到默认密钥或弱密钥,在生产环境下拒绝启动。
|
||||
- **调试开关**:「跳过登录」之类的开关只在测试配置里存在;生产环境检测到这类开关会直接退出。
|
||||
- **加密**:
|
||||
@@ -409,6 +409,51 @@ flowchart LR
|
||||
- **报价**:模板里的报价位置只放空白填充位,由用户自己填写(红线 6)。
|
||||
- **OFD 格式**:标擎没有处理国家标准的 OFD 版式文件(GB/T 33190)。部分政府采购平台和电子公文会用到 OFD,需要在种子用户访谈时确认是否需要支持;需要的话再评估开源的 OFD 解析和转换库。
|
||||
|
||||
### 3.14 账号、企业与权限:给以后的版本留结构
|
||||
|
||||
以后会上团队版和企业版:一个企业多个席位,按角色和项目分权限;也会支持飞书、企业微信登录,以及私有化部署的 SSO。**这些功能早期版本都不做**。这一节只定一件事:MVP 的表结构和代码分层先按多人、多登录方式来建,以后上这些功能时只加功能,不用重构。
|
||||
|
||||
#### 原设计的问题
|
||||
|
||||
原设计的租户隔离(§3.3)和建在企业上的额度池(§3.9)不用改。会导致以后要重构的有三处:
|
||||
|
||||
1. **用户表直接带所属企业**(04 §2)。以后一个人要能有多种登录方式、要能离职、要能加入别的企业,就得拆表、迁移数据。
|
||||
2. **权限只有租户这一层**。以后加项目级权限,要回头给每个接口补检查,还要改所有列表查询。
|
||||
3. **记录「谁」的字段没约定指向哪张表**。如果指向会被删除的账号,人离职以后,留痕就断了。
|
||||
|
||||
#### MVP 就按这个结构建
|
||||
|
||||
| 内容 | MVP 的样子 | 以后接入时 |
|
||||
|---|---|---|
|
||||
| `user_account`:一个自然人,全局表,不带 `tenant_id` | 注册时建一条 | 不变 |
|
||||
| `login_identity`:登录方式,字段有来源、外部组织编号、外部用户编号;唯一键是「来源 + 外部组织 + 外部用户」 | 只有「手机号」一种来源 | 飞书、企业微信、账号密码、OIDC、LDAP 都只是新的来源 |
|
||||
| `membership`:人在企业里的成员身份,字段有企业角色、状态 | 每个企业一条,角色是「所有者」;「一人只属于一个企业」(FR-M6-04)在服务层检查,不写进表结构 | 加邀请、停用,放开一人多企业 |
|
||||
| `user_session` 绑定 `membership_id` | 当前租户从成员身份上取 | 切换企业就是换一个会话 |
|
||||
| `project_member`:项目、用户、项目角色 | 建项目的人自动成为负责人 | 加项目成员管理、可见范围 |
|
||||
| 订阅带「席位数」 | 写 1 | 按席位计费 |
|
||||
| 权限点枚举 + service 层统一调用 `authz.require(ctx, 权限点, 对象)` | 所有者拥有全部权限点,检查总是通过 | 加角色、改角色和权限点的对应关系;接口代码不用改 |
|
||||
| 列表查询走 repo 层统一的可见范围过滤 | 过滤条件只有租户 | 加「只有项目成员可见」的条件 |
|
||||
| `IdentityProvider` 接口:授权地址 → 回调换取用户信息 → 统一的外部身份 | 只有手机号验证码一个实现 | 每种新登录方式加一个实现 |
|
||||
|
||||
约定:
|
||||
|
||||
- 业务表里记录「谁」的字段(创建人、确认人、处理人)都指向 `user_account`。人不做物理删除,离职只停用成员身份。
|
||||
- 额度流水和审计事件都记操作人;审计再存一份操作人姓名快照,人离职后,报告和留痕上仍显示当时确认的人。
|
||||
- `user_account` 和 `login_identity` 是 §3.3 唯一的例外:全局表,不受行级安全策略约束,只能由 `identity` 模块读写,在 import-linter 规则里写明。
|
||||
- 行级安全策略只管租户这一层,项目级权限在应用层判断。
|
||||
|
||||
这些在 MVP 里多出来的工作只是两三张表和一层检查调用,界面上看不出任何区别。
|
||||
|
||||
#### 接入时再定的事
|
||||
|
||||
下面这些不影响表结构,到对应版本立项时再设计:
|
||||
|
||||
- 团队版、企业版的具体角色和权限点划分(PRD 写的是管理员 / 编标 / 只读);
|
||||
- 项目可见范围的默认值、分工指派;
|
||||
- 飞书、企业微信的应用形态,外部组织怎么绑定到企业,新成员是否需要批准,账号怎么合并;
|
||||
- 桌面端的第三方登录回调方式;
|
||||
- 个人注销和企业注销的拆分(MVP 只有一个成员,两者是同一个操作)。
|
||||
|
||||
## 4. 前端
|
||||
|
||||
### 4.1 Vue 3 单页应用(AR2,已确认)
|
||||
@@ -739,7 +784,8 @@ docs/ # 现有文档
|
||||
物理建模在下一步细化,这里先定原则:
|
||||
|
||||
- 主键用 **UUIDv7**:按时间有序、不可猜测;私有化环境和 SaaS 之间迁移数据时也不会冲突。
|
||||
- 所有业务表都带 `tenant_id`、`created_at`、`updated_at`;时间一律用 `timestamptz`。
|
||||
- 所有业务表都带 `tenant_id`、`created_at`、`updated_at`;时间一律用 `timestamptz`。例外只有 `user_account` 和 `login_identity` 两张全局表(§3.14)。
|
||||
- 业务表里记录「谁」的字段(创建人、确认人、处理人)都指向 `user_account`,不指向成员身份;人不做物理删除。
|
||||
- 出处(Citation)存:文档编号、规范化 PDF 的哈希、页码、句子编号、字符范围、坐标框数组(`quads`)。
|
||||
- AI 值和人工值分开存(§3.8);状态字段用枚举,不用自由文本。
|
||||
- 文字层的逐字数据量大,存在对象存储里;数据库里只存句子和块的索引,以及校验要用的文本。
|
||||
@@ -783,10 +829,12 @@ S1–S4 风险最高,建议先做;S8(桌面外壳 PoC)等桌面版立项
|
||||
| AR8 | 会话机制 | 服务端会话(可吊销),令牌只存哈希;网页端用 cookie,桌面端用 Bearer 令牌 | 已确认 |
|
||||
| AR9 | 仓库组织 | 单一仓库(monorepo) | 已确认 |
|
||||
| AR10 | UI 组件 | **不引入带样式的 UI 框架**:视觉自己写,复杂交互用 Reka UI(无样式)打底;表格、表单也用无样式方案(§4.3)。运营后台另议 | 已确认 |
|
||||
| AR11 | 身份模型 | 拆成人(`user_account`)、登录方式(`login_identity`)、成员身份(`membership`)三层,MVP 就按这个结构建;「一人只属于一个企业」在服务层限制(§3.14) | 已确认 |
|
||||
| AR12 | 权限检查点 | MVP 就建 `project_member` 表,service 层统一调用 `authz.require`,列表查询统一按可见范围过滤;具体角色划分到团队版再定(§3.14) | 已确认 |
|
||||
|
||||
## 12. 下一步
|
||||
|
||||
1. 做技术验证 S1–S4,结论写进本文件,并据此确定 FR-M2-05、FR-M2-06 的目标值。
|
||||
2. 物理数据建模:在 04 领域模型的基础上细化表结构,重点是清单项、出处、问题、额度流水。
|
||||
2. 物理数据建模:在 04 领域模型的基础上细化表结构,重点是清单项、出处、问题、额度流水,以及 §3.14 的人 / 登录方式 / 成员身份、项目成员。
|
||||
3. 定接口契约:先写核心接口的 OpenAPI 定义,前后端据此并行开发。
|
||||
4. 搭工程骨架:仓库结构、CI、Compose 一键启动、一个贯通「上传 → 解析 → 显示清单」的最小链路。
|
||||
|
||||
@@ -4,6 +4,13 @@
|
||||
|
||||
---
|
||||
|
||||
## AR11–AR12 · 2026-11-03 · 早期只给多人、多登录方式留结构
|
||||
|
||||
- **原则**:团队版、企业版(多席位、按角色和项目分权限)、飞书 / 企业微信登录、私有化 SSO 都是以后的版本,早期版本不做;但 MVP 的架构和表结构要先考虑到,以后能直接接进来,不用重构。理由:用户要求。
|
||||
- **AR11 身份分三层**:人(`user_account`)、登录方式(`login_identity`)、成员身份(`membership`),MVP 就按这个结构建;「一个手机号只属于一个企业」(FR-M6-04)在服务层检查,不写进表结构。
|
||||
- **AR12 权限检查点先建好**:`project_member` 表(建项目的人自动成为负责人)、service 层统一的 `authz.require`、列表查询统一按可见范围过滤;MVP 里唯一的成员是所有者,检查总是通过。具体角色、可见范围、飞书 / 企业微信的接入规则都到对应版本立项时再定。
|
||||
- **影响**:技术架构 v0.3 §3.14;04 领域模型的用户拆成 User / LoginIdentity / Membership,增加 ProjectMember,订阅增加席位数。
|
||||
|
||||
## Q13、U 键 · 2026-11-03 · 按建议
|
||||
|
||||
- **Q13 额度流水记录「免扣」行**:24 小时内复查不扣点时,也记一行流水,类型「免扣(24 小时内复查)」,数量 0,关联到这次检查。理由:红线 9 要求扣点规则可见、可查,用户能自己核对复查确实没扣点。影响:FR-M6-03 和 04 领域模型补「免扣」类型。
|
||||
|
||||
Reference in New Issue
Block a user