Quickstart
Build your first feature with Supasheet in 5 minutes
Build Your First Admin Interface
Let's create a simple task management interface to demonstrate Supasheet's SQL-first approach.
Create a Migration
npx supabase migration new create_tasks_tableThis creates a new migration file in /supabase/migrations/.
Define Your Schema
Edit the migration file and add:
begin;
-- Step 1: Create custom types
create type task_status as enum ('pending', 'in_progress', 'completed');
create type task_priority as enum ('low', 'medium', 'high');
-- Step 2: Add permissions to the system
alter type supasheet.app_permission add value 'public.tasks:select';
alter type supasheet.app_permission add value 'public.tasks:insert';
alter type supasheet.app_permission add value 'public.tasks:update';
alter type supasheet.app_permission add value 'public.tasks:delete';
commit;
-- Step 3: Create tasks table
CREATE TABLE public.tasks (
id UUID PRIMARY KEY DEFAULT extensions.uuid_generate_v4(),
title TEXT NOT NULL,
description TEXT,
status task_status DEFAULT 'pending',
priority task_priority DEFAULT 'medium',
due_date TIMESTAMPTZ,
-- User association
account_id UUID REFERENCES supasheet.accounts(id) ON DELETE CASCADE,
-- Audit fields
created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP
);
-- Create indexes
create index idx_tasks_account_id on tasks (account_id);
create index idx_tasks_status on tasks (status);
-- Step 4: Enable Row Level Security with permission checks
ALTER TABLE public.tasks ENABLE ROW LEVEL SECURITY;
-- Revoke default permissions
revoke all on table tasks from authenticated, service_role;
-- Grant basic permissions
grant select, insert, update, delete on table tasks to authenticated;
-- Create RLS policies with permission checks
create policy tasks_select on tasks
for select
to authenticated
using (account_id = auth.uid() and supasheet.has_permission('public.tasks:select'));
create policy tasks_insert on tasks
for insert
to authenticated
with check (supasheet.has_permission('public.tasks:insert'));
create policy tasks_update on tasks
for update
to authenticated
using (account_id = auth.uid() and supasheet.has_permission('public.tasks:update'))
with check (account_id = auth.uid() and supasheet.has_permission('public.tasks:update'));
create policy tasks_delete on tasks
for delete
to authenticated
using (account_id = auth.uid() and supasheet.has_permission('public.tasks:delete'));
-- Step 5: Grant permissions to the 'user' role
insert into supasheet.role_permissions (role, permission) values
('user', 'public.tasks:select'),
('user', 'public.tasks:insert'),
('user', 'public.tasks:update'),
('user', 'public.tasks:delete');Apply the Migration
npx supabase db pushThis applies your migration to the local database without resetting existing data.
View Your Admin Interface
That's it! Supasheet automatically:
- ✅ Creates a CRUD interface at
/home/public/resource/tasks - ✅ Generates forms based on your schema
- ✅ Applies your RLS policies for security
- ✅ Handles pagination, filtering, and sorting
- ✅ Shows only the tasks the user created (via RLS)
Navigate to the Resources section in Supasheet and select "tasks" to see your new interface.