Skip to main content

Database Schema

The schema is defined in supabase/schema.sql. Run it once in the Supabase SQL editor when setting up a new project.

Tables

public.users

Extends Supabase's built-in auth.users with a public profile row. Created automatically by a trigger when a user registers.

ColumnTypeDescription
idUUID (PK)References auth.users.id. Cascade deletes.
emailTEXTUser's email address
registration_timestampBIGINTUnix timestamp (ms) of registration
created_atTIMESTAMPTZRow creation time
updated_atTIMESTAMPTZLast update time

public.login_events

Append-only log of every successful login.

ColumnTypeDescription
idUUID (PK)Auto-generated
user_idUUIDReferences auth.users.id. Cascade deletes.
timestampBIGINTUnix timestamp (ms) of the login
created_atTIMESTAMPTZRow creation time

Row Level Security

Both tables have RLS enabled. Users can only read and write their own rows.

TablePolicyRule
usersView own profileauth.uid() = id
usersUpdate own profileauth.uid() = id
usersInsert own profileauth.uid() = id
login_eventsView own eventsauth.uid() = user_id
login_eventsInsert own eventsauth.uid() = user_id

Functions

handle_new_user()

A trigger function that automatically creates a public.users row when a new user is created in auth.users.

CREATE TRIGGER on_auth_user_created
AFTER INSERT ON auth.users
FOR EACH ROW EXECUTE FUNCTION public.handle_new_user();

get_user_count()INTEGER

Returns the total number of registered users. Callable by anonymous and authenticated roles. Used by setupLiveMetrics() in supabase-auth.js for real-time metrics subscriptions.

get_login_events_count()INTEGER

Returns the total number of login events recorded. Used alongside get_user_count() for platform metrics.

Running the Schema

In the Supabase dashboard:

  1. Go to SQL Editor
  2. Paste the contents of supabase/schema.sql
  3. Click Run

Re-running is safe — all CREATE TABLE and CREATE POLICY statements use IF NOT EXISTS or CREATE OR REPLACE.