集合:通知(notifications)
字数
1084 字
阅读时间
5 分钟
1. 目的与使用场景
- 管理小程序内外通知,包括任务提醒、周报推送、SOS 告警、运营活动等。由通知服务、
/api/notifications(若实现)、客户端收取与已读反馈使用。
2. Schema 定义
| 字段 | 类型 | 必填 | 默认值 | 约束/校验 | 说明 | 隐私分级 |
|---|---|---|---|---|---|---|
| _id | string | 是 | - | TCB 自动 | 主键 | P1 |
| user_id | 指针id | 是 | - | 指向 users._id | 接收者 | P1 |
| message_type | string | 是 | task_reminder | 枚举(task_reminder,weekly_report,risk_alert,community,system) | 通知类型 | P1 |
| template_code | string | 否 | - | 长度 ≤ 64 | 模板标识 | P1 |
| title | string | 是 | - | 长度 ≤ 60 | 通知标题 | P1 |
| content | string | 否 | - | 长度 ≤ 200 | 文案摘要 | P1 |
| payload | object | 否 | - | - | 结构化参数 | P1 |
| channel | string | 是 | miniapp | 枚举(miniapp,subscription,push,email,sms) | 发送渠道 | P1 |
| target_page | string | 否 | - | 小程序路径 | 点击跳转 | P1 |
| deeplink | string | 否 | - | URL 校验 | 外部链接 | P1 |
| status | string | 是 | pending | 枚举(pending,sending,sent,failed,read) | 状态 | P1 |
| send_at | date | 否 | - | ISO 字符串 | 计划发送时间 | P1 |
| sent_at | date | 否 | - | ISO 字符串 | 实际发送时间 | P1 |
| read_at | date | 否 | - | ISO 字符串 | 已读时间 | P1 |
| error_message | string | 否 | - | 长度 ≤ 200 | 失败原因 | P1 |
| createdAt | date | 是 | - | 服务端时间 | 创建时间 | P1 |
| updatedAt | date | 是 | - | 服务端时间 | 更新时间 | P1 |
3. 索引与唯一约束
- 单字段索引:
user_id、status、message_type - 复合索引:
[user_id, status, send_at] - 唯一性约束:
[user_id, message_type, payload.hash](若提供)避免重复推送 - 设计理由:前端列表查询按用户/状态;后台排队按发送时间。
4. 访问控制(TCB 权限)
json
{
"read": "user_id == auth.uid || auth.role in ['ops']",
"write": "auth.role in ['notification_service','ops']"
}通知服务写入;用户仅能读取并回写已读状态。
- 关系与级联
user_id→userspayload.task_id→taskspayload.report_id→reports- 删除策略:保留 90 天后批量归档至日志;用户删除仅标记为已读。
- 反范式:
title/content直接存储,避免多次模板渲染。
- 数据生命周期与合规
- 留存:90 天,超过归档至对象存储。
- 匿名化:导出时去除个性化内容,仅留统计字段。
- 审计:
createdAt、updatedAt、status、error_message。
API/云函数契约映射 | 接口/函数 | 读/写 | 使用字段 | 过滤条件 | 排序/分页 | 备注 | | 通知服务
enqueueNotification| 写 | user_id, message_type, payload, channel, send_at | - | - | 队列入口 | | 推送 WorkerdispatchNotification| 写 | status, sent_at, error_message |status='pending'|send_at asc| 实际发送 | |/api/notificationsGET (预留) | 读 | title, content, channel, status, createdAt |user_id = auth.uid|createdAt desc| 我的页消息中心 | |/api/notifications/:id/read| 写 | status='read', read_at |_id,user_id=auth.uid| - | 已读回写 | | SOS 通知流程 | 写 | message_type='risk_alert', payload | - | - | 触发守护者提醒 |示例文档(≥3条)
json
{
"_id": "noti_7001",
"user_id": "usr_001",
"message_type": "task_reminder",
"template_code": "task_due_soon",
"title": "20 分钟后开始和室友沟通",
"content": "准备讨论三个安静时段",
"payload": {"task_id": "task_305"},
"channel": "miniapp",
"target_page": "miniprogram/pages/today/index",
"status": "sent",
"send_at": "2024-04-06T13:40:00Z",
"sent_at": "2024-04-06T13:40:05Z",
"createdAt": "2024-04-06T13:25:00Z",
"updatedAt": "2024-04-06T13:40:05Z"
}
{
"_id": "noti_7100",
"user_id": "usr_002",
"message_type": "weekly_report",
"title": "你的护心周报已生成",
"content": "点击查看本周洞察",
"payload": {"report_id": "rep_week_2024w14_usr002"},
"channel": "subscription",
"status": "sent",
"sent_at": "2024-04-07T23:06:00Z",
"createdAt": "2024-04-07T23:05:00Z",
"updatedAt": "2024-04-07T23:06:00Z"
}
{
"_id": "noti_7200",
"user_id": "usr_guard_01",
"message_type": "risk_alert",
"title": "学生 SOS 请求",
"content": "学生 Aria 请求联络,请尽快回拨",
"payload": {"sos_id": "sos_20240406_01"},
"channel": "sms",
"status": "sent",
"sent_at": "2024-04-06T14:04:00Z",
"createdAt": "2024-04-06T14:03:30Z",
"updatedAt": "2024-04-06T14:04:00Z"
}- 常用查询样例(≥3条)
javascript
// 用户消息中心
const list = await db.collection('notifications').where({ user_id: auth.uid })
.orderBy('createdAt', 'desc').limit(20).get();
// 未读数统计
const unread = await db.collection('notifications').where({
user_id: auth.uid,
status: db.command.neq('read')
}).count();
// 推送队列查找待发送
const queue = await db.collection('notifications').where({
status: 'pending',
send_at: db.command.lte(new Date().toISOString())
}).orderBy('send_at', 'asc').limit(50).get();- 边界与错误码
- 发送失败:记录
error_message并返回E_NOTIFICATION_SEND_FAIL。 - 重复队列:命中唯一约束返回
E_NOTIFICATION_DUPLICATE。 - 越权读取:非本人访问返回
E_FORBIDDEN。
- 变更影响评估
- 新模板需同步通知服务配置、
/api/notifications接口及埋点weekly_report_view、task_status_update的推送策略。 - 索引调整影响消息中心加载与队列处理延迟。
- 假设与待确认
- 假设未来会补充
/api/notifications;当前客户端可能直接通过订阅消息,无需 REST 接口。 - 待确认是否需要记录阅读设备信息。