docs: 添加订阅与每日运势推送功能的设计文档

- ADR-002: 订阅与每日运势推送功能设计决策
- PRD: 订阅与每日推送功能需求规格说明
- 实现计划文档
This commit is contained in:
2026-08-13 08:06:01 +08:00
parent 7f0ef622e7
commit e6488cdab9
3 changed files with 773 additions and 0 deletions
+134
View File
@@ -0,0 +1,134 @@
# ADR-002: 订阅与每日运势推送功能设计
## 状态
✅ 已采纳
## 日期
2026-08-13
## 背景
用户希望在小程序端获得每日运势推送功能,无需手动打开应用即可在每日固定时间收到个性化运势推送。
## 需求
1. 用户可订阅每日运势推送服务
2. 每日固定时间(默认 07:00)推送当日运势
3. 推送内容基于用户生辰信息的紫微斗数命盘,由现有算法本地生成
4. 用户可自定义推送时间
5. 仅限微信小程序平台
## 约束
1. 纯客户端 → 需引入轻量后端用于推送(微信订阅消息要求服务端调用)
2. 微信订阅消息模板需在微信小程序后台申请,使用 `wx.subscribeMessage.send` 接口
3. 云函数运行环境为 Node.js,需兼容现有 TypeScript 算法
## 数据模型
### 云数据库:subscriptions 集合
```typescript
interface Subscription {
_id: string // 云数据库自动 ID
openid: string // 用户微信 openid(唯一索引)
templateId: string // 微信订阅消息模板 ID
birthInfo: { // 用户生辰信息(用于服务器端生成运势)
birthDate: string // 公历出生日期 YYYY-MM-DD
birthHour: number // 出生小时 (0-23)
birthMinute: number // 出生分钟 (0-59)
birthPlace: string // 出生地名称
longitude: number // 出生地经度
latitude: number // 出生地纬度
gender: 'MALE' | 'FEMALE'
}
pushTime: string // 推送时间,格式 "HH:mm",默认 "07:00"
pushEnabled: boolean // 是否开启推送
subscribedAt: Date // 订阅时间
lastPushDate: string // 最后推送日期 YYYY-MM-DD(防重复推送)
expireAt: Date // 订阅过期时间(微信订阅消息有效期)
}
```
### 小程序端本地存储(新增)
| Key | 类型 | 存储内容 | 生命周期 |
|-----|------|---------|---------|
| `eis_push_subscription` | `Subscription` | 订阅信息缓存 | 持久化,订阅/取消时更新 |
## 决策
### 决策1:推送方案 — 微信订阅消息 + 微信云开发
**方案**:微信订阅消息(`wx.subscribeMessage.send`+ 微信云开发(CloudBase
**选择理由**
- 微信订阅消息是微信小程序原生推送能力,用户可在"服务通知"中收到推送
- 微信云开发提供云函数 + 云数据库 + 定时触发器,与微信生态无缝集成
- 无需额外服务器,按量计费,小规模使用在免费额度内
- 云函数定时触发器(cron)支持每日定时执行
**替代方案排除**
- 自建后端服务器:运维成本高,超出当前项目规模
- 纯本地推送:H5 不支持后台推送,小程序端无法跨平台
- 第三方推送服务:增加外部依赖和费用
### 决策2:算法复用方案 — 共享算法包
**方案**:将现有运势算法(纯函数层)抽取为独立 npm 包,小程序和云函数共享
**选择理由**
- 现有运势算法(`fortuneStrategy.ts``ziweiAlgorithm.ts``fortune.ts`)是纯函数,无 UI 依赖
- 输入 `ZiweiChart + Date` 输出 `DailyFortune`,可在 Node.js 环境直接运行
- 结果一致性保障:小程序端和云函数推送使用同一份代码
- 后续算法更新只需维护一份代码
**依赖映射**
```
共享算法包 @everything-suitable/algorithm/
├── fortuneStrategy.ts # 运势生成策略(纯函数)
├── fortune.ts # 综合运势生成(纯函数)
├── ziweiAlgorithm.ts # 紫微算法基础(纯函数,含幸运色/数字/方位)
├── types.ts # 类型定义
├── enums.ts # 枚举定义
└── index.ts # 导出入口
```
### 决策3:数据流设计
**订阅流程**
```
小程序端 → 用户订阅 → 收集生辰信息 → 上传至云函数 → 存储至云数据库
```
**每日推送流程**
```
云函数定时触发器 (07:00) → 查询当日所有订阅 → 对每用户调用共享算法生成运势
→ 调用 wx.subscribeMessage.send → 用户收到服务通知
```
### 决策4:推送模板结构
| 模板字段 | 内容 | 数据来源 |
|---------|------|---------|
| `date1` | 今日日期 | `new Date().toLocaleDateString('zh-CN')` |
| `thing2` | 综合运势评分 + 等级 | `overallScore` + `overallLuck` |
| `thing3` | 各维度运势建议 | `careerAdvice` / `wealthAdvice` / `relationshipAdvice` / `healthAdvice` |
| `thing4` | 幸运色 + 幸运数字 | `luckyColor` + `luckyNumber` |
## 影响
1. **新增目录**`everything-is-suitable-uniapp/cloudfunctions/`(云函数目录)
2. **新增目录**`packages/algorithm/`(共享算法包)
3. **新增依赖**`@everything-suitable/algorithm`(共享算法包的本地引用)
4. **新增页面**:小程序端订阅管理页面(订阅/取消/配置推送时间)
5. **新增存储**:微信云开发环境配置(云数据库、云函数、定时触发器)
6. **不影响现有功能**:现有运势页面、紫微排盘、黄历查询不受影响
7. **不影响现有测试**:共享算法包抽取后,现有测试仍可正常运行
## 术语表
| 术语 | 定义 |
|------|------|
| 微信订阅消息 | 微信小程序提供的消息推送能力,用户订阅后可在"服务通知"中收到消息 |
| 微信云开发 | 微信生态内的 Serverless 云服务,提供云函数、云数据库、存储等 |
| 云函数 | 运行在微信云端的 Node.js 函数,通过定时触发器或事件触发 |
| 定时触发器 | 云函数的 cron 触发机制,支持按指定时间定期执行 |
| 共享算法包 | 从应用中抽取的纯算法模块,可在多环境(小程序/云函数)复用 |
| 生辰信息 | 用户的出生日期、时间、地点、性别等用于紫微斗数排盘的数据 |
| 服务通知 | 微信内用户接收订阅消息的入口,位于微信聊天列表"服务通知" |