gcx/backend/migrations/038_create_announcements.sql

75 lines
2.9 KiB
SQL

-- =============================================================
-- 038: Announcement targeting system (ported from rwadurian)
-- 公告定向推送系统: 全体用户 / 按标签 / 指定用户
-- =============================================================
-- 1. 公告主表
CREATE TABLE IF NOT EXISTS announcements (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
title VARCHAR(200) NOT NULL,
content TEXT NOT NULL,
type VARCHAR(20) NOT NULL DEFAULT 'SYSTEM'
CHECK (type IN ('SYSTEM','ACTIVITY','REWARD','UPGRADE','ANNOUNCEMENT')),
priority VARCHAR(10) NOT NULL DEFAULT 'NORMAL'
CHECK (priority IN ('LOW','NORMAL','HIGH','URGENT')),
target_type VARCHAR(10) NOT NULL DEFAULT 'ALL'
CHECK (target_type IN ('ALL','BY_TAG','SPECIFIC')),
target_config JSONB,
image_url VARCHAR(500),
link_url VARCHAR(500),
is_enabled BOOLEAN NOT NULL DEFAULT true,
published_at TIMESTAMPTZ,
expires_at TIMESTAMPTZ,
created_by UUID,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
CREATE INDEX idx_announcements_type ON announcements(type);
CREATE INDEX idx_announcements_target ON announcements(target_type);
CREATE INDEX idx_announcements_enabled ON announcements(is_enabled, published_at);
-- 2. 公告标签定向表
CREATE TABLE IF NOT EXISTS announcement_tag_targets (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
announcement_id UUID NOT NULL REFERENCES announcements(id) ON DELETE CASCADE,
tag VARCHAR(100) NOT NULL
);
CREATE INDEX idx_ann_tag_targets_ann ON announcement_tag_targets(announcement_id);
CREATE INDEX idx_ann_tag_targets_tag ON announcement_tag_targets(tag);
-- 3. 公告用户定向表
CREATE TABLE IF NOT EXISTS announcement_user_targets (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
announcement_id UUID NOT NULL REFERENCES announcements(id) ON DELETE CASCADE,
user_id UUID NOT NULL
);
CREATE INDEX idx_ann_user_targets_ann ON announcement_user_targets(announcement_id);
CREATE INDEX idx_ann_user_targets_user ON announcement_user_targets(user_id);
-- 4. 公告已读记录表
CREATE TABLE IF NOT EXISTS announcement_reads (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
announcement_id UUID NOT NULL REFERENCES announcements(id) ON DELETE CASCADE,
user_id UUID NOT NULL,
read_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
UNIQUE (announcement_id, user_id)
);
CREATE INDEX idx_ann_reads_user ON announcement_reads(user_id);
CREATE INDEX idx_ann_reads_ann ON announcement_reads(announcement_id);
-- 5. 用户标签表
CREATE TABLE IF NOT EXISTS user_tags (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
user_id UUID NOT NULL,
tag VARCHAR(100) NOT NULL,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
UNIQUE (user_id, tag)
);
CREATE INDEX idx_user_tags_user ON user_tags(user_id);
CREATE INDEX idx_user_tags_tag ON user_tags(tag);