# 消息推送后台 —— 核心数据库表结构需求文档 > **创建日期**:2026年03月16日 > **模块归属**:商城发货与物流推送后台 > **涉及架构**:Node.js Worker + Supabase (PostgreSQL) + UniPush 2.0 为支撑高可用、防丢失、可追溯的异步消息推送架构,本消息推送系统在底层(Supabase/PostgreSQL)摒弃了传统的 Redis 中间件依赖,直接利用关系型数据库的横表与触发器机制(Transactional Outbox 事务外箱模式)完成了高并发状态下的物流事件缓冲与分发。 本需求文档详细列出了参与推送闭环的 **5 张核心数据表** 的设计规范、字段说明与职责定位,是后端/DBA 开发与日常客诉运维排障的唯一真理依据。 --- ## 整体库表流转全景 消息在数据库中的物理游走路径为: **`平台接收原生钩子`** $\rightarrow$ **`轨迹业务表入库`** $\rightarrow$ (触发器) $\rightarrow$ **`任务队列缓冲表`** $\rightarrow$ (合并订单/用户数据) $\rightarrow$ **`最终下发通知表`** $\rightarrow$ **`匹配设备表CID推送`** --- ## 一、 原始通信日志表 (`platform_express_event_raw`) ### 1. 表职责方向 保存第一手的物流商(如快递100)Webhook 推送过来的原生 JSON 报文。不做任何业务过滤。 - **核心价值**:排查“某单是不是底下的快递公司就没给我们发回调?”的第一现场。如果这里没有记录,绝不可能是本系统的 Bug。 ### 2. 核心字段设计 (逻辑概述) * `id` (UUID): 唯一自增主键。 * `raw_payload` (JSONB): 快递100推过来的纯原生报文。 * `created_at` (Timestamp): 平台接收到外网请求的确切服务器时间。 --- ## 二、 规范化轨迹主表 (`platform_express_tracking_events` / `waybills`) ### 1. 表职责方向 用于商城订单域查询使用的结构化物流跟踪事件表。接收服务将 `event_raw` 里的 JSON 解包后,转化为本商城统一的枚举状态。 - **机制特点**:这张表在发生 `INSERT` (即产生新轨迹节点) 时,会触发 PostgreSQL 内置触发器 `event_to_queue_trigger`。 ### 2. 核心字段要求 * `waybill_id` (UUID): 关联的运单主键。 * `status_code` (VARCHAR): 规范化的签收/派件枚举状态码。 * `event_text` (TEXT): 具体的物流节点描述文本(例:“北京市【朝阳区】,您的快递已由门卫代签收”)。 --- ## 三、 异步缓冲队列表 (`notify_queue`) ### 1. 表职责方向 承接业务量暴增时的**削峰填谷**与**断电防丢**任务(本质是实现基于 DB 的 Message Queue)。 - **流程规范**:触发器把满足条件(如需要给用户弹推送的节点)的事件主键,极速插入本表待命。后台的 `notify-worker.js` (消费者) 轮询查表消费。 ### 2. 核心字段定义 * `id` (UUID): 队列任务唯一标识。 * `waybill_id` (UUID): 运单号,Worker 读取后利用它去关联查询出订单里的 `user_id` 和商品信息。 * `status_code` (VARCHAR): 通知级别状态。 * **`dedupe_key` (VARCHAR)**: 防重幂等键。防止因为相同事件重复回调产生两条推送。 * **`process_status` (VARCHAR)**: 最核心的状态机! * `pending`: 等待 Node.js Worker 消费。 * `processing`: Worker 消费中(乐观锁占用)。 * `processed`: 拼接业务数据完成,已成功放入推送大表,完美结束。 * `failed`: 服务异常或订单找不到,抛弃处理。 * `last_error` (TEXT): 消费报错时的堆栈。 --- ## 四、 最终下发通知表 (`express_notifications`) ### 1. 表职责方向 面向客户端推送与“站内信展示”的实体记录表。这里存放的是已经完成业务数据组装(谁买的、买的啥、什么物流状态),只需调用第三方厂商接口往外发的纯粹“信件”内容。 - **流程规范**:`push-server.js` 轮询此表进行真实推送。 ### 2. 核心字段定义 * `id` (UUID): 消息的主键ID。 * `recipient_id` (UUID): 接收用户的标识 (商城买家ID)。 * `event_text_safe` (TEXT): 已经组装好且脱敏的安全话术(例如:“[张*],您的Nike球鞋正在派送中”)。 * **`send_status / push_status` (VARCHAR)**: 推送服务通道状态机。 * `pending`: 已产生信件,排队等待网络 POST 请发给 UniPush 云函数。 * `delivered`: 云函数返回 200,且厂家确认通道收录。 * `failed`: 网络异常或设备CID已注销失效。 * `provider_response` (JSONB): 如果推送失败,此处会存储华为/小米等厂商或推服务产生的物理失败原因。 --- ## 五、 设备凭证绑定表 (`push_devices`) ### 1. 表职责方向 提供从“商城系统 `user_id`” 到“手机厂家原生通道标识 `cid`” 的 KV 路由映射能力。 - **业务场景**:用户 App 在启动或大版本更新时,前端会通过 `uni.getPushClientId` 获取本设备的厂商识别码,通过接口上报并 UPSERT 写入此表。 ### 2. 核心字段定义 * `id` (UUID): 映射记录主键。 * `user_id` (UUID): 系统业务逻辑里的用户身份标识。 * **`cid` (VARCHAR)**: UniPush 2.0 分配在设备当前生命周期的绝对推送识别码(至关重要,一旦清空缓存/重装系统可能会变动,必须持续覆盖更新)。 * `updated_at` (Timestamp): 用以判断该设备CID的活跃新鲜度。如果一个CID超过1年未更新导致 `push_status` 频繁 `failed`,后台可将其标记为离线沉默用户放弃网络调用。 --- ## 附:业务表拓展准则 (Guidelines) 如果未来需要将这套机制从物流推送拓展至**“拼团成功通知”**或**“特价秒杀通知”**,只需要: 1. 复用 `express_notifications` 表,或者建立同层级类似的 `system_notifications` 表,保留 `push_status` 和 `recipient_id`。 2. 复用 `push_devices` 路由查找。 3. 把源头触发器挂载到新的交易表中即可。此五表闭环具备极佳的**水平扩展性**与**极低的中间件运维成本**。