Project Info
Inspiration
Both of us recognized that the United States is currently in a politically complex and pivotal moment. We saw an opportunity to make a meaningful impact by helping people better understand the flow of money in politics. In the U.S., Super PACs and PACs wield significant influence over the political landscape, often shaping outcomes behind the scenes.
What it does
Our website OpenPockets sifts through massive bulk data downloaded from the Federal Election Committee (FEC) to track, analyze, and visualize political campaign contributions. Our platform allows users to: Explore contributions by industry sectors like Pharmaceuticals, Military & Defense, Oil & Gas View detailed profiles of politicians with their funding sources Track industry influence across different senators and representatives Visualize financial relationships between corporations and politicians
How we built it
Lots and lots of struggling and revision. Back-end Developed a Node.js/Express server to handle API requests efficiently Used a SQLite database for fast querying Implemented data processing pipelines to transform raw FEC data into insights Created specialized endpoints for industry-specific and candidate-specific queries ### Front-end We used Figma to prototype and React, ChakraUI, and TypeScript for rapid development.
Challenges we ran into
The text files we dealt with were massive (as in gigabytes). Unfortunately, MongoDB ran out of storage after attempting to add our first table. After talking to teammates around us, we learned that SQLite is great for parsing relatively large data and decided to switch. This entailed MUCH faster queries. As of April, every government related API was shutting down or was already shut down perhaps due to recent government cuts. The OpenSecrets API was unavailable, OpenFEC had a limit of 40 calls/hour, congress.gov’s API was broken, Google Civic API was very limited and extremely slow and ProPublica's Congress API is no longer available. So we decided to just store and parse all the data ourselves with SQLite. The queries were extremely fast and understanding the syntax grew easier by the end We had never queried data so big before, or really queried in general. Our computer would crash if we even tried to open one of the .txt files We also are not political science majors so the jargon was tricky to understand.
Accomplishments we're proud of
We accomplished this much as a team of 2. Of the 4 APIs we planned to use, only one somewhat worked, and even then, we decided to scrap it and do it ourselves by downloading a bunch of campaign data and essentially making our own personalized api. We messed with a ton of technologies that we had no idea about: Model Context Protocol, SQLite databases
What we learned
Extreme improvisation: having all the API’s fail on us, and then deciding to just build it ourselves was a cool experience
What's next
for OpenPocket One of our biggest limiting factors was the deactivation of the OpenSecrets API, which is one of the biggest tools in tracking political finances. This API will come back new and improved soon, and it is a very potent tool for us to leverage to gain insight on political transactions. One of the biggest features we wanted to implement was a Gemini agent that worked off of a Model Context Protocol server connected to our database to answer any questions about a politician's financial integrity. We were successful in creating it, but not so much in integrating it into our front-end. We also created methods to see a politician's active industries and a list of their highest donating political action committees, but we weren’t to integrate it into our ui at the end.
OpenPockets
A React + TypeScript app with a Node/Express + SQLite backend that helps you explore U.S. politicians’ committees, corporate connections, and recent votes. It aggregates FEC committee data, corporate PAC links, and industry connections and presents them with a clean UI powered by Chakra UI.
Watch the Video here:
Inspiration
The United States is in a politically complex and pivotal moment. We wanted to make a meaningful impact by helping people better understand the flow of money in politics. Super PACs and PACs wield significant influence, often shaping outcomes behind the scenes. Open Pocket aims to surface those financial relationships in a transparent and navigable way. R
Features
- Politician profile with:
- Recent House vote info via Congress.gov API
- Affiliated committees and contribution totals
- Corporate connections grouped by industry
- Explore contributions by industry sectors (e.g., Pharmaceuticals, Military & Defense, Oil & Gas)
- Track industry influence across senators and representatives
- SQLite database (
src/services/politicaldata.db) seeded with FEC-derived tables
Tech Stack
- Frontend: React, TypeScript, Vite, Chakra UI
- Backend: Node.js (Express) in
src/server.js - Data/Services: Python utilities in
src/services/*.py, SQLite (politicaldata.db)
Getting Started
Prerequisites
- Node.js 18+ and npm
- Python 3.x
- SQLite (CLI optional but useful)
1) Install dependencies
npm install
2) Environment variables
Create .env or .env.local (Vite-compatible) in the project root:
VITE_CONGRESS_API_KEY=your_congress_gov_api_key
This key is used by the frontend to fetch vote details from Congress.gov.
3) Database
The app uses a SQLite database located at:
src/services/politicaldata.db
It contains tables for committees, candidate linkages, and optionally linkedin_companies.
Initialize/update schema (optional):
python src/services/initialize_db.py
4) Run the backend
node src/server.js
By default it serves the API on http://localhost:3001.
5) Run the frontend
npm run dev
Vite will start the app (typically on http://localhost:5173).
How We Built It
- Back-end
- Node.js/Express server for API endpoints and request handling
- SQLite for fast, local querying of large FEC-derived datasets
- Python data-processing scripts to transform raw FEC text files into queryable tables
- Candidate- and industry-specific endpoints to support the UI
- Front-end
- Figma for rapid prototyping
- React + TypeScript + Chakra UI for fast iteration and clean component design
- Keyword-based industry classifier to robustly categorize companies when third-party APIs are limited
Challenges
- Data scale: FEC text files are massive (gigabytes). Attempting to import to MongoDB quickly exhausted storage. SQLite proved significantly faster for parsing and querying locally.
- API instability/limits (as of April):
- OpenSecrets API unavailable
- OpenFEC rate-limited (≈40 calls/hour)
- Congress.gov unstable; ProPublica Congress API deprecated; Google Civic slow/limited
- We pivoted to downloading and parsing the data ourselves with SQLite, which yielded very fast queries once structured
- Learning curve: Working with very large datasets and unfamiliar political finance terminology
Accomplishments
- Built a full-stack system as a team of two, despite multiple API failures
- Switched to a self-hosted data pipeline (SQLite) and effectively made a tailored “internal API” for our needs
- Experimented with new tech: Model Context Protocol ideas, SQLite-based analytics, and robust data wrangling
What We Learned
- Extreme improvisation pays off: when external APIs failed, building our own pipeline with SQLite let us move forward quickly
- Practical strategies for handling large, messy public datasets and turning them into fast queries and usable UI
What’s Next for Open Pocket
- Reintegrate external data sources when they stabilize (e.g., the returning OpenSecrets API) to enhance scope and accuracy
- Ship an AI agent powered by a Model Context Protocol server connected to our database for natural-language Q&A about politicians’ finances
- Expand UI to include deeper “active industries” views and top-donating PACs per politician, integrated directly into the profile pages
Key Pages
src/pages/Politician.tsx– Main profile view with Committees, Industries, and Recent Votessrc/pages/IndustryDetail.tsx– Deeper dive for a specific industry
Data Flow (High-level)
- Frontend fetches politician details and UI sections from the backend API
- Backend calls Python helpers to read from
politicaldata.dband assemble committee and corporate-connection data - Industry grouping uses a keyword-based classifier to ensure every company gets a reasonable category even if LinkedIn data is sparse
API Endpoints (selected)
- GET
http://localhost:3001/api/congressman/:id- Returns the politician record used by
Politician.tsx
- Returns the politician record used by
- GET
http://localhost:3001/api/senator/:id/committees- Returns affiliated committees and summary stats
- GET
http://localhost:3001/api/senator/:id/industries- Returns companies grouped by industry; uses keyword-based classification as a fallback
- GET
http://localhost:3001/api/politician/:lastName/industries?firstName=Optional- Alternative industry view by name
Note: The frontend passes VITE_CONGRESS_API_KEY as x-api-key where required.
Troubleshooting
- Industries all show “Unknown”
- Ensure frontend classification is running: refresh and check browser console logs from
Politician.tsx - Verify the backend at http://localhost:3001 is running
- Confirm
VITE_CONGRESS_API_KEYis set for vote lookups (not required for industry classification but useful for the page)
- Ensure frontend classification is running: refresh and check browser console logs from
- DB file not found
- Confirm
src/services/politicaldata.dbexists; re-runpython src/services/initialize_db.pyif needed
- Confirm
Project Structure (partial)
src/
pages/
Politician.tsx
IndustryDetail.tsx
components/
RecentVoteInfo.tsx
ChatBot.tsx
CongressmanBanner.tsx
services/
server.js # Express API
*.py # Python helpers, DB utilities
politicaldata.db # SQLite database
License
MIT (or project-specific license if different).
Analysis
View
Metric
- 10
Figures cover GitHub contributors during the hackathon window. A co-authored commit counts in full for each author, so per-member totals add up to more than the whole-team figures.
Technology
- CSSIn code
- ExpressIn code
- HTMLIn code
- JavaScriptIn code
- MongoDBIn code
- PythonIn code
- ReactIn code
- TypeScriptIn code
- Google GeminiClaimed
- Node.jsClaimed
8 of 10 appear in the indexed code. 2 claimed on Devpost could not be matched to code, which may simply mean the tool leaves no trace in the repository.
AI coding agents
No AI coding agent signals were found in this repository.
Detected from committed agent config files and commit authorship. Absence of a signal is not proof an agent was unused.
Codebase size
Source size
110 KB
Source files
30
Counts recognized source files only; vendored directories, binaries and lockfiles are excluded, so this is smaller than the repository on disk.
Repository
riachx/open-pocket
53 files · 14.2 MB · @ 0424b02
Structure
Interface
9 files · 17%Screens, components and styles rendered to the user.
API & routing
1 file · 2%Request entry points: routes, handlers and controllers.
Application logic
18 files · 34%Domain rules, services and shared utilities.
Data & schema
1 file · 2%Schema definitions, migrations and data access.
Supporting
Layers are inferred from where files sit in the tree, not from reading the code. A project that names its directories unconventionally will read oddly here — open the file browser to check anything the diagram implies.
Languages
- TypeScript48%
- JavaScript25%
- Python19%
- Markdown6%
- CSS2%
- HTML1%
Share of indexed source by file size. Binary and vendored files are excluded.
Dependencies
package.json
npm · 31- @chakra-ui/icons
- @chakra-ui/react
- @emotion/react
- @emotion/styled
- @types/cors
- @types/react-router-dom
- axios
- cors
- dotenv
- express
- framer-motion
- mongoose
- react
- react-dom
- react-router-dom
- sqlite
- sqlite3
- +14 more
src/services/requirements.txt
pypi · 2- httpx
- python-dotenv
Declared in the repository’s manifests at the indexed commit. A declared package is not proof it is used, and runtime dependencies are listed first.
This project’s features have not been analysed yet.
Export this project's context (description, README, evidence, key source files) to chat with an AI agent elsewhere.
