Files
goodbuddy/docs/features/office-document-editing/technical-design.md
T

9.1 KiB
Raw Blame History

Office 协同编辑技术设计

文档信息

项目 内容
状态 设计中
版本 0.1
日期 2026-09-09
关联 PRD Office 协同编辑 PRD
跨端架构 ShareServer 联邦网络总体设计

1. 技术选型

首个 Provider 使用 ONLYOFFICE Docs Developer Edition。采用前必须确认当前许可证、桌面应用 分发权、并发连接口径、白标、Automation API、离线私有部署和安全支持;技术设计不构成授权 结论。

不采用:

  • ONLYOFFICE Desktop Editors:它是独立桌面产品,不是 GoodBuddy 工作栏嵌入 SDK。
  • Node/Python OOXML 库:只提供生成或结构化处理,不提供高保真画布、选区和撤销栈。
  • Microsoft WOPI:第三方接入资格和云授权不适合作为 GoodBuddy 默认能力。
  • 自研 OOXML 渲染器:格式兼容和编辑成本超出当前产品边界。

后续 Provider 可以增加 Univer Sheets,但只能按通过验收的格式和能力声明,不能由“纯前端”推导 为完整 Office 兼容。

2. 组件边界

GoodBuddy Renderer
  └─ 文档 Tab 外壳、公开状态、用户命令

GoodBuddy Main
  ├─ DocumentEditSessionService
  ├─ 本地/SSH 源文件 Grant 与校验
  ├─ 上传、下载、原子回写和冲突检测
  ├─ OfficeEditorView 生命周期
  └─ 本地活动记录

ShareServer
  ├─ 用户、设备、组织和策略认证
  ├─ Office 会话 API 与短期启动授权
  ├─ 工作副本、保存检查点和保留清理
  ├─ ONLYOFFICE JWT、文件 URL 和 callback handler
  ├─ 编辑器版本、健康、配额和审计
  └─ 可选 AI 编辑消息中继

ONLYOFFICE Document Server
  └─ Word、Spreadsheet、Presentation Web Editors

ShareServer 可以把 ONLYOFFICE 和对象存储作为同一部署套件的依赖管理,但两者仍是独立服务。 Desktop 不读取 Document Server 地址或密钥,只消费 ShareServer 返回的一次性编辑启动 URL。

3. 工作栏实例

在工作栏应用注册表新增多实例 document:

type DocumentPanelInstance = {
  id: string
  capability: 'document'
  documentSessionId: string
  displayName: string
  duplicateIndex?: number
  binding: { mode: 'pinned'; target: { type: 'document-session'; id: string } }
  dock: 'right' | 'bottom' | 'window'
}

持久布局只保存公开会话 ID、显示名、来源对象 ID 和停靠方式,不保存启动 URL、Cookie、文件 令牌、绝对路径或 ONLYOFFICE 配置。应用恢复时由 Main 重新认证并判断会话能否恢复。

编辑器内容不使用现有静态 HTML iframe sandbox=""。Main 为每个已加载会话创建独立 WebContentsView,固定允许的 ShareServer origin、隔离 session partition、关闭 Node integration、开启 context isolation 和 sandbox,并禁用新窗口、任意下载、权限请求和非允许 导航。远端页面不获得通用 Electron preload API。

多页签允许多个会话描述同时存在;只有经过资源验收的有限数量编辑器保持加载。非活动实例的 具体挂起和恢复阈值在跨平台内存测试后冻结,不能未经保存检查点直接销毁 dirty 编辑器。

4. ShareServer API 边界

建议的服务端资源:

POST   /api/v1/office/sessions
PUT    /api/v1/office/sessions/{id}/source
POST   /api/v1/office/sessions/{id}/launch
GET    /api/v1/office/sessions/{id}
GET    /api/v1/office/sessions/{id}/events
GET    /api/v1/office/sessions/{id}/checkpoints/{revision}
POST   /api/v1/office/sessions/{id}/source-commit
DELETE /api/v1/office/sessions/{id}

GET    /internal/office/files/{objectToken}
POST   /internal/office/callback/{callbackToken}

Desktop API 使用设备凭据和组织 audience。启动 URL 使用一次性 code,交换为 HttpOnly、Secure、 SameSite Cookie 后立即失效。ONLYOFFICE 文件 URL、callback URL 和 JWT 使用独立 audience、短 有效期及单会话绑定,不能用于普通 ShareServer API。

ShareServer 不把对象存储公开 URL 直接返回 Renderer。文件下载必须重新验证用户、设备、会话、 revision 和策略,并返回声明大小和 SHA-256。

5. 会话契约

type CreateDocumentEditSession = {
  source: {
    kind: 'workspace-file' | 'artifact'
    publicSourceId: string
    displayName: string
    mediaType: string
    size: number
    sha256: string
  }
  requestedAccess: 'edit' | 'read-only'
}

type DocumentEditSessionSummary = {
  id: string
  state: 'uploading' | 'ready' | 'editing' | 'offline' | 'expired' | 'closed'
  access: 'edit' | 'read-only'
  documentType: 'word' | 'cell' | 'slide'
  displayName: string
  sourceRevision: string
  checkpoint?: {
    revision: string
    size: number
    sha256: string
    createdAt: string
  }
  retentionExpiresAt: string
}

远端值全部经过有界 schema 校验。publicSourceId 是 Desktop 管理的对象 ID,不是文件路径。

6. 文件与保存

  • Desktop 从已授权本地或 SSH 源读取并流式计算大小和 SHA-256。
  • 上传目标由 Main 从固定 ShareServer API 获得,不接受 Renderer 提供 URL。
  • ShareServer 写入随机对象键,拒绝用户文件名决定存储路径。
  • ONLYOFFICE callback 先写临时对象,校验后原子发布为新 checkpoint。
  • Desktop 下载 checkpoint 到 GoodBuddy-owned 暂存,复核大小、SHA-256、普通文件属性和文件 magic,再在源文件同目录创建临时文件并原子替换。
  • SSH 源文件由远程 GoodBuddy Agent 执行相同摘要、冲突和原子替换,不把远程凭据交给 ShareServer。
  • 每次成功回写后 Desktop 将新摘要作为下一次冲突检测基准。

7. 编辑器桥与 AI 编辑

ShareServer 托管固定版本的 GoodBuddy ONLYOFFICE 插件。插件只能:

  • 获取当前会话和有界选区描述;
  • 发起 AI 编辑请求并显示状态;
  • 接收受限结构化编辑操作;
  • 在一个编辑器撤销上下文中应用、回滚和高亮修改;
  • 发布不含正文的 dirty、save 和 revision 事件。

首期优先让插件通过 ShareServer 会话通道与 Desktop 交换事件,不给远端编辑页面添加通用 Electron preload。ShareServer 只中继有界事件;Agent 请求仍由 Desktop 创建并经过现有 Conversation、模型、Ask/Execute、取消和活动记录边界。

Ask 请求可以返回可复制的修改建议,但 Main 拒绝向插件下发写操作。只有 Execute 请求能够 取得绑定当前文档会话、revision 和选区的短期编辑 Grant;该 Grant 不包含源文件路径,也不能 用于其他文档、文件工具或系统能力。

结构化操作按文档类型单独列白名单,例如文本替换、单元格值或公式更新、幻灯片对象文字 替换。禁止传入 JavaScript、宏、任意 ONLYOFFICE 方法名或表达式求值。

8. 部署与配置

ShareServer 部署清单新增可选 Office 组件:

ShareServer API
PostgreSQL
兼容 S3 的对象存储
ONLYOFFICE Document Server
Office callback worker

服务端管理配置包含 Document Server 内部地址、公开编辑 origin、JWT 密钥引用、对象存储、 允许格式、文件大小、并发、会话期限和 checkpoint 保留。管理界面提供真实健康检查:创建最小 文档、打开编辑器、执行保存回调并核对输出,而不是只检查 HTTP 端口。

Desktop 仅显示某个 ShareServer 是否声明并实际通过 office.edit 能力检查。未配置或不健康时 保留文档入口并说明不可用原因。

9. 安全边界

  1. ShareServer 和 ONLYOFFICE 之间使用独立网络和凭据,不公开管理接口。
  2. 文档内容是不可信输入;禁用宏、外部插件、任意外链加载和 Document Server 出站网络。
  3. 每个文件 URL、callback 和启动授权绑定单会话、单用途和短期限。
  4. Renderer 不接触设备凭据、ONLYOFFICE JWT、对象存储凭据或本机绝对路径。
  5. 编辑器 origin 不能调用任意 IPC、Shell、文件系统、浏览器或 Runtime 工具。
  6. 上传、下载、callback、事件和 AI 操作限制字节数、频率、并发和总时长。
  7. 服务端保留策略到期后清理工作副本、checkpoint、编辑 Cookie 和对象令牌;审计元数据按组织 策略独立保留。
  8. 组织管理员能够撤销 Office 能力和活动会话;撤销后 Desktop 仍保留本地源文件,不把服务端 删除描述为本地删除。

10. 实施顺序

  1. 在 ShareServer 独立仓库补充 Office 服务 PRD、部署配置、对象存储和 ONLYOFFICE 许可证决策。
  2. 实现服务端最小会话、上传、启动、callback、checkpoint、下载和清理闭环。
  3. Desktop 增加多实例文档页签和只读打开,完成三平台真实视觉及资源验证。
  4. 接入源文件冲突检测、原子保存、另存为、关闭和恢复。
  5. 实现固定 ONLYOFFICE 插件及单次可撤销 AI 选区修改。
  6. 增加组织策略、配额、审计和生产部署验收。

不得在服务端闭环、许可证和三平台真实编辑验收前把该能力标记为已提供。