Files
junhong_cmp_fiber/migrations/000168_create_notification.up.sql
2026-07-24 16:07:18 +08:00

56 lines
3.4 KiB
SQL
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
-- 创建公共站内通知事实表;不建立外键,接收人与资源引用由应用层显式校验。
CREATE TABLE tb_notification (
id bigserial PRIMARY KEY,
event_id varchar(64) NOT NULL,
recipient_kind varchar(32) NOT NULL,
recipient_id bigint NOT NULL,
category varchar(32) NOT NULL,
type varchar(100) NOT NULL,
severity varchar(16) NOT NULL,
title varchar(200) NOT NULL,
body text NOT NULL,
ref_type varchar(64) NOT NULL DEFAULT '',
ref_id varchar(128) NOT NULL DEFAULT '',
ref_key varchar(128) NOT NULL DEFAULT '',
is_read boolean NOT NULL DEFAULT FALSE,
read_at timestamptz,
expires_at timestamptz,
created_at timestamptz NOT NULL DEFAULT NOW(),
CONSTRAINT uq_notification_event_recipient UNIQUE (event_id, recipient_kind, recipient_id),
CONSTRAINT ck_notification_recipient_kind CHECK (recipient_kind IN ('account', 'personal_customer')),
CONSTRAINT ck_notification_recipient_id CHECK (recipient_id > 0),
CONSTRAINT ck_notification_required_text CHECK (event_id <> '' AND type <> '' AND title <> '' AND body <> ''),
CONSTRAINT ck_notification_reference CHECK (
(ref_type = '' AND ref_id = '' AND ref_key = '') OR
(ref_type <> '' AND (ref_id <> '' OR ref_key <> ''))
),
CONSTRAINT ck_notification_category CHECK (category IN ('approval', 'expiry', 'sync', 'system')),
CONSTRAINT ck_notification_severity CHECK (severity IN ('info', 'warning', 'error', 'critical')),
CONSTRAINT ck_notification_read_time CHECK ((is_read = FALSE AND read_at IS NULL) OR (is_read = TRUE AND read_at IS NOT NULL))
);
CREATE INDEX idx_notification_recipient_unread
ON tb_notification (recipient_kind, recipient_id, is_read, created_at DESC, id DESC);
CREATE INDEX idx_notification_recipient_category
ON tb_notification (recipient_kind, recipient_id, category, created_at DESC, id DESC);
CREATE INDEX idx_notification_expires_at
ON tb_notification (expires_at, id) WHERE expires_at IS NOT NULL;
COMMENT ON TABLE tb_notification IS '公共站内通知事实';
COMMENT ON COLUMN tb_notification.id IS '通知主键ID';
COMMENT ON COLUMN tb_notification.event_id IS '上游稳定事件ID与接收人共同防重';
COMMENT ON COLUMN tb_notification.recipient_kind IS '接收人类型account后台账号personal_customer个人客户';
COMMENT ON COLUMN tb_notification.recipient_id IS '接收人账号或个人客户ID';
COMMENT ON COLUMN tb_notification.category IS '通知分类:审批、临期、同步或系统';
COMMENT ON COLUMN tb_notification.type IS '稳定通知类型编码';
COMMENT ON COLUMN tb_notification.severity IS '通知严重级别:普通、警告、错误或严重';
COMMENT ON COLUMN tb_notification.title IS '发送时固化的纯文本标题';
COMMENT ON COLUMN tb_notification.body IS '发送时固化的纯文本正文';
COMMENT ON COLUMN tb_notification.ref_type IS '受控关联资源类型,空字符串表示无关联资源';
COMMENT ON COLUMN tb_notification.ref_id IS '受控关联资源ID禁止保存任意URL';
COMMENT ON COLUMN tb_notification.ref_key IS '受控关联资源稳定键禁止保存任意URL';
COMMENT ON COLUMN tb_notification.is_read IS '是否已被接收人读取';
COMMENT ON COLUMN tb_notification.read_at IS '接收人首次读取时间';
COMMENT ON COLUMN tb_notification.expires_at IS '通知停止展示时间,空值表示不自动过期';
COMMENT ON COLUMN tb_notification.created_at IS '通知创建时间';