Cosmic Story v2 架构——深度解析。

面向工程师、产品经理、记者与合作伙伴拓展人员。完整的流程管线、四个 MongoDB 集合、EDA 事件、V 模型的严谨、性能目标、安全性与无障碍——尽在一页之中。

  • Soulwise-story 是与现有 cosmic-story 模块并列的全新 NestJS 模块。各功能模块之间零直接引用。
  • 四个 MongoDB 集合:soulwise_persons、soulwise_chapters、soulwise_journal_entries、soulwise_resonances。正文采用 AES-256 加密,并按各自服务的查询建立索引。
  • 通过 BullMQ 队列进行异步生成,超时为 28 秒。事件仅在数据库提交后才由 EventEmitter2 发出——不会产生幽灵收件项。
  • V 模型规格:119 项需求,零缺口。后端覆盖率目标为服务层语句 85%;前端 Pinia store 达 90%。

再次审视整条流程,附带工程细节

每一步都有一个服务、一份契约和一个事件。

  1. 触发

    一个用户操作——"为姐姐生成今日篇章"——或是一个定时任务,比如周日9点的回顾,或每6小时一次的天气刷新。

  2. 队列

    任务进入名为 soulwise-chapter-generation 的 BullMQ 队列,硬性超时为28秒。运行过久的任务会被终止,并向用户报告为"请重试"。

  3. 组合

    ChapterGenerationService 会将四要素提示词——人物背景、占星、信号、节奏——汇集成单一输入。没有任何原始用户个人身份信息会原样进入提示词;一切都会先经过清洗。

  4. 生成

    通过 AI_GENERATION_ADAPTER 符号令牌调用 AI 服务商,服务商可随时替换。继续之前,会检查响应的长度、结构与安全性。

  5. 后处理

    此时会发生四件事:危机分类器检查是否含有危机性语言;相位标签提取器抽取一到三个星座标签;反断言过滤器剔除被禁止的措辞;正文以平台托管密钥进行 AES-256 加密。

  6. 持久化

    该产物会写入相应的 MongoDB 集合——章节、日志条目、共鸣——并带有 userId 与 personId 索引,以便快速查询。先做软删除;个人身份信息在 30 天后硬删除。

  7. 通知

    数据库提交后,会触发一个 EventEmitter2 事件——CHAPTER_COMPLETED、JOURNAL_CREATED。通知模块接收该事件,创建收件箱条目,并可选择发送推送(每天最多一次,遵守免打扰时段)。

  8. 呈现

    前端通过经过身份验证的 API 调用拉取该产物。Hub 会以新内容重新渲染。如果你处于离线状态,缓存会提供昨天的视图,新产物将在重新连接时出现。

从触发到呈现的七个步骤,每一步都以其实际作用命名。

四个集合

按各自要回答的查询建立索引。

soulwise_persons

相册条目。在 userId、status、deletedAt 上建立索引。先做软删除;PII 在 30 天后硬删除。

soulwise_chapters

AI 撰写的篇章,正文加密。在 personId、userId、generatedAt 上建立索引。相位标签单独存为数组,便于快速筛选。

soulwise_journal_entries

用户撰写的感悟,正文加密。在 userId、personId、createdAt 上建立索引。正文建立文本索引以供搜索。每条均带"私密——不要提供给 Luminara"标记。

soulwise_resonances

每段关系的四维评分。在 personId 上建立唯一索引。在写入篇章或日志后通过服务调用重新计算。

EDA 事件

严格规则:事件仅在数据库提交后触发。跨模块依赖通过 Symbol 注入令牌实现,绝不使用 forwardRef。功能模块之间禁止直接进行服务到服务的导入。

  • SoulwiseEvents.CHAPTER_COMPLETED — SoulwiseEvents.CHAPTER_COMPLETED——在章节加密并持久化后触发。Notifications-v2 监听该事件;创建收件箱条目;可选择发送推送。
  • SoulwiseEvents.JOURNAL_CREATED — SoulwiseEvents.JOURNAL_CREATED——在日志条目加密并持久化后触发。Resonance 服务监听该事件;触发重新计算。
  • SoulwiseEvents.PERSON_BIRTH_UPDATED — SoulwiseEvents.PERSON_BIRTH_UPDATED——在某人的出生数据发生变化后触发。合盘缓存随之失效。
  • SoulwiseEvents.PUSH_REQUESTED — SoulwiseEvents.PUSH_REQUESTED——遵循 notifications-v2 契约;尊重推送预算与免打扰时段。

V 模型规范严谨度

119 条可追溯的需求,零遗漏。每条需求都向前映射到一个测试用例(UTP、ITP、STP、E2E),向后映射到一个用户故事。20 个用户故事。15 条功能需求。12 类非功能需求。8 道全局验收关卡。

性能契约

章节生成在 95% 的请求中达到 30 秒或更快,以 BullMQ 任务时长分布为准衡量。API p99 GET 延迟在 1,000 并发用户下达到 500 毫秒或更快,通过 k6 负载测试衡量。前端 TTI 在模拟 4G 网络下达到 3 秒或更快,通过 Lighthouse CI 衡量。

安全契约

日志与章节正文采用 AES-256 静态加密,密钥由平台托管。传输中使用 TLS 1.2+;HTTP→HTTPS 重定向。JWT 访问令牌有效期 1 小时,刷新令牌有效期 30 天,刷新时轮换。软删除设有 30 天窗口期,之后才对 PII 进行硬删除。

无障碍契约

全局尊重 prefers-reduced-motion 设置——GSAP 动画将变为仅透明度的淡入淡出。每个可交互元素都带有 VoiceOver 与 TalkBack 标签。每次发布前都在 iOS 与 Android 上手动验证。

为什么单独建立 soulwise-story 模块,而不是扩展 cosmic-story?

因为上游规范会重建该功能,而在现有模块内重建,要么会破坏 v1 的体验,要么得先分叉再合并。新建模块能让 v1 保持不变,让 v2 得到验证,并在就绪时干净地迁移。

为什么选 MongoDB 而不是 Postgres?

现有的 My Zodiac AI 后端运行在 MongoDB 上;切换意味着要做一个与本功能无关的基础设施决策。文档模型也很契合章节与日志条目——嵌套、长度不一、以加密块形式存储。

为什么队列选用 BullMQ?

BullMQ 运行在 Redis 上,而 Redis 已用于会话与限流,存在于技术栈中。无需新增基础设施。内置的重试、超时与可观测性,无需自定义管道即可满足章节生成的需求。

上游规范究竟写在哪里?

内部仓库。本页上的数字与契约是对上游 V 模型成果的转述。My Zodiac AI 博客集群上的公开工程博文(标签为 'cosmic-story-v2')会更深入地探讨构建的具体部分。

立即体验 My Zodiac AI

当 Soulwise 掀起它的浪潮之时,我们的旗舰占星应用早已在你手中。

占星内容仅供自我省思与娱乐。此处所述的 Cosmic Story v2 功能仍在开发中,是否上线可能随时变更,恕不另行通知。