Files
everything-is-suitable/docs/superpowers/specs/2026-08-13-daily-fortune-push-PRD.md
T
zhangxiang e6488cdab9 docs: 添加订阅与每日运势推送功能的设计文档
- ADR-002: 订阅与每日运势推送功能设计决策
- PRD: 订阅与每日推送功能需求规格说明
- 实现计划文档
2026-08-13 08:06:01 +08:00

241 lines
12 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# PRD: 订阅与每日运势推送功能
## 1. 概述
### 1.1 产品名称
万事宜 — 订阅与每日运势推送
### 1.2 目标用户
已输入生辰信息并使用紫微斗数运势功能的微信小程序用户
### 1.3 核心价值
用户无需手动打开小程序,每日自动收到个性化运势推送,提升日活与用户粘性
### 1.4 约束条件
- 仅限微信小程序平台
- 依赖微信云开发(CloudBase)作为轻量后端
- 推送内容由现有算法本地/云端生成,无需外部数据源
## 2. 功能范围
### 2.1 范围内(MVP
| 功能 | 说明 |
|------|------|
| F1: 订阅入口 | 在运势页面提供订阅入口,引导用户订阅每日推送 |
| F2: 微信订阅消息授权 | 调用 `wx.requestSubscribeMessage` 获取用户授权 |
| F3: 生辰信息上传 | 将用户生辰信息上传至云数据库,用于云端生成运势 |
| F4: 每日定时推送 | 云函数定时触发器每日 07:00 执行推送 |
| F5: 推送内容生成 | 云函数调用共享算法包生成当日运势 |
| F6: 推送时间配置 | 用户可自定义推送时间(默认 07:00) |
| F7: 取消订阅 | 用户可随时取消推送,清理云数据库订阅记录 |
| F8: 共享算法包抽取 | 将运势算法纯函数层抽取为独立 npm 包 |
### 2.2 范围外(后续迭代)
| 功能 | 说明 |
|------|------|
| 黄历每日推送 | 未来可扩展为推送当日宜忌 |
| 多模板推送 | 支持不同模板(运势、黄历、提醒等) |
| 多平台推送 | H5 浏览器推送、App 原生推送 |
| 推送统计 | 推送到达率、点击率分析 |
## 3. 用户故事
### US-01: 订阅推送
> 作为已设置生辰信息的用户,我希望在运势页面看到订阅入口,一键订阅每日运势推送,从而每天自动收到我的运势信息。
**验收标准**
- [ ] 用户进入运势页面时,显示订阅入口(仅未订阅时)
- [ ] 点击订阅后,弹出微信订阅消息授权弹窗
- [ ] 用户授权后,生辰信息上传至云数据库
- [ ] 订阅成功后显示"已订阅"状态和每日推送时间
- [ ] 未输入生辰信息的用户提示先设置生辰信息
### US-02: 每日推送接收
> 作为已订阅用户,我希望每天在固定时间收到服务通知,查看当日的综合运势、各维度运势和幸运信息。
**验收标准**
- [ ] 每日在用户配置的时间(默认 07:00)收到服务通知
- [ ] 推送内容包含:日期、综合运势评分+等级、各维度运势、幸运色+数字
- [ ] 推送内容与小程序内当日运势一致
- [ ] 同一用户每日不会收到重复推送
### US-03: 推送时间配置
> 作为已订阅用户,我希望在订阅管理页面修改推送时间,从而适配我的作息习惯。
**验收标准**
- [ ] 订阅管理页面显示当前推送时间
- [ ] 用户可修改推送时间(步长 30 分钟)
- [ ] 修改后云端同步更新
- [ ] 修改后下一次推送按新时间执行
### US-04: 取消订阅
> 作为已订阅用户,我希望在订阅管理页面一键取消订阅,从而不再收到每日推送。
**验收标准**
- [ ] 订阅管理页面提供"取消订阅"按钮
- [ ] 取消后删除云端订阅记录
- [ ] 取消后不再收到推送
- [ ] 取消后订阅入口重新显示
## 4. 架构与数据流
### 4.1 系统架构
```
┌──────────────────────────────────────────────────────┐
│ 微信小程序 │
│ ┌──────────────┐ ┌──────────────┐ ┌───────────┐ │
│ │ 运势页面 │ │ 订阅管理页面 │ │ 共享算法包 │ │
│ │ (订阅入口) │ │ (时间/取消) │ │ (本地使用) │ │
│ └──────┬───────┘ └──────┬───────┘ └───────────┘ │
│ │ │ │
│ └────────┬────────┘ │
│ │ │
│ wx.cloud.callFunction │
└──────────────────┼─────────────────────────────────────┘
┌──────────────────────────────────────────────────────┐
│ 微信云开发 (CloudBase) │
│ ┌────────────────────┐ ┌────────────────────────┐ │
│ │ 云函数: subscribe │ │ 云函数: dailyPush │ │
│ │ - 存储订阅关系 │ │ - 定时触发器 07:00 │ │
│ │ - 存储生辰信息 │ │ - 调用共享算法包 │ │
│ │ - 更新推送时间 │ │ - 生成运势内容 │ │
│ │ - 取消订阅 │ │ - 调用 subscribe.send │ │
│ └────────────────────┘ └────────────────────────┘ │
│ ┌────────────────────────┐ │
│ │ 云函数: unsubscribe │ │
│ │ - 删除订阅记录 │ │
│ └────────────────────────┘ │
│ ┌────────────────────────────────────────────────┐ │
│ │ 云数据库: subscriptions 集合 │ │
│ │ { openid, templateId, birthInfo, pushTime, │ │
│ │ pushEnabled, subscribedAt, lastPushDate } │ │
│ └────────────────────────────────────────────────┘ │
│ ┌────────────────────────────────────────────────┐ │
│ │ 共享算法包 @everything-suitable/algorithm │ │
│ │ (云函数依赖,纯 TypeScript 计算) │ │
│ └────────────────────────────────────────────────┘ │
└──────────────────────────────────────────────────────┘
```
### 4.2 数据流
**订阅流程**
```
1. 用户点击"订阅每日推送"
2. 小程序检查用户是否已输入生辰信息
3. 调用 wx.requestSubscribeMessage 请求授权
4. 用户授权 → 小程序调用云函数 subscribe
5. 云函数将 { openid, birthInfo, templateId, pushTime } 写入云数据库
6. 返回成功 → 小程序 UI 更新为"已订阅"
```
**每日推送流程**
```
1. 云函数定时触发器 (dailyPush) 在每日 07:00 触发
2. 查询云数据库 subscriptions 中 pushEnabled=true 且 lastPushDate != today 的记录
3. 对每条记录:
a. 使用 birthInfo 计算 ZiweiChart(本地算法)
b. 使用 chart + today 调用 generateDailyFortune
c. 格式化推送内容(模板字段绑定)
d. 调用 wx.subscribeMessage.send 发送
e. 更新 lastPushDate = today
```
## 5. 共享算法包定义
### 5.1 包结构
```
packages/algorithm/
├── package.json
├── tsconfig.json
├── src/
│ ├── index.ts # 导出入口
│ ├── fortuneStrategy.ts # 运势生成策略
│ ├── fortune.ts # 综合运势生成
│ ├── ziweiAlgorithm.ts # 紫微算法基础
│ ├── types.ts # 类型定义
│ ├── enums.ts # 枚举定义
│ └── __tests__/ # 算法测试
│ └── fortuneStrategy.test.ts
└── README.md
```
### 5.2 导出接口
```typescript
// 核心导出
export { generateDailyFortune } from './fortuneStrategy'
export { generateComprehensiveFortune } from './fortune'
export { calculateLuckyColor, calculateLuckyNumber, calculateLuckyDirection } from './ziweiAlgorithm'
export { determineLuckLevel, calculatePalaceScore } from './ziweiAlgorithm'
export type { DailyFortune, ZiweiChart, PalaceFortune } from './types'
```
## 6. 微信订阅消息模板
### 6.1 模板申请
在微信小程序管理后台 → 功能 → 订阅消息 → 公共模板库,搜索并选用合适的模板。
### 6.2 推荐模板字段映射
| 模板参数 | 值 | 说明 |
|---------|-----|------|
| `date1` | `{{data.date1}}` | 日期,格式:2026年8月14日 |
| `thing2` | `{{data.thing2}}` | 综合运势,格式:综合评分85分,等级:吉 |
| `thing3` | `{{data.thing3}}` | 各维度运势摘要 |
| `thing4` | `{{data.thing4}}` | 幸运信息,格式:幸运色红色 幸运数字7 |
### 6.3 推送内容示例
```
📅 2026年8月14日
🌟 综合运势:85分(吉)
📊 事业:今日事业运势吉显,适合处理重要工作事务
财运:财运亨通,可进行投资理财
感情:感情运势良好,适合表达爱意
健康:身体状况良好,精力充沛
🍀 幸运色:红色 幸运数字:7
```
## 7. 阶段与里程碑
| 阶段 | 内容 | 预估工时 | 依赖 |
|------|------|---------|------|
| **M1: 共享算法包** | 抽取算法为独立包,确保云函数可调用 | 2d | 无 |
| **M2: 云开发环境** | 开通微信云开发,创建数据库、云函数、定时触发器 | 1d | M1 |
| **M3: 订阅功能** | 小程序端订阅入口 + 订阅管理页面 + 云函数 | 2d | M2 |
| **M4: 每日推送** | 云函数 dailyPush 实现 + 定时触发器配置 | 1.5d | M2+M3 |
| **M5: 测试与验收** | 集成测试 + 推送验证 + 异常处理 | 1.5d | M4 |
## 8. 验收标准
### 8.1 功能验收
| # | 验收项 | 预期结果 |
|---|--------|---------|
| 1 | 未输入生辰信息时订阅 | 提示用户先设置生辰信息 |
| 2 | 首次订阅流程 | 微信授权弹窗 → 生辰信息上传 → 订阅成功 |
| 3 | 每日推送触发 | 用户在配置时间收到服务通知 |
| 4 | 推送内容正确性 | 推送内容与小程序内当日运势一致 |
| 5 | 推送时间修改 | 修改后下次推送按新时间执行 |
| 6 | 取消订阅 | 删除云端记录,不再收到推送 |
| 7 | 重复推送防护 | 同一用户每日仅收到一次推送 |
| 8 | 订阅消息过期 | 用户重新订阅后恢复正常推送 |
### 8.2 非功能验收
| # | 验收项 | 预期结果 |
|---|--------|---------|
| 1 | 云函数执行时间 | < 3s/用户(含算法计算) |
| 2 | 订阅消息到达率 | 微信官方保障,不做额外要求 |
| 3 | 用户数据安全 | 生辰信息仅用于推送计算,不另作他用 |
## 9. 术语表
| 术语 | 定义 |
|------|------|
| 微信订阅消息 | 微信小程序提供的消息推送能力,用户订阅后可在"服务通知"中收到消息 |
| 微信云开发 | 微信生态内的 Serverless 云服务,提供云函数、云数据库、存储等 |
| 云函数 | 运行在微信云端的 Node.js 函数 |
| 定时触发器 | 云函数的 cron 触发机制 |
| 共享算法包 | 从应用中抽取的纯算法模块 |
| 服务通知 | 微信内用户接收订阅消息的入口 |