Files
2026-02-03 17:43:58 +08:00

9.0 KiB
Raw Permalink Blame History

App Push每日提醒推送客户端 + 后端Spec

阶段高层规范spec

目标:实现“每日提醒”推送闭环:用户在首次进入 Onboarding 可选择每天推送次数05可跳过并可在个人主页的“每日提醒”弹窗随时调整次数或关闭客户端使用首次生成的 UUID 作为用户标识与后端关联;后端按用户配置定时下发推送。


1. 背景与动机(摘要)

当前客户端已有 Push 引导页(可跳过)与“每日提醒”设置入口,但尚未形成完整闭环:

  • 需要一个稳定的匿名用户标识UUID将“提醒配置”与“推送 token”绑定到后端
  • 需要后端能够按用户选择的每日次数05进行定时推送
  • 本期不追求高级推送能力(富媒体、复杂分群、到达率分析等)

2. 目标Goals

  • G1Onboarding 选择:用户首次进入 Onboarding 可设置“每日提醒次数”05可跳过且不阻塞进入主功能。
  • G2设置页可改可关用户可在个人主页的“每日提醒”弹窗调整次数05或关闭推送。
  • G3UUID 关联:客户端首次进入生成 client_user_idUUID用于与后端关联用户配置与推送 tokenspec_kit/Client User Identity/spec.md)。
  • G4推送闭环:客户端拿到推送权限与 Push Token 后上报后端;后端存储并按计划每日推送。
  • G5幂等与可恢复重复上报、token 轮换、用户反复开关不应导致重复推送或“僵尸任务”。
  • G6多语言:推送文案至少支持当前客户端语言体系(zh-CN/en/es/pt/zh-TW),或以安全默认语言回退。

3. 非目标Non-goals

  • 不接入高级推送能力(富媒体、通知分类/动作按钮、复杂分群、A/B 实验、到达率看板等)。
  • 不引入账号体系与“多设备同人合并”策略(未来可基于 account_id 扩展)。
  • 不在本阶段做精细化内容策略(例如千人千面的复杂推荐推送);仅保证“按次数定时发送”与文案安全合规。

4. 技术选型(高层)

4.1 客户端

  • 继续使用 Expoexpo-notifications
  • Push 权限申请:通过引导页解释后再触发系统弹窗(降低拒绝率)
  • Token 获取:使用 Expo Push Token后续计划阶段细化获取与上报时机

4.2 后端

  • 推送通道:Expo Push Service(与客户端 expo-notifications 配套)
  • 定时任务使用现有后端技术栈约定Celery + Redis / 或等价调度器),每日按用户时区/策略触发推送

说明:若未来需要更高上限(自建 APNs/FCM 直连),可在后续模块升级,不影响本期 API 字段语义(client_user_idpush_token、偏好配置)的大框架。


5. 用户流程User Flows

5.1 首次进入Onboarding

  1. App 首次启动 → 进入 Onboarding 流程
  2. 在 Onboarding 某一页提供“每日提醒次数”选择05
    • 0 表示不接收每日提醒(等同关闭)
    • 可点击“跳过”(不设置/不打扰)
  3. 若用户选择次数 > 0
    • 展示 Push 引导说明页
    • 用户点击“立即开启”触发系统权限申请
  4. 无论是否开启成功,均可进入主功能(不阻塞)

5.2 个人主页(每日提醒弹窗)

  • 用户可:
    • 调整每日次数05
    • 开启/关闭提醒(关闭等价次数=0
    • 若系统权限为 denied提示用户前往系统设置开启不做强制跳转要求按平台能力实现

5.3 后端推送执行

  • 后端按用户配置与时区,在每日窗口内发送 (N) 次推送((N\in[0,5])
  • 若用户关闭或次数=0不再推送

6. 数据与持久化(高层)

6.1 客户端本地存储(最小集合)

  • client_user_id: stringUUID稳定持久化见用户标识 spec
  • push.permission_state: unknown | granted | denied(用于 UI 显示与引导)
  • daily_reminder.enabled: boolean可选或由次数是否为 0 推导)
  • daily_reminder.times_per_day: number05
  • daily_reminder.updated_at: ISO string可选用于排障/幂等)

6.2 后端持久化(逻辑约束)

最小需要表达两类信息:

  1. 设备/Token 绑定
  • client_user_id
  • platformios/android
  • push_tokenExpo Push Token
  • app_idbundle id / package name
  • envdev/prod
  • last_seen_at
  • is_active
  1. 用户推送偏好
  • client_user_id
  • enabled
  • times_per_day05
  • timezone(建议 IANAAsia/Shanghai;若拿不到则回退为服务器默认策略)
  • locale(用于推送文案语言选择;可从客户端上报或推送时推断)
  • updated_at

7. API 契约(高层)

说明:路由名可在 plan 阶段对齐现有服务结构;此处先固定“字段语义 + 幂等行为”。

7.1 注册/更新 Push Token幂等

  • POST /v1/push/register
  • 请求体(最小集,继承用户标识 spec
    • client_user_id: stringUUID
    • platform: "ios" | "android"
    • push_token: stringExpo Push Token
    • app_id: string
    • env: "dev" | "prod"
    • device_meta(可选):{ model, os_version, app_version, locale, timezone }
  • 行为:
    • 幂等:重复上报同一 token 不产生多条“有效绑定”
    • token 变更:同一 client_user_id 上报新 token 后,后端应更新“当前有效 token”

7.2 设置每日提醒偏好(幂等)

  • PUT /v1/push/preferences
  • 请求体:
    • client_user_id: string
    • enabled: boolean
    • times_per_day: number05若 enabled=false 则可强制视为 0
    • timezone: string可选
    • locale: string可选
  • 行为:
    • 幂等:相同配置重复提交不改变结果
    • enabled=falsetimes_per_day=0:必须停止后续推送(不再产生新的发送任务)

7.3 查询当前偏好(可选但建议)

  • GET /v1/push/preferences?client_user_id=...
  • 返回:
    • enabled
    • times_per_day
    • timezone
    • locale
    • updated_at

7.4 立即测试推送(仅 dev可选

  • POST /v1/push/test
  • 请求体:
    • client_user_id
    • title / body(可选)
  • 用途联调排障token 绑定、证书/通道、Expo 配置)

8. 推送策略(高层)

8.1 发送次数与窗口

  • 每日发送次数05
  • 建议定义“允许发送的时间窗口”(例如 09:0021:00避免深夜打扰
  • times_per_day > 0 时,在窗口内生成 (N) 个时间点并发送

时间点生成策略(均匀分布/固定时刻/随机抖动)在 plan 阶段确定;本期只要求“次数正确、用户可控、不会超发”。

8.2 文案来源与语言

  • 文案可先采用后端配置的模板(按 locale 选择,失败回退 enzh-CN
  • 若未来要接入推荐系统,可在后续迭代按用户画像生成更个性化文案(不在本期范围)

9. 边界场景与处理原则

  • 用户跳过 Onboarding:不强制开启;可在个人主页再次设置。
  • 系统权限 denied:客户端提示引导去系统设置;后端保存偏好但不保证可推送(无有效 token 时不发送)。
  • token 缺失/过期:后端发送失败时应标记 token 为不可用,并等待客户端下次上报更新。
  • 重复开关/改次数:后端必须幂等更新,避免同一用户一天内重复排程导致超发。
  • 环境隔离dev/prod 的 token 与配置必须隔离(env + app_id 维度)。
  • 卸载/重装client_user_id 可能变化;视为新用户实例(符合匿名策略)。

10. 验收标准Acceptance Criteria

  • 首次进入 Onboarding
    • 用户可选择每日次数05或跳过
    • 选择后不阻塞进入主功能
  • 个人主页每日提醒弹窗:
    • 可设置次数05与关闭
    • 权限 denied 时有明确提示
  • 客户端:
    • client_user_id 稳定持久化
    • 在获得权限与 token 后能上报后端(幂等)
    • 修改偏好会同步到后端(幂等)
  • 后端:
    • 能保存 token 与偏好
    • 能按用户配置每日推送(次数正确、不会超发)
    • token 失效可被识别并停止对失效 token 推送

11. 待确认问题清单(进入 plan/tasks 前必须确认)

  1. “05 次”的含义:是否严格表示“每天发送 05 条通知”(看起来是),还是“提醒强度档位”?
  2. 发送时间策略:默认窗口与时间点生成方式(固定时刻 vs 均匀分布 vs 随机抖动)选哪一种?
  3. 时区来源:以客户端上报的 IANA 时区为准吗?若缺失回退到什么策略?
  4. 推送文案:本期文案是否完全由后端模板控制(便于随时调整),还是前端上报“文案 key/参数”由后端拼装?
  5. Push 允许发送的静默规则:是否需要“勿扰时间段/睡眠模式”开关(例如 22:0008:00 不推)?