Marvin-Gregorio
🚀

quorum

BuildingProvenOpen SourceOther

Self-service election platform built with Next.js and Supabase. Create a private ballot in minutes: Google/Microsoft sig

Visit siteBeta

README

Quorum — voting system

A Next.js app (App Router) backed by Supabase (Postgres + Auth + Storage + Realtime) for running org-wide elections: positions, candidates, domain-gated private elections, live results, and RLS-enforced ballot secrecy.

See AGENTS.md for the full architecture and code conventions this project follows (RLS-first authorization, Server Actions, Tailwind usage, etc.) — read it before opening a PR.

Requirements

  • Node.js >= 22 (enforced via package.json's engines field). @supabase/supabase-js's realtime client specifically depends on APIs only available from Node 22 onward, which is what the test suites (test:rls, test:e2e) need it for. If node -v reports something older, install Node 22+ (e.g. via nvm or Homebrew).
  • The Supabase CLI (npx supabase, no separate install needed) and Docker, for running a local Supabase stack.

Setup

  1. Clone the repo and install dependencies:

    npm install
    
  2. Copy the environment example file and fill in your Supabase project's credentials:

    cp .env.local.example .env.local
    

    NEXT_PUBLIC_SUPABASE_URL and NEXT_PUBLIC_SUPABASE_ANON_KEY come from your Supabase project settings (or from npx supabase status if you're running the stack locally — see below).

  3. Sign-in is OAuth-only (Google and Microsoft) — there's no password login, so you need your own OAuth app credentials even for local development:

    • Google: create an OAuth client in the Google Cloud Console, then set GOOGLE_CLIENT_ID/GOOGLE_SECRET in .env.local.
    • Microsoft: register an app in Azure AD, then set AZURE_CLIENT_ID/AZURE_SECRET in .env.local.

    Both are read by supabase/config.toml's [auth.external.google]/ [auth.external.azure] blocks automatically — no other config needed. The redirect URI to register with each provider is http://localhost:54321/auth/v1/callback for local development (Supabase Auth's own callback, not the app's /auth/callback route).

  4. Run a local Supabase stack (recommended for development), or link to a hosted project instead:

    npx supabase start
    

    This starts Postgres, Auth, Storage, and Realtime locally via Docker and prints the local API URL and keys to use in .env.local. Alternatively, run npx supabase link to point at a hosted Supabase project.

  5. Apply database migrations:

    npx supabase migration up --local
    

    (Drop --local if you're migrating a linked hosted project instead.)

  6. Start the dev server:

    npm run dev
    

    Open http://localhost:3000.

Rate limiting on election creation, voting, and public results polling uses Upstash Redis — optional for local development (it no-ops without credentials) but required in production. Set UPSTASH_REDIS_REST_URL/UPSTASH_REDIS_REST_TOKEN in .env.local if you want to exercise it locally.

Tests

  • npm run test:unit — unit tests (tests/unit), no external services required.
  • npm run test:rls — RLS/integration tests (tests/rls) against a real local Supabase stack. Just run npx supabase start first — the env vars these tests need (SUPABASE_URL, SUPABASE_ANON_KEY, SUPABASE_SERVICE_ROLE_KEY) are populated automatically from supabase status by tests/rls/global-setup.ts, no manual setup required. Needs Node >= 22 (see Requirements above).
  • npm run test:e2e — Playwright end-to-end tests (tests/e2e). Also needs a running local Supabase stack and Node >= 22.

Before opening a PR

Run the same checks CI runs (.github/workflows/ci.yml):

npm run lint
npm run test:unit
npm run test:rls
npm run build

See CONTRIBUTING.md for the full contribution process.

Releases

Versioning is managed with Changesets and is on-demand, not automatic: a bot keeps a "Version Packages" PR up to date on main as changesets accumulate, and merging that PR is the one manual step that cuts a release — a git tag and GitHub Release are then created automatically (.github/workflows/release.yml).

Journey

Building a dev tool or hiring developers? Get seen here. Become our Sponsor

Stays free because of
  • John Cyrill Corsanes
  • rodge-dev
  • RCastromero()
  • Doctor Scoliosis
  • Michael William Mesina
  • King Salomon
  • John Javier R. Idmilao
  • Blairwitchii
  • wacxv
  • Benson
  • <JRJDev>
  • </Peter> "21st Dev Vinci"
  • Lixter Niño D. Dinawanao
  • Mon Albert Gamil
  • Ian de Jesus
  • JB Benedicto
  • euphydev
  • Lewis John Villamor
  • Ruri
  • Nico Alumbro
  • Denmark Crisostomo
  • Joowd
  • UrAvgProgrammer
  • DXT303
  • Kaihzan-Nixxo Jamilla
  • exciar
  • Carlo Dandan
  • John Cyrill Corsanes
  • rodge-dev
  • RCastromero()
  • Doctor Scoliosis
  • Michael William Mesina
  • King Salomon
  • John Javier R. Idmilao
  • Blairwitchii
  • wacxv
  • Benson
  • <JRJDev>
  • </Peter> "21st Dev Vinci"
  • Lixter Niño D. Dinawanao
  • Mon Albert Gamil
  • Ian de Jesus
  • JB Benedicto
  • euphydev
  • Lewis John Villamor
  • Ruri
  • Nico Alumbro
  • Denmark Crisostomo
  • Joowd
  • UrAvgProgrammer
  • DXT303
  • Kaihzan-Nixxo Jamilla
  • exciar
  • Carlo Dandan
Join them

Oct 12, 2026

Hello everyone. I'm building an open-source apache 2.0 licensed election system with Supabase. My goal is to test how to integrate SSO in the web app.

Building a dev tool or hiring developers? Get seen here. Become our Sponsor

Stays free because of
  • Joowd
  • Lixter Niño D. Dinawanao
  • John Javier R. Idmilao
  • </Peter> "21st Dev Vinci"
  • Doctor Scoliosis
  • rodge-dev
  • Michael William Mesina
  • Lewis John Villamor
  • Carlo Dandan
  • Nico Alumbro
  • Benson
  • Denmark Crisostomo
  • Ruri
  • Blairwitchii
  • King Salomon
  • exciar
  • <JRJDev>
  • UrAvgProgrammer
  • JB Benedicto
  • euphydev
  • Kaihzan-Nixxo Jamilla
  • DXT303
  • wacxv
  • Mon Albert Gamil
  • John Cyrill Corsanes
  • RCastromero()
  • Ian de Jesus
  • Joowd
  • Lixter Niño D. Dinawanao
  • John Javier R. Idmilao
  • </Peter> "21st Dev Vinci"
  • Doctor Scoliosis
  • rodge-dev
  • Michael William Mesina
  • Lewis John Villamor
  • Carlo Dandan
  • Nico Alumbro
  • Benson
  • Denmark Crisostomo
  • Ruri
  • Blairwitchii
  • King Salomon
  • exciar
  • <JRJDev>
  • UrAvgProgrammer
  • JB Benedicto
  • euphydev
  • Kaihzan-Nixxo Jamilla
  • DXT303
  • wacxv
  • Mon Albert Gamil
  • John Cyrill Corsanes
  • RCastromero()
  • Ian de Jesus
Join them