You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

9.1 KiB

Person Panel:多用户个人数据中心与 RSS 收件箱 — 设计说明

日期:2026-04-18
状态:已评审(待实现计划)
范围:在现有 Nuxt 4 + Nitro + SQLite + Drizzle + @nuxt/ui 仓库上扩展,不引入分布式队列/Redis(单实例)。


1. 背景与目标

1.1 目标

构建 多用户个人数据中心:每位用户独立管理 个人资料/生平叙事Markdown 文章时光机(时间线)RSS 阅读收件箱;支持 条目级可见性(公开 / 私密 / 仅链接);实例级 管理员 负责账号生命周期(邀请制:管理员创建账号)。定时任务在 单实例进程内 周期性拉取 RSS。

1.2 非目标(第一期不做)

  • 空间协作:多账号共编同一主页(owner/editor 等)不做。
  • RSS 订阅源列表对外公开:订阅源仅本人可见。
  • 通用第三方 API 插件平台:先做 RSS/Atom(及可解析的变体);扩展点可在代码层预留接口,不产品化。
  • 分布式任务队列 / 多实例 SQLite 水平扩展:不纳入本期;若未来需要,再评估「外部 HTTPS 触发同步」或独立 worker。

1.3 已确认需求摘要

维度 选择
用户模型 多用户,数据按 userId 隔离
注册 邀请制:管理员创建账号
可见性策略 混合:部分可对公网展示
可见性粒度 条目级(每篇文章、每条时间线事件、每条 RSS 条目可单独设置)
RSS 源列表 永远仅本人可见
RSS 新条目默认 私密
角色 实例级admin(开号/禁用)与 user
内容主线 自写 Markdown 为主;RSS 为阅读收件箱,可与时间线等合并展示(UI 层)
定时任务 进程内调度(A)
部署 单实例

1.4 架构方案(选定)

单仓 Nuxt/Nitro 单体 + 领域分包 + SQLite:在现有仓库内划分 auth/adminprofilepoststimelinerssjobs;定时器在 Nitro ready 钩子注册;抓取逻辑异步分批、每源超时,避免阻塞事件循环。


2. 功能模块

  1. Auth:延续 Cookie 会话;users 表扩展 rolestatuspublicSlug 等。
  2. Admin:创建用户、禁用/启用;首个管理员通过 bootstrap 环境变量 创建(见 §5.2)。
  3. Profile:简介、头像、生平(Markdown)、社交链接等;展示受条目/字段可见性约束(与 §3 一致)。
  4. Posts:Markdown 文章;slug 在单用户内唯一;元数据含标题、摘要、封面、标签、发布时间。
  5. Timeline:时间线事件表;可与 Posts / RSS 在 UI 上合并展示;第一期以 独立事件表 + 可选手动关联 为主,自动聚合为二期。
  6. RSS:订阅源、抓取状态、条目存储、去重;每用户独立。
  7. Jobs:进程内调度,周期性同步到期订阅源;启动后短延迟补跑一次。

3. 数据模型与可见性

3.1 多租户隔离

所有业务表含 userIdme/* API 必须从会话解析 userId禁止由客户端指定任意 userId 访问他人数据。admin/* 在显式校验 role=admin 后操作账号维度字段。

3.2 表(概念)

要点
账号 users(扩展) role: admin | userstatus: active | disabledpublicSlug 唯一(公开主页)
文章 posts Markdown 正文、元数据、visibilityuserIdslug 用户内唯一
时光机 timeline_events 日期/时间段、标题、正文、visibilityuserId
RSS rss_feeds feedUrluserId、拉取状态(lastFetchedAtlastError 等)、可选 pollIntervalMinutes
RSS rss_items feedIduserId(冗余便于查询)、guidcanonicalUrl、标题、摘要、正文片段、publishedAt;默认 visibility=private

去重:优先 guid,否则规范化后的 canonicalUrl

3.3 可见性枚举(统一)

  • private:仅所有者可读(第一期建议:管理员默认不读取用户私密正文,仅管理账号;若需审计再单列策略)。
  • unlisted:凭 不可猜测链接 访问;不出现在公开聚合列表;不进站点公共 feed(若未来有)。
  • public:出现在该用户 公开主页 的聚合列表中。

仅链接 URL(U1,已定稿):采用 用户可读 publicSlug + 短随机 shareToken 的路径形态(例如 /p/:publicSlug/t/:shareToken),避免仅依赖可枚举 id。

3.4 公开主页 URL(实现定稿)

采用 /@:publicSlug 作为公开主页路径(若实现时发现与路由冲突,可退化为 /u/:publicSlug,但仓库内应 只保留一种 canonical 形式)。

3.5 禁用用户后的公开行为(实现定稿)

用户 status=disabled 时,其 公开主页返回 404;已登录会话在后续请求中拒绝。不在第一期做「禁用后仍展示历史公开快照」。


4. API 与路由分层

  • server/api/public/*:未登录可访问;仅聚合 visibility=public 的内容。unlisted 通过专用详情路由(§3.3)。
  • server/api/me/*:登录用户读写自有数据。
  • server/api/admin/*:仅 admin;用户 CRUD、可选实例级健康统计(注意隐私与脱敏)。

中间件:公开白名单 + 会话保护;admin 额外校验 role


5. 管理员与账号流程

5.1 创建与禁用

  • 管理员创建用户:username、初始密码、可选 emailrole=userstatus=active
  • 禁用:status=disabled,使会话失效策略与中间件一致(见 §3.5)。

5.2 首个管理员(Bootstrap)

通过一次性环境变量创建,例如:

  • BOOTSTRAP_ADMIN_USERNAME
  • BOOTSTRAP_ADMIN_PASSWORD

迁移/启动脚本 中若检测到不存在任何 admin 用户则创建;成功后运维侧应 移除或清空 上述变量。具体执行点(seed vs 启动插件)在实现计划中敲定,但必须保证 不可重复无意提权

5.3 自助注册

关闭或隐藏面向公众的注册;与现有 register 路由的兼容策略在实现计划中明确(例如仅 dev 开放或完全移除)。


6. Nuxt UI 信息架构

  • 登录:Nuxt UI 表单组件;无自助注册入口(或仅管理员可见)。
  • 站内(登录后):侧栏 — 概览、文章、时光机、RSS、资料、设置;admin 额外「用户管理」。
  • RSS:左侧订阅源(本人)、右侧条目流;支持 手动触发同步;条目上切换可见性。
  • 公开站:独立简洁布局,以阅读为主。

7. 定时任务(进程内)

  • Nitro ready 注册间隔任务(如每 N 分钟扫描到期 rss_feeds)。
  • 启动补跑:短延迟触发一轮到期同步。
  • 并发:小并发池 + 每源超时;失败写入 lastError;可选对连续失败源做退避。
  • 手动同步me/rss/sync 类接口,仍受 SSRF 与超时约束。

8. 安全基线

  • RSS SSRF:仅允许 http/https;限制重定向;解析 IP 时阻断私网段(实现细节遵循所选 HTTP 客户端能力);响应体大小上限。
  • 管理员接口:内存级速率限制或反向代理层限制(实现计划二选一)。
  • Cookie:延续 HttpOnlySameSite 等与现有 cookie 服务一致的做法。

9. 错误处理与观测

  • API 错误:统一 JSON 错误体(沿用现有 handler/响应工具);区分 401/403/404/422/429/500
  • RSS 抓取错误:写入 rss_feeds.lastError(及时间);用户可在 UI 查看 自己的 源状态;不向访客泄露内部堆栈。
  • 日志:抓取失败、SSRF 拒绝、管理员操作可记审计日志(级别与脱敏在实现计划中定)。

10. 测试策略

  • 单元测试:RSS URL 校验、去重键生成、可见性判定纯函数。
  • 集成测试mepublic 路由在 多用户数据并存 下无串租;admin 仅管理员可访问。
  • 手动清单:禁用用户 404、unlisted 链接不可枚举进列表、新 RSS 条目默认私密。

11. 配置项(建议)

变量 含义
RSS_SYNC_INTERVAL_MINUTES 全局默认轮询间隔(可被单源覆盖)
RSS_FETCH_TIMEOUT_MS 单源超时
RSS_MAX_CONCURRENT_FEEDS 同步并发上限
RSS_MAX_RESPONSE_BYTES 响应体上限
BOOTSTRAP_ADMIN_* 仅首次创建管理员(§5.2)

12. 自检记录(spec review)

  • 占位符:无 TBD;bootstrap 执行点标为「实现计划敲定」属合理边界。
  • 一致性:多用户隔离、条目级可见性、RSS 默认私密、单实例进程内任务彼此一致。
  • 范围:第一期不引入队列/多实例;协作与 OPML 等未承诺。
  • 歧义:公开路径已定 /@:publicSlug;禁用用户公开 404;unlisted 为 U1。

13. 后续步骤

实现前在单独会话使用 writing-plans 技能生成实现计划;本设计文档经作者与维护者确认后再进入开发。