feat: 角色卡 demo
This commit is contained in:
156
wei_ai_app/supabase/migrations/001_create_tables.sql
Normal file
156
wei_ai_app/supabase/migrations/001_create_tables.sql
Normal file
@@ -0,0 +1,156 @@
|
||||
-- =============================================
|
||||
-- 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 '角色-标签关联表';
|
||||
Reference in New Issue
Block a user