Configuration

This project uses Supabase for the backend, which handles the database, authentication, etc.

Supabase (.env) Setup

Pre-Requirements: Have a Supabase account with a project. Otherwise, feel free to create a new project [here] before continuing.

In order for our boilerplate to have all the required environment variables, we need to set them up in the .env file. Please get the following values from Supabase: NEXT_PUBLIC_SUPABASE_URL, NEXT_PUBLIC_SUPABASE_ANON_KEY and PROTECTED_SUPABASE_SERVICE_ROLE_KEY.


Supabase Table Setup

Let’s now create all the required tables for this boilerplate to handle things such as user data, subscriptions, free trials, etc. - using the Supabase SQL Editor:


The SQL commands below are the ones that will be used to create the tables. You can also find the SQL commands in the createTables.sql file inside the codebase.

createTables.sql
CREATE TABLE
    users (
        id UUID PRIMARY KEY UNIQUE DEFAULT gen_random_uuid (),
        email TEXT NOT NULL,
        first_name TEXT,
        stripe_customer_id TEXT,
        profile_image_url TEXT,
        position TEXT,
        bio TEXT,
        auth_method TEXT NOT NULL CHECK (
            auth_method IN ('password', 'magicLink', 'google')
        ),
        onboarding_completed BOOLEAN NOT NULL DEFAULT FALSE,
        created_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
        updated_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP
    );
createTables.sql
CREATE TABLE
    user_subscriptions (
        id UUID PRIMARY KEY DEFAULT gen_random_uuid (),
        user_id UUID NOT NULL UNIQUE REFERENCES auth.users (id) ON DELETE CASCADE,
        stripe_subscription_id TEXT,
        stripe_price_id TEXT,
        status TEXT NOT NULL CHECK (
            status IN ('ACTIVE', 'TRIALING', 'CANCELLED', 'EXPIRED')
        ),
        subscription_tier TEXT NOT NULL CHECK (
            subscription_tier IN ('FREE', 'ESSENTIALS', 'FOUNDERS')
        ),
        billing_period TEXT CHECK (
            billing_period IN ('MONTHLY', 'YEARLY', 'LIFETIME')
        ),
        billing_plan TEXT CHECK (billing_plan IN ('RECURRING', 'ONE_TIME')),
        end_date TIMESTAMPTZ,
        created_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
        updated_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP
    );
createTables.sql
CREATE TABLE
    free_trials (
        id UUID PRIMARY KEY DEFAULT gen_random_uuid (),
        user_id UUID NOT NULL UNIQUE REFERENCES auth.users (id) ON DELETE CASCADE,
        stripe_subscription_id TEXT NOT NULL,
        subscription_tier TEXT NOT NULL CHECK (
            subscription_tier IN ('FREE', 'ESSENTIALS', 'FOUNDERS')
        ),
        status TEXT NOT NULL CHECK (
            status IN ('ACTIVE', 'CONVERTED', 'CANCELLED', 'EXPIRED')
        ),
        start_date TIMESTAMPTZ NOT NULL,
        end_date TIMESTAMPTZ NOT NULL,
        created_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
        updated_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP
    );