Open Source Campaign Infrastructure
Automate ballot signature recognition and validation. Put powerful organizing tools in the hands of grassroots campaigns. Democracy should be accessible to everyone.
- Signature Validation: High-accuracy signature triaging using multimodal LLMs integrated with voter files
- Grassroots Focused: Built for community organizers and campaigns that need powerful tools without the high costs
- Open Source: Transparent, community-driven technology that strengthens democratic participation
- PDF Processing: OCR capabilities for processing petition documents
- Fuzzy Matching: Advanced name and address matching algorithms
- Campaign Management: Multi-campaign support with user isolation
- Frontend: Next.js 15, React 19, TypeScript, Tailwind CSS
- Backend: Supabase (PostgreSQL, Auth, Storage, Edge Functions)
- AI/ML: OpenAI, Mistral, Gemini API integration
- PDF Processing: PDF.js for client-side PDF handling
- UI Components: Radix UI, Lucide React icons
Before deploying VoteCatcher, ensure you have:
- Node.js 18+ installed
- Supabase CLI installed
- API keys for AI providers (OpenAI, Mistral, or Gemini)
The key objectives of this guide are to:
- Clone and set-up the VoteCatcher project
- Create and connect to the Supabase project
- Configure and run the Votecatcher application locally or deploy to the web.
This guide assumes you are using a Unix-like operating system (e.g. Linux, macOS). For Windows, make adjustments as necessary.
- Clone the repository to your local machine:
git clone https://github.com/civictechdc/votecatcher- Open your terminal and navigate to the cloned project directory:
cd votecatcher- Install project dependencies
npm installQuick setup run the setupSupabase.sh script
supabase login YOUR_SUPABASE_ACCESS_TOKEN
chmod +x setupSupabase.sh
./setupSupabase.sh- Sign in or create an account at supabase.com
- Create a new project or select an existing one.
- Locate your API key and project URL in the project dashboard under Project Overview. (You will need both for configuration.)
- Log in to Supabase using the API key:
supabase login YOUR_SUPABASE_ACCESS_TOKEN-
Open your terminal or file browser and navigate to the supabase directory in your cloned project.
-
Confirm the following numbered SQL migration files are in the
supabasedirectory: -
Run DB migrations. Enter the DB password when prompted
supabase db push4. Deploy Edge Functions
- Deploy the Edge Functions:
supabase functions deploy process-voter-file-
Select the desired project when prompted in the terminal.
-
Verify the edge function is deployed successfully by checking the list of functions:
supabase functions listThis should return a table with a STATUS column indicating the functions are deployed and active.
- In your terminal, navigate to the root project folder.
- Copy and rename the example
.env.localfile with either off the following commands:
cp .env.example.local .env.local- Open
.env.localand fill in the required environment variables with the values collected in section 2. Supabase Setup:
# Required for Supabase
NEXT_PUBLIC_SUPABASE_URL=https://<project-id>.supabase.co
NEXT_PUBLIC_SUPABASE_ANON_KEY=<public anon key>
# Required for encryption. Generate a secure 32-character hex string
ENCRYPTION_KEY=0123456789abcdef0123456789abcdefNote: Environment variables with working defaults not shown. Open the .env.local file to view and modify as needed.
- Save and close the
.env.localfile.
The application automatically creates these storage buckets:
petitions- For petition PDF filesvoter-files- For voter registration CSV files
Verify these buckets exist in your Supabase project under: Storage > All Buckets.
- In your terminal, navigate to the project root directory.
- Start the development server:
npm run dev- Open your web browser and go to http://localhost:3000 to see the application.
- Push your code to GitHub
- Connect your repository to Vercel
- Add environment variables in Vercel dashboard
- Deploy
- Build the application:
npm run build- Start production server:
npm startVoteCatcher uses Supabase Auth. Configure authentication providers in your Supabase dashboard:
- Go to Authentication > Settings
- Configure your preferred providers (Email, Google, etc.)
All tables have RLS enabled with policies that ensure:
- Users can only access data from campaigns they own
- Proper data isolation between campaigns
- Secure API key management
- No service role access - all operations use user authentication
Users can store their own API keys for AI providers:
- OpenAI API Key
- Mistral API Key
- Gemini API Key
Keys are encrypted and stored securely with user-level access control.
votecatcher/
βββ app/ # Next.js App Router
β βββ api/ # API routes
β βββ auth/ # Authentication pages
β βββ workspace/ # Main application workspace
β βββ globals.css # Global styles
βββ components/ # Reusable UI components
β βββ ui/ # Radix UI components
βββ lib/ # Utility libraries
β βββ supabase/ # Supabase client configuration
β βββ encryption.ts # Encryption utilities
β βββ hooks/ # Custom React hooks
βββ supabase/ # Database and functions
β βββ functions/ # Edge functions
β βββ *.sql # Database schemas
βββ types/ # TypeScript type definitions
- Row Level Security: All data is protected by RLS policies
- Encrypted API Keys: User API keys are encrypted at rest
- User Isolation: Campaigns are isolated by user ownership
- Secure File Upload: Files are stored in private buckets with access controls
- User-Based Authentication: All API operations use authenticated user context
- No Service Role Access: Eliminated service role key dependency for enhanced security
This project is open source. See LICENSE for details.