56 lines
3.4 KiB
SQL
56 lines
3.4 KiB
SQL
-- 创建公共站内通知事实表;不建立外键,接收人与资源引用由应用层显式校验。
|
||
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 '通知创建时间';
|