Files
app/wei_ai_app/supabase/migrations/001_create_tables.sql
2026-01-28 20:28:38 +08:00

157 lines
5.7 KiB
PL/PgSQL
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.
-- =============================================
-- Wei AI App - Supabase 数据库初始化脚本
-- 版本: 1.0.0
-- 日期: 2026-01-28
-- =============================================
-- 1. 创建分类表 (categories)
-- 用于 Discovery 页面的筛选标签
CREATE TABLE IF NOT EXISTS categories (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
code TEXT NOT NULL UNIQUE, -- 分类代码: all, gentle, dom, wild 等
label TEXT NOT NULL, -- 显示名称: 全部, 温柔治愈 等
sort_order INTEGER DEFAULT 0, -- 排序顺序
is_active BOOLEAN DEFAULT true, -- 是否启用
created_at TIMESTAMPTZ DEFAULT now()
);
-- 2. 创建标签表 (tags)
-- 角色的标签,如 "温顺", "调教", "治愈" 等
CREATE TABLE IF NOT EXISTS tags (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
name TEXT NOT NULL UNIQUE, -- 标签名称
category_id UUID REFERENCES categories(id) ON DELETE SET NULL, -- 关联分类(可选)
color TEXT, -- 标签颜色可选HEX 格式)
created_at TIMESTAMPTZ DEFAULT now()
);
-- 3. 创建角色表 (characters)
-- 核心表:存储 AI 角色信息
CREATE TABLE IF NOT EXISTS characters (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
-- 基本信息
name TEXT NOT NULL, -- 角色名称
tagline TEXT, -- 角色标语/副标题
avatar_path TEXT, -- Storage 中的头像路径
description TEXT, -- 角色描述
-- 状态信息
compatibility REAL DEFAULT 0, -- 契合度 (0-100)
status TEXT DEFAULT 'online', -- 状态: online, busy, offline
is_locked BOOLEAN DEFAULT false, -- 是否锁定(会员限定)
is_active BOOLEAN DEFAULT true, -- 是否上架显示
sort_order INTEGER DEFAULT 0, -- 排序顺序
-- AI 配置
ai_system_prompt TEXT, -- AI 系统提示词(人设 Prompt
ai_greeting TEXT, -- AI 第一句问候语
ai_personality JSONB DEFAULT '{}', -- AI 性格配置
ai_voice_config JSONB DEFAULT '{}', -- 语音配置
-- 时间戳
created_at TIMESTAMPTZ DEFAULT now(),
updated_at TIMESTAMPTZ DEFAULT now()
);
-- 4. 创建角色-标签关联表 (character_tags)
CREATE TABLE IF NOT EXISTS character_tags (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
character_id UUID NOT NULL REFERENCES characters(id) ON DELETE CASCADE,
tag_id UUID NOT NULL REFERENCES tags(id) ON DELETE CASCADE,
sort_order INTEGER DEFAULT 0, -- 标签在角色卡片上的显示顺序
-- 唯一约束:一个角色不能有重复标签
UNIQUE(character_id, tag_id)
);
-- =============================================
-- 创建索引以提升查询性能
-- =============================================
CREATE INDEX IF NOT EXISTS idx_categories_sort ON categories(sort_order);
CREATE INDEX IF NOT EXISTS idx_categories_active ON categories(is_active);
CREATE INDEX IF NOT EXISTS idx_tags_category ON tags(category_id);
CREATE INDEX IF NOT EXISTS idx_characters_active ON characters(is_active);
CREATE INDEX IF NOT EXISTS idx_characters_locked ON characters(is_locked);
CREATE INDEX IF NOT EXISTS idx_characters_status ON characters(status);
CREATE INDEX IF NOT EXISTS idx_characters_sort ON characters(sort_order);
CREATE INDEX IF NOT EXISTS idx_character_tags_character ON character_tags(character_id);
CREATE INDEX IF NOT EXISTS idx_character_tags_tag ON character_tags(tag_id);
-- =============================================
-- 创建更新时间触发器
-- =============================================
CREATE OR REPLACE FUNCTION update_updated_at_column()
RETURNS TRIGGER AS $$
BEGIN
NEW.updated_at = now();
RETURN NEW;
END;
$$ language 'plpgsql';
CREATE TRIGGER update_characters_updated_at
BEFORE UPDATE ON characters
FOR EACH ROW
EXECUTE FUNCTION update_updated_at_column();
-- =============================================
-- 创建 RLS (Row Level Security) 策略
-- 暂时允许所有人读取,后续可以根据需求修改
-- =============================================
ALTER TABLE categories ENABLE ROW LEVEL SECURITY;
ALTER TABLE tags ENABLE ROW LEVEL SECURITY;
ALTER TABLE characters ENABLE ROW LEVEL SECURITY;
ALTER TABLE character_tags ENABLE ROW LEVEL SECURITY;
-- 允许匿名用户读取所有数据
CREATE POLICY "Allow public read access on categories"
ON categories FOR SELECT
USING (true);
CREATE POLICY "Allow public read access on tags"
ON tags FOR SELECT
USING (true);
CREATE POLICY "Allow public read access on characters"
ON characters FOR SELECT
USING (is_active = true);
CREATE POLICY "Allow public read access on character_tags"
ON character_tags FOR SELECT
USING (true);
-- =============================================
-- 创建视图:角色完整信息(包含标签)
-- =============================================
CREATE OR REPLACE VIEW characters_with_tags AS
SELECT
c.*,
COALESCE(
jsonb_agg(
jsonb_build_object(
'id', t.id,
'name', t.name,
'color', t.color
) ORDER BY ct.sort_order
) FILTER (WHERE t.id IS NOT NULL),
'[]'::jsonb
) as tags
FROM characters c
LEFT JOIN character_tags ct ON c.id = ct.character_id
LEFT JOIN tags t ON ct.tag_id = t.id
WHERE c.is_active = true
GROUP BY c.id
ORDER BY c.sort_order, c.created_at;
COMMENT ON TABLE categories IS '分类筛选表 - Discovery 页面的筛选选项';
COMMENT ON TABLE tags IS '标签表 - 角色的标签';
COMMENT ON TABLE characters IS '角色表 - AI 角色信息和配置';
COMMENT ON TABLE character_tags IS '角色-标签关联表';