This guide walks you through setting up Supabase for the Leddger AI project from scratch.
- Create a Supabase Project
- Get Your API Keys
- Configure Environment Variables
- Run the SQL Schema
- Enable Google OAuth
- Enable Email/Password Auth
- Verify Setup
- Production Checklist
- Go to https://app.supabase.com
- Sign in (or create an account — free tier available)
- Click New Project
- Fill in:
- Name:
leddger-ai(or your preferred name) - Database Password: Choose a strong password (save it somewhere safe)
- Region: Choose the closest to your users
- Pricing Plan: Free (500MB database, 50K monthly active users)
- Name:
- Click Create new project
- Wait 2–3 minutes for provisioning to complete
- Go to your project dashboard
- Navigate to Settings → API
- You'll see three values:
| Value | Where to Use | Env Var |
|---|---|---|
| Project URL | Frontend + Backend | VITE_SUPABASE_URL (frontend), SUPABASE_URL (backend) |
| anon public key | Frontend only | VITE_SUPABASE_ANON_KEY |
| service_role secret key | Backend only | SUPABASE_SERVICE_ROLE_KEY |
⚠️ CRITICAL: Theservice_rolekey bypasses all Row Level Security. NEVER put it in frontend code, never commit it to git, and never expose it in browser network requests.
Create or update .env in the project root:
# Supabase (frontend — uses anon key, subject to RLS)
VITE_SUPABASE_URL=https://your-project-ref.supabase.co
VITE_SUPABASE_ANON_KEY=your-anon-public-key
# API server URL
VITE_API_URL=http://localhost:5000Create or update server/.env:
# Supabase (backend — uses service role key, bypasses RLS)
SUPABASE_URL=https://your-project-ref.supabase.co
SUPABASE_SERVICE_ROLE_KEY=your-service-role-secret-key
# MongoDB (for Spreadsheet storage)
MONGODB_URI=mongodb+srv://your-connection-string
# Server
PORT=5000
# Email (Gmail OAuth2 — for form submission notifications)
GOOGLE_CLIENT_ID=your-google-client-id
GOOGLE_CLIENT_SECRET=your-google-client-secret
GOOGLE_REFRESH_TOKEN=your-google-refresh-token
GOOGLE_EMAIL=your-email@gmail.comDelete these from server/.env if they exist:
# REMOVE THESE
FIREBASE_PROJECT_ID=...
FIREBASE_CLIENT_EMAIL=...
FIREBASE_PRIVATE_KEY=...This creates all tables, RLS policies, indexes, and the auto-profile trigger.
- Go to your Supabase Dashboard
- Navigate to SQL Editor
- Click New query
- Open the file
server/supabase_schema.sqlfrom your project - Copy the entire contents and paste into the SQL Editor
- Click Run
- You should see "Success. No rows returned." — this is normal for DDL statements
- Go to Table Editor in the sidebar
- You should see these tables:
profilesform_draftsform_submissionsmeetingsalertscandidates
- Go to Authentication → Policies
- Each table should show "RLS Enabled" with policies listed
- Go to Google Cloud Console
- Create or select a project (you can reuse the existing
leddger-aiFirebase project) - Go to APIs & Services → Credentials
- Click Create Credentials → OAuth client ID
- Choose Web application
- Set Authorized JavaScript origins:
http://localhost:5173 https://leddger-ai.netlify.app - Set Authorized redirect URIs:
https://your-project-ref.supabase.co/auth/v1/callbackReplace
your-project-refwith your actual Supabase project reference (found in Settings → API) - Click Create
- Copy the Client ID and Client Secret
- In Google Cloud Console, go to APIs & Services → Library
- Search for Google Calendar API
- Click Enable
- Go to Supabase Dashboard → Authentication → Providers
- Find Google and click to expand
- Toggle Enable Google
- Paste the Client ID and Client Secret from step 5.1
- Set the Redirect URL to:
https://your-project-ref.supabase.co/auth/v1/callback - Click Save
- Start your frontend:
npm run dev - Open
http://localhost:5173 - Click Sign In → Google OAuth
- You should be redirected to Google's consent page
- After consent, you'll be redirected back to the app as an authenticated user
- Go to Supabase Dashboard → Authentication → Providers
- Find Email and ensure it's Enabled (enabled by default)
- Optionally configure:
- Confirm email: On (requires SMTP setup) or Off (for development)
- Allow new signups: On
- Go to Authentication → Sign In / Up
- Under Email, turn OFF Confirm email
- This allows instant login without email verification
npm run buildShould complete with no errors.
cd server
node index.jsYou should see:
✅ Supabase Admin client initialized successfully via .env.
✅ Connected to MongoDB via Mongoose
🚀 Server running on port 5000 (bound to 0.0.0.0)
- Start both frontend and backend:
npm run dev - Sign in with Google or email/password
- Check Supabase Dashboard → Authentication → Users — your user should appear
- Check Table Editor →
profiles— a profile row should have been auto-created by the trigger
# Get your access token from the browser's localStorage (key: sb-<ref>-auth-token)
# Then test:
curl -H "Authorization: Bearer YOUR_TOKEN" http://localhost:5000/api/user/departments
# Should return: { "departments": [] }Before deploying to production:
- Supabase project created and SQL schema run
- Google OAuth configured with production redirect URIs
- Google Calendar API enabled in Google Cloud Console
-
.env(frontend) configured withVITE_SUPABASE_URLandVITE_SUPABASE_ANON_KEY -
server/.envconfigured withSUPABASE_URLandSUPABASE_SERVICE_ROLE_KEY -
server/.envconfigured withMONGODB_URI - All old Firebase env vars removed
-
firebaseandfirebase-adminpackages uninstalled -
src/firebaseAuth.jsdeleted (dead code) - Old Mongoose models (
User.js,FormDraft.js,FormSubmission.js) deleted - Email confirmation setting configured appropriately
- RLS policies verified in Supabase Dashboard
- Frontend build succeeds:
npm run build - Backend starts without errors:
cd server && node index.js - Google sign-in redirect works in production
- Test spreadsheet save/load/delete
- Test form draft creation and activation
- Double-check that
VITE_SUPABASE_URLandVITE_SUPABASE_ANON_KEYare correct in.env - Restart the Vite dev server after changing
.envfiles
- Ensure the redirect URI in Google Cloud Console exactly matches
https://your-project-ref.supabase.co/auth/v1/callback - Check that the redirect URI in Supabase Dashboard → Authentication → Providers → Google matches
- Ensure you're using the
service_rolekey (notanon) inserver/.env - Verify RLS policies are created by checking Authentication → Policies in Supabase Dashboard
- Verify the
handle_new_user()trigger was created by running the SQL schema - Check Database → Triggers in Supabase Dashboard
- Ensure
MONGODB_URIis set inserver/.env - Check network access / IP whitelist in MongoDB Atlas