跳转到主要内容

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、并找到需要写入环境变量的凭据。
1

创建一个 Supabase 项目

  1. 前往 supabase.com 并登录(或免费注册账号)。
  2. 在组织面板中点击 New project
  3. 给项目起名(如 birthday-wall),选择数据库密码,并选择离用户最近的区域。
  4. 点击 Create new project 并等待项目创建完成 — 通常大约 30 秒。
2

运行数据库迁移

所有所需的数据表都由一份 SQL 脚本一次性创建。在你的 Supabase 项目中:
  1. 点击左侧栏的 SQL Editor
  2. 点击 New query
  3. 粘贴下面的完整迁移脚本,然后点击 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 中看到全部四张表 — messagespage_configsusersregistration_codes
3

获取 API 凭据

Next.js 应用需要从 Supabase 获取三个值。请在 Supabase 仪表板中进入 Project Settings → API
凭据在哪里找到用于
Project URL”Project URL” 字段NEXT_PUBLIC_SUPABASE_URL
anon / public key”Project API keys” → anon publicNEXT_PUBLIC_SUPABASE_ANON_KEY
service_role key”Project API keys” → service_role(点击显示)SUPABASE_SERVICE_ROLE_KEY
把三个值都复制下来 — 下一步会用到。
4

把凭据添加为环境变量

将三个 Supabase 值添加到你的环境中。完整的必填变量清单和一份可直接粘贴的 .env.local 模板,见 环境变量页面

行级安全(Row Level Security)

迁移 SQL 会自动在所有表上启用行级安全(RLS)策略。每条策略的作用如下:
策略效果
messagesAllow public read任何人都可读取在首页展示的祝福
messagesService role full access只有服务端 API 路由可以插入或删除祝福
page_configsAllow public read任何人都可读取页面可见性设置
page_configsService role full access只有服务端 API 路由可以切换页面可见性
usersService role full access只有服务端 API 路由可以读写用户记录
registration_codesAllow public read客户端代码可在提交前校验注册码
registration_codesService role full access只有服务端 API 路由可以创建或标记注册码已使用
service_role 密钥绕过所有 RLS 策略,对整个数据库拥有不受限的访问权限。绝不要在浏览器代码中暴露它,也不要把它提交到仓库。Birthday Wall 只会在服务端 API 路由中使用这个密钥 — 它永远不会被发送到浏览器。
相对地,anon 密钥是有意公开的。它通过 NEXT_PUBLIC_ 前缀嵌入到你的前端包中,可以安全暴露 — 它能做什么、不能做什么由 RLS 策略来保障。

创建第一个管理员用户

建表完成后,你需要一个初始管理员账号来访问 /admin
  1. 在 Supabase 仪表板中前往 Authentication → Users → Add user
  2. 输入邮箱和强密码,然后点击 Create user
  3. 复制用户列表中显示的 UUID。
  4. 打开 SQL Editor 并运行:
INSERT INTO users (id, email, role)
VALUES ('<paste-uuid-here>', 'your@email.com', 'admin');
或者,你也可以使用前面在 SQL 中插入的注册码,通过 /admin/login 界面进行注册 — 任何使用有效注册码创建的账号都会被自动赋予 admin 角色。