系统架构
概述
MysticX 是一个基于 Next.js 16 的 Web 应用程序,采用多进程架构。AI 驱动的塔罗牌解读由后台 Worker 异步处理,避免在长时间运行的生成式 AI 调用期间阻塞 Web 服务器。
系统架构图
┌──────────────────────────────────────────────────────────────────────────────────┐
│ 浏览器客户端 │
│ · POST /api/v1/readings (创建解读) │
│ · GET /api/v1/chats/[id]/messages/[id]/stream (SSE — token 流) │
└────────────────────────────┬─────────────────────────────────────────────────────┘
│ HTTP / SSE
▼
┌────────────────────────────────────────┐ ┌──────────────────────┐
│ Next.js 应用 (App Router) │◄─────►│ PostgreSQL 18 │
│ · API 路由 · 认证 (Better Auth) │ │ (主数据库) │
│ · 管理后台 · 页面渲染 │ └──────────────────────┘
└─────────────────────┬──────────────────┘
│ BullMQ 任务 / Redis Pub/Sub
▼
┌────────────────────────┐
│ Redis │
│ · BullMQ 任务队列 │
│ · Pub/Sub 流式传输 │
│ · 每日使用限制 │
└──┬──────┬──────┬───┬───┘
│ │ │ │
┌──────┘ ┌───┘ ┌───┘ └──────────────────────┐
▼ ▼ ▼ ▼
┌─────────┐ ┌───────┐ ┌────────────────┐ ┌─────────────────────┐
│ 塔罗 │ │ 洞察 │ │ 问题洞察 │ │ 翻译 Worker │
│ Worker │ │Worker │ │ Worker │ │ (博客文章 + │
│ │ │ │ │ │ │ 博客实体) │
│ 队列: │ │ 队列: │ │ 队列: │ │ 队列: │
│ tarot- │ │guidance│ │ question- │ │ blog-translation │
│ reading-│ │-genera-│ │ insights- │ │ blog-entity- │
│ genera- │ │tion │ │ analysis │ │ translation │
│ tion │ │ │ │ │ └──────────┬──────────┘
└────┬────┘ └───┬───┘ └───────┬───────┘ │
│ │ │ │
└──────────┴──────────────┴──────────────────────┘
│
▼
┌────────────────────────────────────────────┐
│ Google Vertex AI — gemini-3-flash-preview │
│ (IAM 服务账号认证,标准模式) │
│ · 塔罗解读 (streamText) │
│ · 后续对话 + 抽牌(+ 谷歌搜索 Grounding) │
│ · 每周指引 / 灵魂旅程 │
│ · 博客翻译 │
└────────────────────────────────────────────┘
┌──────────────────────────────┐
│ Telegram 机器人 (grammY) │ ← 独立 PM2 进程,长轮询模式
│ 调用内部 Next.js API │ POST /api/v1/internal/readings/create
└──────────────────────────────┘进程
MysticX 在生产环境中运行六个进程,由 PM2 管理:
1. Next.js Web 服务器 (mysticx-web)
- 模式:PM2 集群模式(扩展至所有 CPU 核心)
- 职责:提供 App Router 页面、处理 API 路由、管理认证、服务管理后台
- 端口:3031(生产环境默认,可通过
PORT环境变量配置) - 内存限制:每个实例 1 GB
2. 塔罗 Worker (mysticx-worker)
- 模式:PM2 fork(单实例)
- 脚本:
scripts/tarot-worker/index.ts - 队列:
tarot-reading-generation - 任务类型:
generate-reading、generate-followup、generate-draw-card - 职责:从 BullMQ 消费解读任务,通过
@ai-sdk/google-vertex调用gemini-3-flash-preview,将流式 token 发布到 Redis Pub/Sub。后续对话和动态抽牌还会调用谷歌搜索 Grounding(google_search工具)获取实时数据 - 内存限制:512 MB
3. 洞察 Worker (mysticx-insights-worker)
- 模式:PM2 fork(单实例)
- 脚本:
scripts/insights-worker/index.ts - 队列:
guidance-generation - 任务类型(通过
job.data.type分发):weekly、soul-journey - 职责:使用
gemini-3-flash-preview异步生成每周指引和灵魂旅程内容 - 内存限制:512 MB
- 并发数:1(锁定时长 120 秒)
4. Telegram 机器人 (mysticx-telegram-bot)
- 模式:PM2 fork(单实例)
- 脚本:
scripts/telegram-bot/index.ts - 职责:使用 grammY 的长轮询 Telegram 机器人。向 Next.js 服务器发起内部 API 调用来创建解读
- 内存限制:256 MB
5. 问题洞察 Worker (mysticx-question-insights-worker)
- 模式:PM2 fork(单实例)
- 脚本:
scripts/question-insights-worker/index.ts - 队列:
question-insights-analysis - 职责:应管理员请求,通过
gemini-3-flash-preview分析用户提问规律,生成类别分布、热词、词云和趋势数据,存储为InsightSnapshot - 内存限制:512 MB
6. 翻译 Worker (mysticx-translation-worker)
- 模式:PM2 fork(单实例)
- 脚本:
scripts/translation-worker/index.ts - 队列:
blog-translation(文章字段)和blog-entity-translation(分类、标签、作者) - 职责:通过
gemini-3-flash-preview将博客文章字段(标题、摘要、正文、SEO 元数据)和博客实体自动翻译为全部 12 种语言。每次处理一个字段+语言组合,支持指数退避重试、Redis 进度跟踪和实时取消 - 内存限制:512 MB
数据流:塔罗解读
1. 用户提交问题 + 选择牌阵
│
2. POST /api/v1/readings
│ → 验证积分 + 每日使用限制
│ → 创建 TarotReading + Chat + Message 记录
│ → 将任务加入 tarot-reading-generation 队列
│ → 返回 { readingId, chatId, messageId } 给客户端
│
3. 客户端打开 SSE 连接:
GET /api/v1/chats/[chatId]/messages/[messageId]/stream
│ → 订阅 Redis Pub/Sub 频道
│ → 若消息已 COMPLETED → 立即返回完整内容
│
4. 塔罗 Worker 获取 generate-reading 任务
│ → 构建含 Reader 人设 + AI 记忆的系统提示词
│ → 通过 streamText 调用 gemini-3-flash-preview(结构化输出)
│ → 将流式 token 发布到 Redis Pub/Sub 频道
│
5. 客户端接收 SSE token 并逐步渲染
│
6. Worker 完成处理
│ → 更新 Message 状态 → COMPLETED,保存完整内容
│ → 更新 TarotReading,写入 selectedCards + 结构化输出
│ → 记录 AiApiCall 指标(token 数、耗时、TTFT)
│ → 触发 extractMemory() 异步执行(更新 UserMemory,不阻塞)数据流:洞察生成
1. 用户点击"生成"每周指引或灵魂旅程
│
2. POST /api/v1/guidance/weekly(或 soul-journey)
│ → 创建记录,状态:GENERATING
│ → 将 BullMQ 任务加入 guidance-generation 队列
│ → 返回 202 Accepted
│
3. 洞察 Worker 处理任务
│ → 获取用户近期解读
│ → 调用 Gemini 生成内容
│ → 更新记录:状态 → READY,填充内容
│ → 创建通知记录
│
4. 失败时:
│ → 更新状态为 FAILED
│ → 退还用户积分外部服务
| 服务 | 用途 |
|---|---|
Google Vertex AI (gemini-3-flash-preview) | AI 模型,用于所有 AI 功能——解读、后续对话(+ 搜索 Grounding)、指引、翻译、问题洞察 |
| PostgreSQL 18 | 主数据存储 |
| Redis 7+ | BullMQ 任务队列、Pub/Sub token 流传输、每日使用限制 |
| Stripe | 订阅计费、一次性积分包购买、Webhook |
| Cloudflare R2 | 资源存储(牌面皮肤、读者头像/封面、反馈截图) |
| Resend | 事务性邮件(邮箱验证、密码重置) |
| Mixpanel | 产品分析和事件追踪 |
| Google Analytics 4 | 电商和购买事件上报(通过 gtag.js) |
| Tapfiliate | 联盟营销佣金追踪 |
| Telegram Bot API | 通过 grammY 长轮询 Telegram 集成 |
认证
认证由 Better Auth 处理,支持以下方式:
- 邮箱/密码 — 通过 Resend 发送邮箱验证
- Google OAuth — 标准 OAuth 2.0 流程
会话管理使用 HTTP-only Cookie。认证中间件位于 proxy.ts(Next.js middleware),通过检查会话有效性来保护路由,未认证用户会被重定向到 /auth/sign-in?redirectTo=...。
关于 Vertex AI 认证:所有 Worker 均通过服务账号(
GOOGLE_APPLICATION_CREDENTIALS)向 Google Cloud 认证。必须使用标准 Vertex AI 集成(非 Express 模式)——Express 模式不支持谷歌搜索 Grounding(vertex.tools.googleSearch)和精细化thinkingConfig配置。
缓存和实时通信
- Redis Pub/Sub — Worker 按消息发布流式 token;SSE 端点
GET /api/v1/chats/[chatId]/messages/[messageId]/stream订阅并将 token 推送至浏览器 - Redis TTL 键 — 访客用户的每日使用限制(在本地午夜重置);每字段翻译进度和取消标志
- BullMQ — 持久化任务队列,支持五个后台 Worker 的重试逻辑
- Zustand stores — 客户端状态管理,用于积分、通知、牌面选择和 UI 弹窗