Documentation Index
Fetch the complete documentation index at: https://help.helloazhenweb.top/llms.txt
Use this file to discover all available pages before exploring further.
Birthday Wall 把祝福墙留言、页面可见性设置、管理员用户和注册码存储在 Supabase Postgres 数据库中。本页将带你完成创建项目、运行迁移 SQL、并找到需要写入环境变量的凭据。
创建一个 Supabase 项目
- 前往 supabase.com 并登录(或免费注册账号)。
- 在组织面板中点击 New project。
- 给项目起名(如
birthday-wall),选择数据库密码,并选择离用户最近的区域。
- 点击 Create new project 并等待项目创建完成 — 通常大约 30 秒。
运行数据库迁移
所有所需的数据表都由一份 SQL 脚本一次性创建。在你的 Supabase 项目中:
- 点击左侧栏的 SQL Editor。
- 点击 New query。
- 粘贴下面的完整迁移脚本,然后点击 Run。
-- ========================================
-- Table: messages
-- Stores birthday wish wall submissions
-- ========================================
create table messages (
id uuid default gen_random_uuid() primary key,
content text not null,
ip_hash text not null,
color text not null,
created_at timestamp with time zone default timezone('utc'::text, now()) not null
);
-- Allow anyone to read messages (displayed on the home page)
alter table messages enable row level security;
create policy "Allow public read messages" on messages
for select using (true);
-- Only the service role can insert or delete messages
create policy "Service role full access messages" on messages
for all using (auth.role() = 'service_role');
-- ========================================
-- Table: page_configs
-- Controls which pages appear in the bottom navigation bar
-- ========================================
create table page_configs (
id text primary key,
name text not null,
path text not null,
icon text,
visible boolean not null default true,
"order" integer not null default 0
);
-- Insert default page configuration
insert into page_configs (id, name, path, icon, visible, "order") values
('home', '首页', '/', '🏠', true, 1),
('write', '写祝福', '/write', '✏️', true, 2),
('report', '报告', '/report', '📊', true, 3),
('games', '游戏室', '/games', '🎮', true, 4);
-- Allow anyone to read page configs
create policy "Allow public read page_configs" on page_configs
for select using (true);
-- Only the service role can modify page configs
create policy "Service role full access page_configs" on page_configs
for all using (auth.role() = 'service_role');
-- ========================================
-- Table: users
-- Stores admin user records linked to Supabase Auth
-- ========================================
create table users (
id uuid primary key references auth.users(id) on delete cascade,
email text,
role text not null default 'user' check (role in ('admin', 'user')),
created_at timestamp with time zone default timezone('utc'::text, now()) not null
);
-- Only the service role can access user records
create policy "Service role full access users" on users
for all using (auth.role() = 'service_role');
-- ========================================
-- Table: registration_codes
-- Used for invitation-code-gated admin registration
-- ========================================
create table registration_codes (
id uuid default gen_random_uuid() primary key,
code text not null unique,
used boolean not null default false,
created_at timestamp with time zone default timezone('utc'::text, now()) not null
);
-- Allow anyone to read codes (needed for client-side verification)
create policy "Allow public read registration_codes" on registration_codes
for select using (true);
-- Only the service role can modify registration codes
create policy "Service role full access registration_codes" on registration_codes
for all using (auth.role() = 'service_role');
-- ========================================
-- Optional: seed an initial admin registration code
-- Replace 'ADMIN123' with a secret value before running
-- ========================================
insert into registration_codes (code) values ('ADMIN123');
运行之前,请将 ADMIN123 改成一个难以猜测的唯一值。任何拿到这个码的人都可以注册管理员账号。
SQL 执行成功后,你应当能在 Table Editor 中看到全部四张表 — messages、page_configs、users 和 registration_codes。 获取 API 凭据
Next.js 应用需要从 Supabase 获取三个值。请在 Supabase 仪表板中进入 Project Settings → API:| 凭据 | 在哪里找到 | 用于 |
|---|
| Project URL | ”Project URL” 字段 | NEXT_PUBLIC_SUPABASE_URL |
| anon / public key | ”Project API keys” → anon public | NEXT_PUBLIC_SUPABASE_ANON_KEY |
| service_role key | ”Project API keys” → service_role(点击显示) | SUPABASE_SERVICE_ROLE_KEY |
把三个值都复制下来 — 下一步会用到。 把凭据添加为环境变量
将三个 Supabase 值添加到你的环境中。完整的必填变量清单和一份可直接粘贴的 .env.local 模板,见 环境变量页面。
行级安全(Row Level Security)
迁移 SQL 会自动在所有表上启用行级安全(RLS)策略。每条策略的作用如下:
| 表 | 策略 | 效果 |
|---|
messages | Allow public read | 任何人都可读取在首页展示的祝福 |
messages | Service role full access | 只有服务端 API 路由可以插入或删除祝福 |
page_configs | Allow public read | 任何人都可读取页面可见性设置 |
page_configs | Service role full access | 只有服务端 API 路由可以切换页面可见性 |
users | Service role full access | 只有服务端 API 路由可以读写用户记录 |
registration_codes | Allow public read | 客户端代码可在提交前校验注册码 |
registration_codes | Service role full access | 只有服务端 API 路由可以创建或标记注册码已使用 |
service_role 密钥绕过所有 RLS 策略,对整个数据库拥有不受限的访问权限。绝不要在浏览器代码中暴露它,也不要把它提交到仓库。Birthday Wall 只会在服务端 API 路由中使用这个密钥 — 它永远不会被发送到浏览器。
相对地,anon 密钥是有意公开的。它通过 NEXT_PUBLIC_ 前缀嵌入到你的前端包中,可以安全暴露 — 它能做什么、不能做什么由 RLS 策略来保障。
创建第一个管理员用户
建表完成后,你需要一个初始管理员账号来访问 /admin:
- 在 Supabase 仪表板中前往 Authentication → Users → Add user。
- 输入邮箱和强密码,然后点击 Create user。
- 复制用户列表中显示的 UUID。
- 打开 SQL Editor 并运行:
INSERT INTO users (id, email, role)
VALUES ('<paste-uuid-here>', 'your@email.com', 'admin');
或者,你也可以使用前面在 SQL 中插入的注册码,通过 /admin/login 界面进行注册 — 任何使用有效注册码创建的账号都会被自动赋予 admin 角色。