Skip to content

集合:通知(notifications)

字数
1084 字
阅读时间
5 分钟

1. 目的与使用场景

  • 管理小程序内外通知,包括任务提醒、周报推送、SOS 告警、运营活动等。由通知服务、/api/notifications(若实现)、客户端收取与已读反馈使用。

2. Schema 定义

字段类型必填默认值约束/校验说明隐私分级
_idstring-TCB 自动主键P1
user_id指针id-指向 users._id接收者P1
message_typestringtask_reminder枚举(task_reminder,weekly_report,risk_alert,community,system)通知类型P1
template_codestring-长度 ≤ 64模板标识P1
titlestring-长度 ≤ 60通知标题P1
contentstring-长度 ≤ 200文案摘要P1
payloadobject--结构化参数P1
channelstringminiapp枚举(miniapp,subscription,push,email,sms)发送渠道P1
target_pagestring-小程序路径点击跳转P1
deeplinkstring-URL 校验外部链接P1
statusstringpending枚举(pending,sending,sent,failed,read)状态P1
send_atdate-ISO 字符串计划发送时间P1
sent_atdate-ISO 字符串实际发送时间P1
read_atdate-ISO 字符串已读时间P1
error_messagestring-长度 ≤ 200失败原因P1
createdAtdate-服务端时间创建时间P1
updatedAtdate-服务端时间更新时间P1

3. 索引与唯一约束

  • 单字段索引:user_idstatusmessage_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']"
}

通知服务写入;用户仅能读取并回写已读状态。

  1. 关系与级联
  • user_idusers
  • payload.task_idtasks
  • payload.report_idreports
  • 删除策略:保留 90 天后批量归档至日志;用户删除仅标记为已读。
  • 反范式:title/content 直接存储,避免多次模板渲染。
  1. 数据生命周期与合规
  • 留存:90 天,超过归档至对象存储。
  • 匿名化:导出时去除个性化内容,仅留统计字段。
  • 审计:createdAtupdatedAtstatuserror_message
  1. API/云函数契约映射 | 接口/函数 | 读/写 | 使用字段 | 过滤条件 | 排序/分页 | 备注 | | 通知服务 enqueueNotification | 写 | user_id, message_type, payload, channel, send_at | - | - | 队列入口 | | 推送 Worker dispatchNotification | 写 | status, sent_at, error_message | status='pending' | send_at asc | 实际发送 | | /api/notifications GET (预留) | 读 | 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 | - | - | 触发守护者提醒 |

  2. 示例文档(≥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"
}
  1. 常用查询样例(≥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();
  1. 边界与错误码
  • 发送失败:记录 error_message 并返回 E_NOTIFICATION_SEND_FAIL
  • 重复队列:命中唯一约束返回 E_NOTIFICATION_DUPLICATE
  • 越权读取:非本人访问返回 E_FORBIDDEN
  1. 变更影响评估
  • 新模板需同步通知服务配置、/api/notifications 接口及埋点 weekly_report_viewtask_status_update 的推送策略。
  • 索引调整影响消息中心加载与队列处理延迟。
  1. 假设与待确认
  • 假设未来会补充 /api/notifications;当前客户端可能直接通过订阅消息,无需 REST 接口。
  • 待确认是否需要记录阅读设备信息。

贡献者

The avatar of contributor named as Cai Hongyu Cai Hongyu

文件历史

撰写