> ## Documentation Index
> Fetch the complete documentation index at: https://shipfast.so/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Database

> Set up Postgres with Supabase. Create tables, configure security, and start storing data.

## Steps

<Steps>
  <Step title="Create Tables">
    You have created and got the keys in [getting started](https://www.shipfast.so/docs/getting)

    Time to build your database. Go to **SQL Editor** in Supabase.

    ### Profiles Table

    Stores user info and subscription status:

    ```sql SQL Editor theme={null}
    -- Create profiles table
    CREATE TABLE public.profiles (
      id TEXT PRIMARY KEY,
      name TEXT,
      email TEXT UNIQUE NOT NULL,
      customer_id TEXT UNIQUE,
      price_id TEXT,
      has_access BOOLEAN DEFAULT false,
      created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
      updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
    );

    -- Enable security
    ALTER TABLE public.profiles ENABLE ROW LEVEL SECURITY;

    -- Speed up lookups
    CREATE INDEX idx_profiles_customer_id ON public.profiles(customer_id);
    CREATE INDEX idx_profiles_email ON public.profiles(email);
    ```

    Click **Run** ▶️

    ### Leads Table (optional)

    Only need this if you're collecting waitlist signups:

    ```sql SQL Editor theme={null}
    -- Create leads table
    CREATE TABLE public.leads (
      id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
      email TEXT UNIQUE NOT NULL,
      created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
    );

    -- Enable security
    ALTER TABLE public.leads ENABLE ROW LEVEL SECURITY;

    -- Speed up queries
    CREATE INDEX idx_leads_email ON public.leads(email);
    CREATE INDEX idx_leads_created_at ON public.leads(created_at DESC);
    ```

    Click **Run** ▶️

    <Warning>
      Don't skip Row Level Security (RLS) - it protects your data at the database level.
    </Warning>

    ### Stripe Events Table

    Prevents duplicate webhook processing when Stripe retries failed events. Stores event IDs to ensure idempotency - each event is processed exactly once.

    ```sql SQL Editor theme={null}
    create table stripe_events (
      id text primary key,
      type text not null,
      created_at timestamptz default now()
    );

    -- Enable security
    ALTER TABLE public.stripe_events ENABLE ROW LEVEL SECURITY;
    ```

    Click **Run** ▶️
  </Step>

  <Step title="Verify Everything Works">
    Quick check:

    1. Go to **Table Editor** in Supabase
    2. See `profiles` table? ✓
    3. See `leads` table (if you created it)? ✓
    4. Click each table to view columns

    <Check>
      All tables showing up? You're done! 🎉
    </Check>
  </Step>
</Steps>

***
