> ## Documentation Index
> Fetch the complete documentation index at: https://supastack.dev/llms.txt
> Use this file to discover all available pages before exploring further.
> For the full documentation corpus in one file, fetch: https://supastack.dev/llms-full.txt

# 通知与推送

应用内收件箱、渠道偏好，以及 Expo 推送管线。

## 收件箱与渠道偏好

通知标签页列出 GET /api/notifications 返回的工作区通知，并对通知 id 发起 PATCH 标记已读。“设置 → 通知”编辑共享的渠道偏好 —— emailBilling、emailInvites、inAppProduct —— 通过同一路由偏好视图的 GET 与 PATCH 完成，正是 Web 应用使用的契约。未读数量会显示在首页。


## 为推送注册设备

登录时 —— 以及每次切换工作区时 —— 应用会请求通知权限、从应用配置解析 EAS 项目 id、获取 Expo 推送 token，并提交到 POST /api/mobile/push-tokens。Android 在默认渠道上以高重要性注册。

注册结果报告为 registered、permission_denied 或 unavailable，且绝不抛错 —— 推送永远不会阻塞登录。Expo Go 与模拟器无法完成注册，真实覆盖需要开发构建。token 保存在 SecureStore（supastack.push.token）中，以便退出登录时在会话 Cookie 销毁前先将其注销。


## 服务端投递与回执

GET 列出成员的 token，POST 在当前工作区下 upsert token，DELETE 撤销 —— 列表与撤销保持用户级作用域，没有工作区的账户也能清理。每个用户最多保留二十个设备 token；多注册一个会修剪最旧的那个。

每条应用内工作区通知也会尽力推送：服务器以一百条为一批调用 Expo 推送 API，记录 ok 票据，并立即清理 DeviceNotRegistered 的 token。可选的服务端专用 EXPO_ACCESS_TOKEN 会为这些调用附加 Bearer 头，且绝不写入日志。一个平台计划任务每三十分钟核对一次回执并清扫过期票据 —— 它与其他平台计划任务共用同一个调度 tick 驱动。

```
# Optional server-only token for authenticated Expo push sends:
# apps/web/.env.local
EXPO_ACCESS_TOKEN=
```


## 点击通知打开应用路由

发送方把 Web 路径附在 data.href 上。应用会校验它 —— 只允许以斜杠开头的绝对路径、限制长度、禁止路径穿越 —— 并把已知路径映射为原生路由，例如 /billing 到 /settings/billing、/dashboard 到 /home。未登录时到达的点击会先缓冲，登录完成后再回放。


## 验证与排障

在开发构建上测试：授予与拒绝权限、在“设置 → 通知”中切换推送 —— 界面会把此设备报告为 enabled、disabled 或 denied —— 并分别以冷态与热态点击通知。如果关闭时报错，说明服务端注销失败，设备会保持注册状态直到成功为止。

[创建开发构建](https://supastack.dev/zh/docs/mobile/eas-setup.md)


## 下一篇

[用量与额度](https://supastack.dev/zh/docs/mobile/usage.md)
