全书目录

第四十八篇:Supabase 完全指南 —— 开源数据港口宇宙

第十三章:一个最小完整示例 —— 开一座“项目协作码头”

1 分钟 144 字 第 900 / 962 个阅读单元

把前面几块能力串起来。

#需求

  • 用户注册登录
  • 每个人只能看到自己的项目
  • 附件上传到仓库
  • 项目变化实时刷新
  • 某些管理逻辑走 Edge Functions

#表结构与 RLS

sql
create table public.projects (
  id uuid primary key default gen_random_uuid(),
  owner_id uuid not null references auth.users(id) on delete cascade,
  name text not null,
  status text not null default 'draft',
  created_at timestamptz not null default now()
);

alter table public.projects enable row level security;

create policy "Own projects only"
on public.projects
for all
to authenticated
using ((select auth.uid()) = owner_id)
with check ((select auth.uid()) = owner_id);

#前端读写

ts
import { createClient } from "@supabase/supabase-js";

const supabase = createClient(
  process.env.NEXT_PUBLIC_SUPABASE_URL!,
  process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!
);

export async function createProject(name: string, ownerId: string) {
  const { data, error } = await supabase
    .from("projects")
    .insert({ name, owner_id: ownerId })
    .select()
    .single();

  if (error) throw error;
  return data;
}

export async function listProjects() {
  const { data, error } = await supabase
    .from("projects")
    .select("*")
    .order("created_at", { ascending: false });

  if (error) throw error;
  return data;
}

#Realtime 监听

ts
export function watchProjects() {
  return supabase
    .channel("projects-room")
    .on(
      "postgres_changes",
      { event: "*", schema: "public", table: "projects" },
      (payload) => console.log("变化:", payload)
    )
    .subscribe();
}

#Storage 上传

ts
export async function uploadProjectFile(file: File, userId: string) {
  const path = `${userId}/${Date.now()}-${file.name}`;
  const { data, error } = await supabase.storage
    .from("project-files")
    .upload(path, file);

  if (error) throw error;
  return data?.path;
}

整个业务流可以记成:

text
用户通过海关登录
   ↓
前端通过标准码头口读写 projects
   ↓
RLS 只放行自己的货物
   ↓
大文件进港口仓库
   ↓
表变更通过航运广播推送
   ↓
特殊调度逻辑走 Edge Functions

这就是 Supabase 的典型顺滑路径。