架构设计

本文档详细介绍 NexusBook API 的架构设计、目录结构和设计原则。

Document 核心概念架构

graph TB subgraph "Document 文档抽象" Doc["📄 Document
{doc-type}/{doc-id}"] subgraph "核心数据层 Core Data" Props["🏷️ Properties
文档属性
订单时间、门店、金额"] Meta["📋 Metadata
字段定义
25+ 字段类型"] Views["👁️ Views
视图配置
8 种视图类型"] Data["📊 Data
数据行
结构化数据"] Settings["⚙️ Settings
配置
文档/类型级"] end subgraph "协作层 Collaboration" Comments["💬 Comments
评论系统
文档/字段/行/单元格"] end subgraph "工作流层 Workflow" Requests["📝 Requests
变更请求
类似 Git PR"] Revisions["📜 Revisions
修订历史
完整变更追踪"] Approvals["✅ Approvals
审批流程
多层级审批"] end end subgraph "查询能力 Query Engine" Filter["🔍 Filter
过滤器
嵌套逻辑"] Sort["📶 Sort
排序
多字段"] Group["📊 Group
分组聚合
5 种聚合函数"] Aggregate["🎯 Aggregate
聚合查询
一次获取多种数据"] end subgraph "认证授权 Auth" OAuth["🔐 OAuth2/OIDC
标准认证"] Token["🎫 JWT Token
令牌管理"] Scope["🔑 Scopes
权限控制"] end Doc --> Props Doc --> Meta Doc --> Views Doc --> Data Doc --> Settings Doc --> Comments Doc --> Requests Doc --> Revisions Doc --> Approvals Data --> Filter Data --> Sort Data --> Group Doc --> Aggregate Requests -->|合并生成| Revisions Requests -->|可选| Approvals Data -->|默认生成| Requests %% Removed apply=true edge OAuth --> Token Token --> Scope Scope --> Doc

核心概念说明:

  • Document - 统一的文档抽象,支持多种业务类型(订货单、产品、库存等)
  • 核心数据层 - Properties(文档属性)、Metadata(字段定义)、Views(视图)、Data(数据行)、Settings(配置)
  • 协作层 - Comments 支持在文档任何位置进行评论和讨论
  • 工作流层 - Requests(变更请求)→ Revisions(修订历史)+ Approvals(审批流程)
  • 查询能力 - 强大的过滤、排序、分组和聚合查询
  • 认证授权 - OAuth2/OIDC 标准认证,基于 Scope 的权限控制

租户数据核心概念架构

NexusBook 采用多租户 SaaS 架构,通过 Organization(组织)和 Workspace(工作区)实现数据隔离和权限管理,设计理念参考 Miro 的协作模式。

graph TB subgraph "多租户架构 Multi-Tenant Architecture" User["👤 User
用户
独立实体"] subgraph "Organization 组织(租户)" Org["🏢 Organization
组织/租户
数据隔离边界"] OrgMember["👥 Organization Members
组织成员
owner/admin/member/guest"] subgraph "工作区 Workspaces" WS1["📚 主数据中心
Workspace A
包含 product, supplier"] WS2["🍜 朝阳餐厅
Workspace B
引用 A 的 product"] WS3["🛍️ 海淀超市
Workspace C
引用 A 的 product, supplier"] WS4["🚚 绿源供应商
Workspace D
独立数据"] end WSMember["👥 Workspace Members
工作区成员
owner/editor/viewer"] Invite["✉️ Invitation
邀请机制
邮箱邀请"] JoinReq["📝 Join Request
加入申请
用户主动申请"] end subgraph "数据共享关系 Data Sharing" Ref1["🔗 B 引用 A.product
readonly"] Ref2["🔗 C 引用 A.product
readonly"] Ref3["🔗 C 引用 A.supplier
readonly"] end end User -->|注册时自动创建| Org User -->|owner| Org User -->|加入| OrgMember Org -->|包含| WS1 Org -->|包含| WS2 Org -->|包含| WS3 Org -->|包含| WS4 Org -->|创建时自动创建| WS1 OrgMember -->|需显式加入| WSMember Org -->|邀请用户| Invite Org -->|接受申请| JoinReq WS2 -.->|数据源引用| Ref1 WS3 -.->|数据源引用| Ref2 WS3 -.->|数据源引用| Ref3 Ref1 --> WS1 Ref2 --> WS1 Ref3 --> WS1 style Org fill:#e1f5ff style WS1 fill:#d4edda style WS2 fill:#fff4e6 style WS3 fill:#fff4e6 style WS4 fill:#fff4e6 style User fill:#f0f0f0 style Ref1 fill:#ffeaa7 style Ref2 fill:#ffeaa7 style Ref3 fill:#ffeaa7

核心概念说明

1. User(用户)- 独立身份实体

  • 独立性:用户是系统中的独立实体,不依附于任何组织
  • 自动组织:用户注册时,系统自动创建一个 Personal 类型的 Organization,用户成为该组织的 owner
  • 多组织成员:一个用户可以同时是多个 Organization 的成员
  • 身份验证:支持邮箱/密码、OAuth 第三方登录(Google、GitHub、微信、钉钉、飞书)

2. Organization(组织)- 租户边界

  • 租户隔离:Organization 是数据隔离的基本单元,类似 Miro 的 Team
  • 组织类型
    • personal:个人组织(用户注册时自动创建)
    • team:团队组织
    • enterprise:企业组织
  • 成员角色
    • owner:组织拥有者,拥有所有权限(包括删除组织、转让所有权)
    • admin:管理员,可管理成员、工作区、组织设置
    • member:普通成员,可访问被授权的工作区
    • guest:访客,仅能访问特定资源
  • 默认工作区:创建组织时自动创建一个默认 Workspace,通常作为主数据中心使用

3. Workspace(工作区)- 业务容器

Workspace 是 Organization 内的数据组织容器,所有 Workspace 地位平等,通过数据源引用机制实现跨工作区数据共享。

基本特性

  • 数据隔离:每个 Workspace 的 Document 数据默认独立隔离
  • 灵活共享:可选择性地引用其他 Workspace 的特定 document type 数据
  • 显式加入:组织成员需要被显式添加到 Workspace 才能访问其中的内容
  • 成员角色
    • owner:工作区负责人,可管理工作区和成员
    • editor:编辑者,可创建和编辑文档
    • viewer:查看者,只读权限
  • 可见性控制
    • public:组织内所有成员可见(建议主数据中心使用)
    • private:仅成员可见(建议业务工作区使用)

典型场景

  • 📚 主数据中心:存放组织级共享主数据(产品目录、供应商名录、标准菜谱等)
  • 🍜 餐厅工作区:每家餐厅的独立运营管理(朝阳餐厅、西城餐厅等)
  • 🛍️ 超市工作区:超市的采购与库存管理(海淀超市、西单超市等)
  • 🚚 供应商工作区:供应商的订单与发货管理(绿源供应商、丰收农场等)
  • 🏭 仓库工作区:仓库的进出库管理
4. 数据源引用机制(Data Source Reference)

Workspace 支持引用其他 Workspace 的特定 document type 数据,采用替换模式

替换模式

  • Workspace B 引用 Workspace A 的 product 数据后,查询 product 只显示 A 的数据(只读)
  • Workspace B 自己的 product 数据被隐藏(但未删除)
  • 解除引用后,本地数据恢复显示

查询逻辑

  • 有活跃引用:查询源 Workspace 的数据,标记为只读
  • 无引用或引用已停用:查询本地数据,可编辑

5. 成员管理机制

邀请流程(Invitation)

sequenceDiagram participant Admin as 👤 管理员
(owner/admin) participant System as 🌐 系统 participant User as 👤 被邀请用户 participant Email as 📧 邮件 Admin->>System: POST /organizations/{id}/invitations
创建邀请 System->>Email: 发送邀请邮件(包含令牌链接) Email->>User: 接收邮件 User->>System: POST /invitations/{token}/accept
接受邀请 System->>System: 创建 OrganizationMember System-->>User: 成功加入组织 Note over Admin,User: 管理员可以撤销未接受的邀请
DELETE /invitations/{id}

加入申请流程(Join Request)

sequenceDiagram participant User as 👤 申请用户 participant System as 🌐 系统 participant Admin as 👤 管理员
(owner/admin) User->>System: POST /organizations/{id}/join-requests
提交申请 System->>Admin: 通知有新申请 Admin->>System: GET /join-requests
查看申请列表 alt 批准申请 Admin->>System: POST /join-requests/{id}/approve
批准 System->>System: 创建 OrganizationMember System-->>User: 通知申请通过 else 拒绝申请 Admin->>System: POST /join-requests/{id}/reject
拒绝 System-->>User: 通知申请被拒绝(含原因) end Note over User,Admin: 用户可以取消自己的申请
DELETE /join-requests/{id}

6. 角色权限矩阵

Organization 角色权限

操作 owner admin member guest
查看组织信息
更新组织设置
删除组织
邀请成员
管理成员角色
移除成员
创建工作区
管理工作区

Workspace 角色权限

操作 owner editor viewer
查看工作区
查看文档
创建文档
编辑文档
删除文档
管理成员
工作区设置

7. 数据隔离与安全

隔离层级

Organization(租户级隔离)
  └── Workspace(业务级隔离)
        └── Document(文档级隔离)
              ├── Properties(文档属性)
              ├── Metadata(字段定义)
              ├── Data(数据行)
              └── Views(视图配置)

权限校验流程

  1. 用户身份验证:验证 JWT Token
  2. 组织成员检查:确认用户是该 Organization 的成员
  3. 工作区权限检查:确认用户在该 Workspace 中的角色
  4. 操作权限验证:根据角色验证是否有权限执行操作
  5. 数据访问控制:仅返回用户有权访问的数据

部分API

认证与用户

API 方法 功能
/api/v1/auth/register POST 用户注册,系统自动创建个人 Organization 和默认 Workspace

组织管理

API 方法 功能
/api/v1/organizations POST 创建组织,系统自动创建默认 Workspace
/api/v1/organizations/{orgId}/invitations POST 邀请成员加入组织
/api/v1/invitations/{token}/accept POST 接受组织邀请

工作区管理

API 方法 功能
/api/v1/organizations/{orgId}/workspaces POST 创建工作区
/api/v1/organizations/{orgId}/workspaces/{wsId} PATCH 配置工作区名称、可见性等
/api/v1/organizations/{orgId}/workspaces/{wsId}/members POST 添加工作区成员

数据源引用管理

API 方法 功能
/api/v1/organizations/{orgId}/workspaces/{wsId}/data-source-references GET 列出当前工作区的所有引用配置
/api/v1/organizations/{orgId}/workspaces/{wsId}/data-source-references POST 添加数据源引用(替换模式)
/api/v1/organizations/{orgId}/workspaces/{wsId}/data-source-references/{refId} GET 获取单个引用详情
/api/v1/organizations/{orgId}/workspaces/{wsId}/data-source-references/{refId} PATCH 暂停/启用引用
/api/v1/organizations/{orgId}/workspaces/{wsId}/data-source-references/{refId} DELETE 解除引用,恢复本地数据显示

数据引用说明

  • 当 workspace 引用其他 workspace 的 product 数据时,查询只返回源 workspace 的数据,本地数据被隐藏
  • 解除引用后,查询恢复返回本地数据
  • 数据源替换无损,本地数据不会丢失

权限控制说明

场景 结果 说明
用户是 workspace-b owner,但不是 workspace-a 成员 403 Forbidden 添加引用时必须对源 workspace 有读权限
用户是 workspace-b editor,不是 owner 403 Forbidden 只有 workspace owner 可管理引用
用户是 Organization admin 200 OK Organization admin 可强制配置引用

目录结构

api/
├── main.tsp                    # 顶层入口
│
├── shared/                     # 共享基础模块
│   ├── common.tsp             # 通用类型(ApiResponse, Filter, Value...)
│   ├── constants.tsp          # 枚举定义
│   └── index.tsp              # 模块入口
│
├── auth/                       # 认证模块
│   ├── models.tsp             # OAuth2/OIDC 模型
│   └── index.tsp              # 模块入口
│
└── document/                   # 文档模块
    ├── core/                  # 核心数据模型
    │   ├── metadata.tsp       # 字段定义
    │   ├── data.tsp           # 数据行管理
    │   ├── properties.tsp     # 文档属性
    │   ├── views.tsp          # 视图配置
    │   ├── settings.tsp       # 设置
    │   └── index.tsp
    │
    ├── content/               # 内容协作
    │   ├── comments.tsp       # 评论系统
    │   └── index.tsp
    │
    ├── workflow/              # 工作流管理
    │   ├── approvals.tsp      # 审批流程
    │   ├── requests.tsp       # 变更请求
    │   ├── revisions.tsp      # 修订历史
    │   └── index.tsp
    │
    ├── aggregate/             # 聚合查询
    │   └── index.tsp
    │
    ├── operations/            # 预留目录
    └── index.tsp

架构层次

graph TB subgraph "顶层 Top Level" Main["📄 main.tsp
顶层入口"] end subgraph "基础层 Foundation Layer" Shared["📦 shared/
共享基础模块"] Common["common.tsp
通用类型"] Constants["constants.tsp
枚举定义"] Shared --> Common Shared --> Constants end subgraph "认证层 Auth Layer" Auth["🔐 auth/
认证模块"] AuthModels["models.tsp
OAuth2/OIDC"] Auth --> AuthModels end subgraph "业务层 Business Layer" Document["📚 document/
文档模块"] subgraph "核心 Core" Core["core/"] Metadata["metadata.tsp"] Data["data.tsp"] Properties["properties.tsp"] Views["views.tsp"] Settings["settings.tsp"] Core --> Metadata Core --> Data Core --> Properties Core --> Views Core --> Settings end subgraph "协作 Content" Content["content/"] Comments["comments.tsp"] Content --> Comments end subgraph "工作流 Workflow" Workflow["workflow/"] Approvals["approvals.tsp"] Requests["requests.tsp"] Revisions["revisions.tsp"] Workflow --> Approvals Workflow --> Requests Workflow --> Revisions end subgraph "聚合 Aggregate" Aggregate["aggregate/"] AggregateAPI["index.tsp"] Aggregate --> AggregateAPI end Document --> Core Document --> Content Document --> Workflow Document --> Aggregate end subgraph "扩展层 Extension Layer" Extensions["🔌 extensions/
扩展模块
预留"] Integrations["integrations/"] Webhooks["webhooks/"] Extensions -.-> Integrations Extensions -.-> Webhooks end Main --> Shared Main --> Auth Main --> Document Main -.-> Extensions Auth --> Shared Document --> Shared Extensions -.-> Shared Core --> Shared Content --> Shared Workflow --> Shared Aggregate --> Shared Workflow --> Core Aggregate --> Core Aggregate --> Content Aggregate --> Workflow

依赖关系说明:

  • 实线箭头 - 直接依赖关系
  • 虚线箭头 - 预留/可选依赖
  • 颜色分层 - 蓝色(顶层)→ 橙色(基础)→ 粉色(认证)→ 绿色(业务)→ 紫色(扩展)

依赖原则:

  1. 单向依赖 - 上层依赖下层,下层不依赖上层
  2. 基础优先 - 所有模块都依赖 shared 基础层
  3. 模块独立 - 同层模块之间尽量独立
  4. 聚合组合 - aggregate 模块组合其他模块的功能

设计原则

  1. 分层架构 - 清晰的 4 层结构(shared → auth → document → extensions)
  2. 单一职责 - 每个模块功能明确,职责单一
  3. 依赖管理 - 明确的依赖关系,避免循环依赖
  4. 可扩展性 - 预留扩展目录,支持动态扩展
  5. 模块化 - 高内聚低耦合,便于维护和测试

模块职责

模块 职责 主要内容
shared 基础设施 通用类型、错误码、过滤器、聚合函数
auth 认证授权 OAuth2、OIDC、JWT、用户信息
document/core 核心数据 元数据、数据行、属性、视图、设置
document/content 内容协作 评论系统
document/workflow 工作流 审批、请求、修订
document/aggregate 聚合查询 一次性获取多种数据
extensions 扩展功能 集成、Webhooks(预留)

数据流与工作流

sequenceDiagram participant User as 👤 用户 participant API as 🌐 API participant Request as 📝 Request participant Approval as ✅ Approval participant Revision as 📜 Revision participant Data as 📊 Data Store Note over User,Data: 场景 1: 直接应用变更 (apply=true) User->>API: POST /data?apply=true API->>Data: 直接写入数据 API->>Revision: 生成修订记录 Revision-->>User: 返回修订 ID Note over User,Data: 场景 2: 创建变更请求(默认) User->>API: POST /data API->>Request: 创建 Request Request-->>User: 返回 Request ID Note over User,Data: 场景 3: 多人协作编辑 User->>Request: 添加/修改变更 User->>Request: 继续编辑 Note over Request: 多个用户可以
在同一 Request 中
协作编辑 Note over User,Data: 场景 4: 审批流程 User->>API: POST /requests/{id}/merge API->>Approval: 触发审批流程 Approval->>Approval: 多层级审批 alt 审批通过 Approval->>Request: 批准合并 Request->>Data: 应用变更 Request->>Revision: 生成修订 Revision-->>User: 完成 else 审批拒绝 Approval->>Request: 拒绝 Request-->>User: 需要修改 end Note over User,Data: 场景 5: 版本对比与回滚 User->>API: GET /revisions/{id}/diff?base={base-id} API-->>User: 返回差异 User->>API: POST /revisions/{id}/revert API->>Request: 创建回滚 Request Request->>Data: 应用回滚 API->>Revision: 生成回滚修订 Revision-->>User: 完成回滚

工作流说明:

  1. 直接应用 - 使用 ?apply=true 参数直接写入数据并生成修订
  2. 变更请求 - 默认创建 Request,支持多人协作编辑
  3. 审批流程 - 可选的多层级审批机制
  4. 修订追踪 - 所有变更都会生成修订记录
  5. 版本回滚 - 支持对比和回滚到任意历史版本

字段类型与值类型映射

graph LR subgraph "字段类型 Field Types" F1["text
long_text"] F2["number
currency
percent"] F3["boolean"] F4["date
datetime"] F5["duration"] F6["single_select"] F7["multi_select"] F8["rating"] F9["attachment"] F10["user"] F11["collaborator"] F12["relation"] F13["lookup
rollup
formula"] end subgraph "值类型 Value Types" V1["string"] V2["float64"] V3["boolean"] V4["string
ISO 8601"] V5["int64
毫秒"] V6["SelectOption"] V7["SelectOption[]"] V8["int32
1-5"] V9["Attachment[]"] V10["UserRef"] V11["CollaboratorRef"] V12["RelationRef[]"] V13["动态类型"] end F1 --> V1 F2 --> V2 F3 --> V3 F4 --> V4 F5 --> V5 F6 --> V6 F7 --> V7 F8 --> V8 F9 --> V9 F10 --> V10 F11 --> V11 F12 --> V12 F13 --> V13

文档类型路由

Provider 模式:

/api/v1/doc/{doc-type}/{doc-id}
              ↓
        Provider 解析
              ↓
    ┌─────────┼─────────┐
    ▼         ▼         ▼
 Product  Purchase   Invoice
 Provider  Provider  Provider

扩展新类型:

  • 实现对应的 Provider
  • 注册到路由系统
  • 无需修改 API 定义

资源抽象

Doc: {doc-type} + {doc-id}
  ├── properties    # 文档属性(订单时间、门店、金额等)
  ├── metadata      # 字段定义
  ├── views         # 视图配置
  ├── data          # 数据行
  ├── comments      # 评论
  ├── revisions     # 修订历史
  ├── requests      # 变更请求
  ├── approval      # 审批流程
  └── settings      # 设置

下一步