• Blog
  • Documentation
  • Courses
  • Changelog
  • AI Starters
  • UI Kit
  • FAQ
  • Supamode
    New
  • Pricing

Launch your next SaaS in record time with Makerkit, a React SaaS Boilerplate for Next.js and Supabase.

Makerkit is a product of Makerkit Pte Ltd (registered in the Republic of Singapore)Company Registration No: 202407149CFor support or inquiries, please contact us

About
  • FAQ
  • Contact
  • Verify your Discord
  • Consultation
  • Open Source
  • Become an Affiliate
Product
  • Documentation
  • Blog
  • Changelog
  • UI Blocks
  • Figma UI Kit
  • AI SaaS Starters
License
  • Activate License
  • Upgrade License
  • Invite Member
Legal
  • Terms of License
  • Global Configuration
    • Environment Variables
    • Feature Flags
  • Server Actions
    • Sending CSRF Token to Actions
    • Server Actions Error Handling
  • The Makerkit SDK
    • User SDK
    • Organization SDK
    • Organization Subscription SDK
    • Data Loader SDK
  • Architecture and Folder Structure
    • Structure your Application
    • Data Model
    • Introduction
    • Initial Setup
    • Running the App
    • Project Configuration
    • Environment Variables
    • Tailwind CSS and Styling
    • Authentication
    • Onboarding Flow
    • Database Schema
    • Supabase: Data Fetching
    • Supabase: Data Writing
    • Routing
    • Building the Tasks page
    • Building the Task Detail page
    • API Routes
    • Application Pages
    • API Routes Validation
    • Translations
    • Functions you need to know
    • Adding pages to the Marketing Site
    • Deploying to Production
    • Updating to the latest version
This documentation is for a legacy version of Next.js and Supabase. For the latest version, please visit the Next.js and Supabase V2 documentation

Database Schema | Next.js Supabase SaaS Kit

Learn how to get started developing new features from the database schema in your Makerkit Next.js Supabase project.

Before writing the React Components, we want to tackle the task of fetching data from Supabase.

This involves a couple of steps:

  1. We need to define, on paper, what the data model of the Supabase tables looks like
  2. We need to update the SQL schema of the database to match the data model and write the required RLS policies to secure the data
  3. We need to write the hooks to fetch data from Supabase

Learning about RLS

Learning RLS is fundamental to understanding how to secure data in Supabase. The best resource (other than checking Makerkit's code) is the Supabase RLS docs.

Please check it out - and if you have any questions, please ask in the Makerkit Discord.

How is the data structured?

We can place tasks as our own Postgres table tasks. Let's create an SQL table that defines the following columns:

sql
create table tasks (
id bigint generated always as identity primary key,
organization_id bigint not null references public.organizations,
name text not null,
description text,
done bool not null,
due_date timestamptz not null
);

Because tasks belong to an organization, we need to ensure that only users of that organization can read and write those tasks by adding a foreign key to each task named organization_id.

Replicating the tasks table as a Type

We can define a Task model at src/lib/tasks/types/task.ts:

lib/tasks/types/task.ts
export interface Task {
id: number;
name: string;
organizationId: string;
dueDate: string;
done: boolean;
description: string | null;
}

NB: this may not be necessary if you generate the types from the SQL schema. Up to you.

How do we protect the data with RLS?

We can add an RLS policy to the tasks table to ensure that only users of the same organization can read and write tasks.

We know that a user belongs to an organization using the memberships table.

The memberships table has two foreign keys: user_id and organization_id: we can use these foreign keys to ensure that only users of the same organization can read and write tasks.

First, we enable RLS on the tasks table:

sql
alter table tasks enable row level security;

Then, we can add a policy to the tasks table:

sql
create policy "Tasks can be read by users of the organizations to which it belongs" on tasks
for all
using (
exists (
select
1
from
memberships
where
user_id = auth.uid () and
tasks.organization_id = memberships.organization_id
)
);

Generating the types from the SQL schema

We can generate the types from the SQL schema using the Supabase CLI.

To run this command, you need to ensure Supabase is running locally using npm run supabase:start.

You can generate the types by running the following command:

bash
npm run typegen

The types will be generated at src/database-types.ts.

We will import the types whenever we use the Supabase client to ensure that it is typed correctly, which helps us write type-safe queries with the Supabase client.

For example:

tsx
import type { SupabaseClient } from '@supabase/supabase-js';
import type { Database } from '../../database.types';
type Client = SupabaseClient<Database>;