Cloud
Database
Postgres 15 database with automatically generated tables, RLS policies, and types. Full SQL, but without writing SQL.
Introduction
Every Master project has a dedicated Postgres instance in the EU region. You create tables by describing them in the chat.
Creating a table
prompt
Add a posts table:
- title (text)
- body (text)
- author_id (uuid → auth.users)
- published (boolean, default false)
- created_at (timestamp)sql
create table public.posts (
id uuid primary key default gen_random_uuid(),
title text not null,
body text not null,
author_id uuid not null references auth.users on delete cascade,
published boolean not null default false,
created_at timestamptz not null default now()
);
alter table public.posts enable row level security;Row-level security
sql
create policy "Authors can read own posts"
on public.posts for select
using (auth.uid() = author_id);
create policy "Public can read published"
on public.posts for select
using (published = true);Never store user roles in the
profiles table. Always use a separate user_roles with a security definer function has_role().Reading and writing
ts
import { supabase } from "@/integrations/supabase/client";
const { data, error } = await supabase
.from("posts")
.select("id, title, body, created_at")
.eq("published", true)
.order("created_at", { ascending: false })
.limit(20);Realtime
ts
const channel = supabase
.channel("posts-changes")
.on("postgres_changes", { event: "*", schema: "public", table: "posts" }, (payload) => {
console.log("Change:", payload);
})
.subscribe();Migrations and versions
Every schema change creates a new migration. Migrations are versioned, deterministic, and applied in order.
Tips and best practices
- Index foreign keys — Postgres je neindexuje automaticky.
- Use UUID as the primary key for public tables.
- Neselectuj
*— vyjmenuj sloupce. - Limit query — default limit is 1000 rows.
