Files
agent/docs/superpowers/specs/2026-07-24-project-documents-workbench-design.md

4.4 KiB
Raw Blame History

项目笔记资料Documents工作台设计

目标

将项目内原有的笔记与资料能力破坏性重构为统一的 document 领域。技术命名只使用 document/documents,中文产品名称继续使用“笔记资料”。

本次不迁移旧 SaNoteSaSource 数据,也不保留旧 API。

数据模型

  • SaDocument:项目内树节点,支持 folderfile保存父节点、名称、MIME、扩展名、 大小、修订号、来源 Inbox 和软删除状态。
  • SaDocumentContentMarkdown 可编辑正文,与文件节点一对一。
  • SaDocumentBlob:二进制文件存储元数据,与文件节点一对一;物理路径只能由 document 文件服务构造。
  • SaDocumentShare:匿名只读预览链接,数据库只保存随机 token 的哈希、过期时间和撤销时间。

目录内名称忽略大小写唯一。手工重命名遇到重名返回冲突;新建与上传自动追加 (1)

后端契约

API 根路径为 /api/v1/projects/:projectId/documents,提供:

  • 获取项目文档树;
  • 新建目录与 Markdown
  • 上传单个文件(单文件 50 MB
  • 读取文档详情和内容;
  • 使用 revision 更新 Markdown冲突时拒绝覆盖
  • 重命名、移动与软删除;
  • 下载原文件;
  • 将 Markdown 导出为 .md.pdf.docx
  • 创建、列出和撤销有效期分享链接。

匿名分享 API 只暴露单个文档的只读预览,不暴露项目、目录树或创建人,不允许下载。 无效、过期与撤销 token 均返回 404。

旧表和旧任务关联在版本化迁移中直接删除,不做数据转换。

页面布局

保留工作台顶部栏、项目 rail、项目 sidebar 与状态栏。documents 频道内容区采用无标题、 无副标题、无卡片边距的全画布布局:

  • 左侧:可调整宽度、可折叠的文件树;顶部只有新建目录和新建 Markdown 图标;
  • 右侧VS Code 风格横向多标签区与主编辑/预览区;
  • 标签栏末尾固定编辑/预览、保存、导出和分享操作;
  • 文件树底部显示可展开的上传队列和汇总进度。

目录优先并按名称自然排序。文件和目录可拖动移动,禁止目录移入自身或后代。正文侧拖入 的文件一律上传至项目根目录。

编辑、标签与自动保存

  • Markdown 使用 CodeMirror 6
  • Markdown 编辑与预览采用单面切换;
  • 没有标签时显示本地 新建文件1.md,首次输入或手工保存后才创建正式文档;
  • 停止输入 800ms 后自动保存;
  • 标签展示未保存、保存中、已保存和失败状态;
  • 保存失败时保留本地草稿并重试;
  • 标签按项目保存到浏览器;同一文档只打开一个标签;
  • 服务端使用单调递增 revision 防止多窗口静默覆盖。

预览与导出范围

  • Markdown编辑和安全渲染预览
  • PDF内嵌预览
  • 图片PNG、JPEG、GIF、WebP、SVGSVG 净化后预览);
  • 文本和代码:只读文本;
  • 音视频:浏览器原生播放器;
  • DOCX只读内容预览
  • XLS/XLSX只读表格预览
  • 其他格式:显示元数据并允许项目成员下载。

Markdown 导出支持 Markdown、PDF 和 DOCX。导出由后端生成临时响应不写回文件树。 PDF 使用随服务端发布的中文字体。复杂 HTML、Mermaid、数学公式和远程图片不在本轮保证范围。

上传

每个文件独立请求,单文件上限 50 MB客户端最多并发 3 个。上传区显示当前文件、总进度、 成功/失败计数并允许展开查看、取消和重试。Markdown 上传后成为可编辑数据库正文,其他 文件作为二进制文档。

跨频道入口

前端使用幂等的 DocumentOpenIntent 接收其他频道的 create/open 请求。Inbox、AI 和探索页 只做接入 document 的最小改动AI 内容仍须用户确认后才能成为正式对象。Inbox 生成的文档 保留来源 Inbox ID。

安全

  • 服务端校验项目所有权、父目录项目归属、扩展名、MIME 和内容嗅探结果;
  • 磁盘使用随机存储键;
  • Markdown/HTML/SVG 预览禁止脚本与危险 URL
  • Office 预览不执行宏、外链或嵌入对象;
  • 匿名分享页使用严格 CSP 和 noindex
  • 为后续病毒扫描状态预留字段,本轮不接入病毒扫描。

响应式

桌面端使用左右分栏。窄屏下文件树与编辑器切换展示,不强制压缩为双栏。