获取 URL 和密钥(任选其一): 方法A(推荐):点击项目首页右上角 「Connect」 按钮,选 App Frameworks → 任意框架,复制 Project URL 和 API Key 方法B:左侧菜单 Settings → API Keys,点击 Create new API Keys,复制 Publishable key(格式 sb_publishable_xxx) 方法C(旧版):同页面切到 Legacy API Keys 标签页,复制 Project URL 和 anon 密钥
将 URL 和密钥填入下方两个输入框,先点「测试连接」,成功后保存
-- 建表 SQL(复制粘贴到 Supabase SQL Editor 运行,可重复执行)
-- 6张独立数据表 + 1张设置表
CREATE TABLE IF NOT EXISTS todos (
id BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
user_id UUID REFERENCES auth.users NOT NULL,
record_id TEXT NOT NULL,
data JSONB NOT NULL DEFAULT '{}',
created_at TIMESTAMPTZ DEFAULT NOW(),
UNIQUE(user_id, record_id)
);
CREATE TABLE IF NOT EXISTS research (
id BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
user_id UUID REFERENCES auth.users NOT NULL,
record_id TEXT NOT NULL,
data JSONB NOT NULL DEFAULT '{}',
created_at TIMESTAMPTZ DEFAULT NOW(),
UNIQUE(user_id, record_id)
);
CREATE TABLE IF NOT EXISTS vertical (
id BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
user_id UUID REFERENCES auth.users NOT NULL,
record_id TEXT NOT NULL,
data JSONB NOT NULL DEFAULT '{}',
created_at TIMESTAMPTZ DEFAULT NOW(),
UNIQUE(user_id, record_id)
);
CREATE TABLE IF NOT EXISTS horizontal (
id BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
user_id UUID REFERENCES auth.users NOT NULL,
record_id TEXT NOT NULL,
data JSONB NOT NULL DEFAULT '{}',
created_at TIMESTAMPTZ DEFAULT NOW(),
UNIQUE(user_id, record_id)
);
CREATE TABLE IF NOT EXISTS plans (
id BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
user_id UUID REFERENCES auth.users NOT NULL,
record_id TEXT NOT NULL,
data JSONB NOT NULL DEFAULT '{}',
created_at TIMESTAMPTZ DEFAULT NOW(),
UNIQUE(user_id, record_id)
);
CREATE TABLE IF NOT EXISTS daily (
id BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
user_id UUID REFERENCES auth.users NOT NULL,
record_id TEXT NOT NULL,
data JSONB NOT NULL DEFAULT '{}',
created_at TIMESTAMPTZ DEFAULT NOW(),
UNIQUE(user_id, record_id)
);
CREATE TABLE IF NOT EXISTS settings (
id BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
user_id UUID REFERENCES auth.users NOT NULL,
key TEXT NOT NULL,
value TEXT,
updated_at TIMESTAMPTZ DEFAULT NOW(),
UNIQUE(user_id, key)
);
ALTER TABLE todos ENABLE ROW LEVEL SECURITY;
ALTER TABLE research ENABLE ROW LEVEL SECURITY;
ALTER TABLE vertical ENABLE ROW LEVEL SECURITY;
ALTER TABLE horizontal ENABLE ROW LEVEL SECURITY;
ALTER TABLE plans ENABLE ROW LEVEL SECURITY;
ALTER TABLE daily ENABLE ROW LEVEL SECURITY;
ALTER TABLE settings ENABLE ROW LEVEL SECURITY;
DROP POLICY IF EXISTS "crud_todos" ON todos;
CREATE POLICY "crud_todos" ON todos FOR ALL USING (auth.uid() = user_id) WITH CHECK (auth.uid() = user_id);
DROP POLICY IF EXISTS "crud_research" ON research;
CREATE POLICY "crud_research" ON research FOR ALL USING (auth.uid() = user_id) WITH CHECK (auth.uid() = user_id);
DROP POLICY IF EXISTS "crud_vertical" ON vertical;
CREATE POLICY "crud_vertical" ON vertical FOR ALL USING (auth.uid() = user_id) WITH CHECK (auth.uid() = user_id);
DROP POLICY IF EXISTS "crud_horizontal" ON horizontal;
CREATE POLICY "crud_horizontal" ON horizontal FOR ALL USING (auth.uid() = user_id) WITH CHECK (auth.uid() = user_id);
DROP POLICY IF EXISTS "crud_plans" ON plans;
CREATE POLICY "crud_plans" ON plans FOR ALL USING (auth.uid() = user_id) WITH CHECK (auth.uid() = user_id);
DROP POLICY IF EXISTS "crud_daily" ON daily;
CREATE POLICY "crud_daily" ON daily FOR ALL USING (auth.uid() = user_id) WITH CHECK (auth.uid() = user_id);
DROP POLICY IF EXISTS "crud_settings" ON settings;
CREATE POLICY "crud_settings" ON settings FOR ALL USING (auth.uid() = user_id) WITH CHECK (auth.uid() = user_id);
ALTER PUBLICATION supabase_realtime ADD TABLE todos;
ALTER PUBLICATION supabase_realtime ADD TABLE research;
ALTER PUBLICATION supabase_realtime ADD TABLE vertical;
ALTER PUBLICATION supabase_realtime ADD TABLE horizontal;
ALTER PUBLICATION supabase_realtime ADD TABLE plans;
ALTER PUBLICATION supabase_realtime ADD TABLE daily;
ALTER PUBLICATION supabase_realtime ADD TABLE settings;
-- 迁移:如果旧 projects 表存在,按 category 分散到新表(不存在则自动跳过)
DO $$
BEGIN
IF EXISTS (SELECT 1 FROM information_schema.tables WHERE table_schema = 'public' AND table_name = 'projects') THEN
INSERT INTO research (user_id, record_id, data) SELECT user_id, record_id, data FROM projects WHERE data->>'category' = 'research' ON CONFLICT (user_id, record_id) DO NOTHING;
INSERT INTO vertical (user_id, record_id, data) SELECT user_id, record_id, data FROM projects WHERE data->>'category' = 'vertical' ON CONFLICT (user_id, record_id) DO NOTHING;
INSERT INTO horizontal (user_id, record_id, data) SELECT user_id, record_id, data FROM projects WHERE data->>'category' = 'horizontal' ON CONFLICT (user_id, record_id) DO NOTHING;
INSERT INTO daily (user_id, record_id, data) SELECT user_id, record_id, data FROM projects WHERE data->>'category' = 'daily' ON CONFLICT (user_id, record_id) DO NOTHING;
END IF;
END $$;