Skip to main content
Use this checklist to stand up a new environment (a development project, or a fresh production project). Keep values out of git: the API reads them from environment variables, the Workers from secrets.
1

Create the project and collect its settings

From Project settings → API you need the project URL, the anon key, the service-role key and the JWT secret. They map to SUPABASE_URL, SUPABASE_ANON_KEY, SUPABASE_SERVICE_ROLE_KEY and JWT_SECRET (see Local setup).
The service-role key bypasses row-level security. It belongs only in the API’s environment, never in the arena, the admin panel or any repository.
2

Configure Auth

  • Enable Email (with confirmation) and Google.
  • Add the redirect URLs for the arena (https://arena.dualmindlab.tech/auth-callback.html and your localhost equivalent) and the admin panel.
  • Keep the project on the HS256 JWT secret, or update the API to validate with JWKS before you switch signing keys (see Authentication).
3

Create the tables

The most reliable way is to copy the schema from an existing environment with the Supabase CLI, for example supabase db dump --schema public > schema.sql against the source project, then apply it to the new project. Keep that file out of the docs repositories.If you build the tables by hand, create users, ai_models, providers, provider_api_keys, comparisons, model_votes, threads, thread_messages, system_settings, telegram_sessions and model_leaderboard with the columns in Database schema. Then add:
  • a unique constraint on model_votes (comparison_id, user_id),
  • foreign keys from comparisons, model_votes, threads and thread_messages to their parents,
  • defaults: users.role = 'user', threads.visibility = 'private', ai_models.status = 'active', model_leaderboard.elo_score = 1000.
4

Create the views and the ELO function

Create calculate_elo_update, v_leaderboard and v_comparisons_masked as described in Voting and ELO. Copy the current definitions from the production project’s SQL editor rather than writing them from scratch, so environments don’t drift.
5

Seed reference data

  • providers: groq, google, cloudflare (enabled).
  • ai_models: at least two active Groq or Google models, so random battles work.
  • model_leaderboard: one row per model you want on the leaderboard.
  • system_settings: public_sharing set to on if shared links should work without signing in.
6

Create the storage bucket

Create the avatars bucket in Storage for arena profile pictures.
7

Deploy the Edge Functions

send-admin-email (admin panel email) and email-wel-safe (arena welcome email). Their source isn’t in the application repositories; copy them from the production project.
8

Create the first admin

Sign up in the arena, then create a thread, run a battle or chat so UserSyncService creates your row in public.users. Set role = 'admin' on that row from the table editor. From then on, promote others from the admin panel.

Check it

In September 2026 the API’s SupabaseService was fixed to send the apikey and Authorization headers itself, instead of relying on how its HttpClient was registered. If PostgREST calls return 401 with “No API key found”, check that SUPABASE_SERVICE_ROLE_KEY (or SUPABASE_SERVICE_KEY) is set.
Last modified on October 18, 2026