Docs/Feature
// feature
Database (Supabase)
Il database è Postgres gestito da Supabase. Zero setup di server, niente ORM da imparare — usi il client Supabase e scrivi query in modo diretto. Row Level Security (RLS) attiva ti garantisce che ogni utente vede solo i suoi dati.
I due client
Come per l'auth, hai due helper: uno per il browser (Client Components), uno per il server (Server Components, route handler, Server Actions). Non mischiare mai i due — sono lì apposta per gestire i cookie di sessione nel modo giusto.
"use client";
import { createClient } from "@/libs/supabase/client";
const supabase = createClient();
const { data } = await supabase.from("posts").select("*");La tabella profiles
Il webhook Stripe assume che esista una tabella profiles con almeno queste colonne: id (UUID, foreign key a auth.users), email, customer_id, price_id, has_access (bool). La crei una volta sola nella SQL editor di Supabase:
create table profiles (
id uuid references auth.users on delete cascade primary key,
email text,
customer_id text,
price_id text,
has_access boolean default false,
created_at timestamptz default now()
);
alter table profiles enable row level security;
create policy "Un utente vede solo il proprio profilo"
on profiles for select
using (auth.uid() = id);Query lato server
In un Server Component leggi i dati dell'utente con la sessione già risolta dai cookie:
const supabase = await createClient();
const { data: { user } } = await supabase.auth.getUser();
const { data: profile } = await supabase
.from("profiles")
.select("has_access, price_id")
.eq("id", user.id)
.single();Grazie alle policy RLS, quella query ritorna solo la riga dell'utente loggato — anche se scrivi select * senza filtro, Postgres blocca l'accesso alle altre righe.