Repository模块
Vue项目Repository仓库模块设计,本文档主要用于记录开发时的一些灵感,具体实现看项目中的文档。
[!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 或插件扩展仓库功能。
- 帮我根据新的接口实现
我们先来确定好 repository 模块 和 editor 模块的细节(领域范围、聚合根属性和业务、实体属性和业务、值对象、仓储接口,要包含哪些应用层业务、领域层服务), 我新的想法是:
- repository 模块应该还需要文件夹。数据库中可以有任意嵌套的普通文件夹和资源文件,就像一个资源管理器。(资源应该暂时只支持图片、音视频、md文档。 然后 repo 应该有编辑器页面,即预览模式、编辑模式(只有md文档有),这两个模式就像obsidian 一样,左边资源列表,右边编辑器渲染md内容或者图片、视频、音频。资源管理页面,以卡片的形式展示所有资源,类似 obsidian 的 base 页面
- editor 模块就上上面说的,应该是和 repo 模块紧密相连,嵌入在编辑器页面
- 总之,应该是 obsidian 的模仿版、低配版,普通编辑页面+数据库页面
- 请你帮我确定好两个模块的 domain 层、application 层业务方向细节。还有需要引入的库,obsidian 有没有相关的库,我感觉 monaco-editor 并不好用
等等等,你记得现在的 Editor 的功能要求吗,你说的那些应该是之前的 editor 的实体设计,你觉得按照新的 editor 要求,应该是需要哪些实体、聚合根、值对象。
补充一下,实现的目标是像 obsidian 一样的编辑,此时侧边栏的文件管理和搜索都应该属于 repository 模块,editor 模块在前端应该只是作为一个组件,repo 模块选择文件后传入 editor 提供的组件,将 传入内容渲染、编辑、多标签管理之类的功能。
我突然想到一个问题, 聚合根不是应该统一管理旗下的 子实体吗,你这个 聚合根实体的属性里面怎么都没有子实体;DTO 数据中也要有子实体的 DTO,在转换方法里也要递归转换;在接口获取时也都是DDD式的restful,只暴露聚合根的查,从聚合根携带的子实体中获取子实体。
- 当然得继续更新 RepositoryClient.ts 和其他 Client 接口
- 生成 domain-client 和 domain-server 的 repository 模块,我觉得不需要 domain-core 了,多一层感觉增加了复杂性。你帮我直接在domain 层中实现 repository 模块的领域层代码,聚合根、实体、值对象的的继承、实现,领域服务的实现(仓储用依赖注入,使用仓储接口的定义,到时候由应用层注入),仓储接口定义
然后开始使用这些工具来实现 repository 的前端 web 项目,复刻 obsidian,左边(最上方搜索、文件夹(编辑预览视图、管理视图+文件列+最下方切换仓库、设置管理)右边预览编辑区域; 当切换到管理视图时,左边的文件列表内容变为仓库/文件夹 的层级树,不显示文件,在预览区域显示该层级的文件、文件夹(以卡片形式展示),支持批量操作,导入导出等管理操作。
-
先实现 基础设施层、应用层、渲染层
我详细讲讲渲染层
- 仓库管理Dialog,obsidian 中那个用于新建仓库,切换仓库、删除仓库的窗口
- 页面顶部组件(用于切换视图按钮、搜索按钮、
页面标签) - 列表顶部按钮组组件
- 列表组件,用于层级渲染文件树
- 列表下方切换仓库(显示仓库名称、设置按钮)组件
预览、编辑组件(预览编辑视图时)- 管理组件(管理视图时)
- repo主页面 页面标签和 预览编辑应该是 到时候 editor 模块的组件,先占位
常见疑问
DDD 中怎么添加新功能?以搜索为例
来源:questions
问题:现在有了基础的仓库和编辑器模块,要添加搜索功能。搜索属于仓储领域内部的业务,应该直接作为一个搜索服务吗?
解答思路:
在 DDD 中添加新功能的判断路径:
- 判断业务归属:搜索是针对仓库内的资源进行检索,属于 Repository 聚合的业务范围,因此应放在 repository 模块内部,而非新建独立模块。
- 选择实现形式:
- 如果搜索只是简单的属性过滤(如按名称、标签筛选),可以直接作为 Repository 聚合根上的查询方法。
- 如果搜索涉及全文检索、模糊匹配、排序评分等复杂逻辑,应抽象为领域服务(如
ResourceSearchService),因为它需要跨多个 Resource 实体进行查询,不适合放在单个实体内部。 - 搜索的基础设施实现(如对接 Elasticsearch、Meilisearch 等)则放在基础设施层,通过接口解耦。
- 聚合根统一入口:搜索的调用仍应通过 Repository 聚合根或其领域服务暴露,保持 DDD 的封装原则——外部不直接访问子实体。
一句话原则:新功能先判断属于哪个领域/聚合,再判断复杂度决定放实体方法还是领域服务,基础设施细节下沉到基础设施层。