Repository模块

Vue项目Repository仓库模块设计,本文档主要用于记录开发时的一些灵感,具体实现看项目中的文档。

#type / howto #status / growing #tech / dev / pm

[!info] related notes


Repository 模块设计思路

核心职责:个人知识库 (PKM)、文件存储、元数据管理。

Overview

  • 一个用于笔记及其附件管理的模块
  • 可以考虑扩展为一个类似 nas 的文件管理系统

仓库模块用来帮用户管理知识文档(资源)。主要是 md文档,然后是图片,后续可能要扩展,支持音视频等各种文件。
额外功能:

  • 用户可能会在看一篇文章、视频时需要补充知识库。提供 关联内容的功能(直接保存网址),感觉可以通过仓库中初始化时添加默认关联文档,并在里面存储关联的内容。

资源:

  • 现在应该是 md 文档 或者图片、音视频
  • 一个资源的最小单位,包含了资源的基本信息(类型、大小、创建时间、修改时间、路径、名称、描述、作者、版本)
  • 资源引用
  • 标签/分类
  • 元数据扩展

服务

基础服务

仓库:

  • 作为一些资源的集合,提供资源的增删查改功能。
  • 多仓库
  • 仓库统计
  • 批量操作
  • 编辑,和 editor 模块紧密结合,作为资源管理器

复杂业务服务

  • 仓库同步
  • 每日总结功能: 提供 repository 模块相关的当日统计信息,比如修改、新增了哪些笔记、资源
  • 成为一个资源管理器: 在本地desktop 端可以实现,把实际不同位置的文件映射到同一个仓库中,然后用户可以通过 快捷方式打开一个 资源管理界面,来筛选,快速打开所需资源。

领域模型

聚合根对象:

  • Repository (仓库): 逻辑上的 buckets。
  • Resource (资源/文件): 核心对象。

实体对象:

  • ResourceVersion (版本控制): 如果要做简单的版本回溯。

关键值对象:

  • ResourceMeta (元数据): 文件大小、MIME 类型、路径。
  • ReferenceLink (引用链接): 存储关联的 URL。
  • ContentBlob (内容块): 对于 MD 文件,可能直接存文本;对于图片,存 S3/本地路径。

架构建

其他:

标签/分类:支持给资源打标签或分组,便于检索和管理。
资源预览:支持文档、图片、音频等的缩略图或预览功能。
资源权限:支持资源的访问控制(如私有、公开、指定用户可见)。
资源版本管理:支持资源的历史版本回溯与恢复。
资源引用关系:支持资源之间的引用、关联(如文档内嵌图片、附件等)。
资源状态:如草稿、已发布、归档、删除等状态管理。
资源元数据扩展:如自定义字段、扩展属性。

多仓库支持:允许用户创建多个仓库,按项目或用途分隔资源。
仓库备份与恢复:支持仓库级别的数据备份和恢复。
仓库同步:支持本地与云端仓库的同步。
仓库统计:如资源数量、容量、最近活跃等统计信息。
批量操作:支持资源的批量导入、导出、删除、移动等。

全文搜索:支持对资源内容和元数据的全文检索。
操作日志:记录资源的增删改查等操作历史,便于审计和追踪。
API/插件扩展:支持通过 API 或插件扩展仓库功能。
  1. 帮我根据新的接口实现

我们先来确定好 repository 模块 和 editor 模块的细节(领域范围、聚合根属性和业务、实体属性和业务、值对象、仓储接口,要包含哪些应用层业务、领域层服务), 我新的想法是:

  1. repository 模块应该还需要文件夹。数据库中可以有任意嵌套的普通文件夹和资源文件,就像一个资源管理器。(资源应该暂时只支持图片、音视频、md文档。 然后 repo 应该有编辑器页面,即预览模式、编辑模式(只有md文档有),这两个模式就像obsidian 一样,左边资源列表,右边编辑器渲染md内容或者图片、视频、音频。资源管理页面,以卡片的形式展示所有资源,类似 obsidian 的 base 页面
  2. editor 模块就上上面说的,应该是和 repo 模块紧密相连,嵌入在编辑器页面
  3. 总之,应该是 obsidian 的模仿版、低配版,普通编辑页面+数据库页面
  4. 请你帮我确定好两个模块的 domain 层、application 层业务方向细节。还有需要引入的库,obsidian 有没有相关的库,我感觉 monaco-editor 并不好用

等等等,你记得现在的 Editor 的功能要求吗,你说的那些应该是之前的 editor 的实体设计,你觉得按照新的 editor 要求,应该是需要哪些实体、聚合根、值对象。
补充一下,实现的目标是像 obsidian 一样的编辑,此时侧边栏的文件管理和搜索都应该属于 repository 模块,editor 模块在前端应该只是作为一个组件,repo 模块选择文件后传入 editor 提供的组件,将 传入内容渲染、编辑、多标签管理之类的功能。

我突然想到一个问题, 聚合根不是应该统一管理旗下的 子实体吗,你这个 聚合根实体的属性里面怎么都没有子实体;DTO 数据中也要有子实体的 DTO,在转换方法里也要递归转换;在接口获取时也都是DDD式的restful,只暴露聚合根的查,从聚合根携带的子实体中获取子实体。

  1. 当然得继续更新 RepositoryClient.ts 和其他 Client 接口
  2. 生成 domain-client 和 domain-server 的 repository 模块,我觉得不需要 domain-core 了,多一层感觉增加了复杂性。你帮我直接在domain 层中实现 repository 模块的领域层代码,聚合根、实体、值对象的的继承、实现,领域服务的实现(仓储用依赖注入,使用仓储接口的定义,到时候由应用层注入),仓储接口定义

然后开始使用这些工具来实现 repository 的前端 web 项目,复刻 obsidian,左边(最上方搜索、文件夹(编辑预览视图、管理视图+文件列+最下方切换仓库、设置管理)右边预览编辑区域; 当切换到管理视图时,左边的文件列表内容变为仓库/文件夹 的层级树,不显示文件,在预览区域显示该层级的文件、文件夹(以卡片形式展示),支持批量操作,导入导出等管理操作。

  1. 先实现 基础设施层、应用层、渲染层

    我详细讲讲渲染层

    1. 仓库管理Dialog,obsidian 中那个用于新建仓库,切换仓库、删除仓库的窗口
    2. 页面顶部组件(用于切换视图按钮、搜索按钮、页面标签
    3. 列表顶部按钮组组件
    4. 列表组件,用于层级渲染文件树
    5. 列表下方切换仓库(显示仓库名称、设置按钮)组件
    6. 预览、编辑组件(预览编辑视图时)
    7. 管理组件(管理视图时)
    8. repo主页面 页面标签和 预览编辑应该是 到时候 editor 模块的组件,先占位

常见疑问

DDD 中怎么添加新功能?以搜索为例

来源:questions

问题:现在有了基础的仓库和编辑器模块,要添加搜索功能。搜索属于仓储领域内部的业务,应该直接作为一个搜索服务吗?

解答思路

在 DDD 中添加新功能的判断路径:

  1. 判断业务归属:搜索是针对仓库内的资源进行检索,属于 Repository 聚合的业务范围,因此应放在 repository 模块内部,而非新建独立模块。
  2. 选择实现形式
    • 如果搜索只是简单的属性过滤(如按名称、标签筛选),可以直接作为 Repository 聚合根上的查询方法。
    • 如果搜索涉及全文检索、模糊匹配、排序评分等复杂逻辑,应抽象为领域服务(如 ResourceSearchService),因为它需要跨多个 Resource 实体进行查询,不适合放在单个实体内部。
    • 搜索的基础设施实现(如对接 Elasticsearch、Meilisearch 等)则放在基础设施层,通过接口解耦。
  3. 聚合根统一入口:搜索的调用仍应通过 Repository 聚合根或其领域服务暴露,保持 DDD 的封装原则——外部不直接访问子实体。

一句话原则:新功能先判断属于哪个领域/聚合,再判断复杂度决定放实体方法还是领域服务,基础设施细节下沉到基础设施层。

创建于 2025/1/1 更新于 2026/5/27