Files
rsspipe/docs/001_initial_prd.md

104 lines
6.5 KiB
Markdown

# 架构设计与需求文档:RSSPipe
1. 核心需求概述
本系统旨在构建一个针对单用户场景的 高度可扩展、本地优先(Local-First)且端到端加密的 RSS 网关客户端(PWA)。它不仅具备传统 RSS 的订阅与阅读功能,更通过事件驱动的规则引擎,深度集成 AI 能力。
关键特性要求:
* 本地优先 (Local-First PWA):核心数据存储与业务流转在客户端(浏览器环境)完成,支持离线访问。
* 端到端加密 (E2EE):数据在落盘或同步前必须在客户端加密,保证绝对隐私。
* 事件驱动的规则引擎 (Rules Engine):支持类似 Gmail Filter 的 Trigger-Condition-Action 机制。
* 防死循环与状态隔离 (DAG & CQRS):严格拆分 Feed 生命周期,分离单实体(Single-Entity)富化逻辑与多实体(Multi-Entity)聚合逻辑,彻底杜绝规则循环执行。
* 无缝旁路扩展 (Plugin/RPC):通过定义统一的“增量 Patch”通信契约,支持用 TS 编写本地 Plugin,或通过 gRPC/Connect 调用外部 Go/Python 的 AI 节点。
* 无预设动态 Schema:Feed 的附加数据(如 AI 摘要、评分、TTS 音频等)不硬编码在数据模型中,而是通过 JSON 增量合并。
* 遥测与反馈循环 (Telemetry):采集阅读行为(驻留时长、可见字数比),为下游 AI 模型或动态权重系统提供微调依据。
1. 核心架构视图
2. 核心数据模型 (Data Schema)
系统采用 Core (不可变主键) + Metadata (可变 JSONB) 的模式。
// 核心路由与索引字段(关系型特征)
interface FeedCore {
id: string; // 唯一标识符,基于 url + timestamp 哈希
url: string; // 原始链接
sourceId: string; // 订阅源 ID
timestamp: number; // 抓取/发布时间戳
title: string;
content: string; // 清洗后的纯文本/Markdown
}
// 变长扩展数据(无预设 Schema)
interface FeedMetadata {
isRead: boolean;
tags: string[]; // 标签集合
aiSummary?: string; // AI 摘要
ttsUrl?: string; // 语音合成链接
score?: number; // 推荐分数
[key: string]: any; // 其他外部 Plugin 注入的动态字段
}
// 数据库实际存储结构(明文态)
interface LocalFeedEntry extends FeedCore {
metadata: FeedMetadata;
}
1. 生命周期与规则引擎设计 (DAG Rule Engine)
为了防止死循环,Feed 的处理被严格限制在一个单向流动的流水线中。
4.1 生命周期的四个阶段 (Phases)
* Ingestion (摄入期):从远程 XML 拉取数据,使用 rss-parser 解析,使用 @mozilla/readability 提取纯正文。
* Enrichment (丰富期):单 Feed 事件的主战场。在此阶段,系统调用配置好的 Plugin(本地或远程),获取摘要、打分等元数据。
* Aggregation (聚合期):批处理的主战场。由独立的调度器(基于 RxJS)监听数据库写入操作,当符合特定条件的 Feed 数量达到阈值,触发聚合 Action(如生成周报)。
* Action (动作期):数据的最终落盘加密存储,以及触发 UI 层的渲染与系统通知。
4.2 统一 Plugin 接口契约 (Plugin Interface Protocol)
无论是前端本地的 TypeScript 函数,还是远端的 Go 语言 gRPC 服务,都必须遵循以下契约进行通信,强制使用 JSON Patch,禁止外部服务直接覆写完整 Feed 数据。
// 输入契约 (发送给 Plugin 的数据)
interface PluginInput {
eventId: string;
phase: "enrichment" | "aggregation";
feedSnapshot: Readonly<FeedCore>;
feedMetadata: Readonly<FeedMetadata>;
triggerReason: string;
}
// 输出契约 (Plugin 返回给主系统的指令)
interface PluginOutput {
action: "merge_metadata" | "drop_feed" | "none";
metadataPatch?: {
$set?: Record<string, any>; // 覆写字段,如 { aiSummary: "..." }
$push?: Record<string, any[]>; // 追加数组元素,如 { tags: ["tech"] }
};
}
4.3 规则防死锁机制
在添加或修改 Rule 时,运行拓扑排序(Topological Sort)引擎,验证 Trigger 和 Action 之间是否存在循环依赖,存在则拒绝保存配置。
5. 里程碑拆解与模块化实现方案
Milestone 1: 本地基础设施 (Local-First Base)
* 任务目标:搭建基础 PWA 框架,实现端到端加密与基础数据读写。
* 关键技术栈:Vite + React, Dexie.js (IndexedDB), Web Crypto API。
* 核心模块:
* DB 层:基于 Dexie.js 定义本地表结构,只允许应用层通过统一的 Service 读写。
* 加密拦截器:数据写入 IndexedDB 前进行 AES-GCM 加密,读取时解密,确保本地离线数据的安全性。
* 基础 Parser:实现对 RSS 源的拉取和 @mozilla/readability 的正文清洗。
Milestone 2: 单 Feed 规则引擎与本地 Plugin (Core Engine)
* 任务目标:实现生命周期流水线与 Enrichment 阶段的核心逻辑。
* 关键技术栈:RxJS。
* 核心模块:
* 生命周期 Event Bus:基于 RxJS Subject 创建事件总线,控制数据流从 Ingestion 向下流转。
* Plugin 调度中心:根据用户配置的 Rules,将数据 Snapshot 传递给对应的本地 TS 函数,获取 Patch 并执行安全合并(Lodash merge 等效逻辑)。
* DAG 校验器:实现并集成拓扑排序算法,验证用户配置。
Milestone 3: 旁路扩展层 (Remote RPC & Extensibility)
* 任务目标:实现外部 Go/Python AI 控制器的接入。
* 关键技术栈:Connect-RPC (@connectrpc/connect-web), Protobuf。
* 核心模块:
* 契约生成:使用 Protobuf 将 PluginInput 和 PluginOutput 标准化,生成两端的接口代码。
* RPC 适配器:在前端 Rules Engine 中编写一个特殊的 Plugin Adapter,遇到远程规则时,通过 Connect 将数据发往 Go 后端服务,并等待返回 JSON Patch。
* 动态 UI 渲染器:重构阅读页面,使其不再依赖硬编码字段,而是根据 Metadata 动态挂载组件(如检测到 ttsUrl 挂载播放器)。
Milestone 4: 遥测与批量聚合处理 (Telemetry & Aggregation)
* 任务目标:实现多状态 Filter 与用户阅读数据的反馈回路。
* 关键技术栈:RxJS (bufferCount, bufferTime), Intersection Observer API。
* 核心模块:
* 批处理调度器:针对 Aggregation 阶段,使用 RxJS 的缓冲操作符,在达到数量或时间阈值时触发特定的 RPC 聚合调用。
* 阅读统计探针:基于页面的滚动事件与 Intersection Observer,计算用户的实际停留时间与可见内容量,生成打分日志。
* 反馈推流机制:周期性地将本地存储的遥测日志通过网络发送给后端模型训练/微调服务。