GovernancePulse

What Inspired Us

Local governments often promise roads, drainage, streetlights, and sanitation. Updates scatter across speeches, newsletters, and news. Citizens rarely have a single place to see what was pledged, what’s in progress, and what’s done.

We wanted a system where:

  • Every pledge is visible and traceable
  • Evidence can’t be changed or hidden
  • Citizens can vote on progress in a transparent way

GovernancePulse started as an experiment: combine AI, decentralized storage, and blockchain to turn messy, unstructured documents into clear, verifiable records of government commitments.


What We Learned

AI for Governance Content

Using Google Gemini to classify documents taught us how to work with governance language. Promises, progress reports, and irrelevant content need different handling. We designed prompts focused on infrastructure and public service, then iterated until the model reliably distinguished new pledges, updates, and unrelated content.

Blockchain Beyond Tokens

Blockchain here isn’t about tokens or speculation. It’s about immutability and transparency. Once a pledge or vote is recorded, it stays on the chain. That gives a permanent, auditable history that can’t be altered after the fact.

IPFS for Evidence

IPFS (via Pinata) gave us decentralized, content-addressed storage. Each document gets a CID: a hash-based identifier that guarantees the content. Anyone can check that the evidence hasn’t changed. This fits well with the idea of immutable proof for pledges.

MongoDB for Structured Pledge Data

We used MongoDB with Mongoose to store pledges, artifacts, trigger events, review rounds, and votes. We learned to design schemas that work with both Mongoose and the blockchain: MongoDB holds rich, queryable data (text, relations, metadata), while the chain stores hashes and IDs for verification. We also had to ensure only plain, serializable objects are passed from Server Components to Client Components—Mongoose documents and populated refs had to be mapped to plain objects with .lean() and explicit field selection to avoid serialization errors in Next.js.

Serverless and Real-Time UX

Building on Vercel meant dealing with read-only filesystems, cold starts, and dynamic rendering. We learned how to use /tmp for uploads, call connectDB() before any DB access, and make PDF parsing work in serverless. We also used Server-Sent Events for real-time pipeline updates instead of polling.

Core Components

  1. Artifact ingestion — A folder watcher process files from artifacts/incoming. Later, we plan to scrape local news and government sites by location.

  2. AI classification — Gemini 2.5 Flash classifies each document as NEW_PROMISE, PROMISE_UPDATE, or IRRELEVANT, and extracts promise text, category, and region.

  3. IPFS storage — Pinata stores each document on IPFS and returns a CID. Evidence links in the app point to these immutable references.

  4. Smart contract — A Solidity contract on Polygon Amoy records pledges, evidence, and review rounds. Citizens vote with castVote(); status is computed from votes and written with updateStatus().

  5. Vote-to-status logic — Final status comes from vote distribution. For a round with vote counts (v_0, v_1, v_2, v_3) (Not Visible, In Progress, Partially Done, Done), the winning option is:

[ \text{status} = \arg\max_{i \in {0,1,2,3}} v_i ]

Ties are broken by a fixed precedence (e.g., Done > Partially Done > In Progress).

Tech Stack

Layer Technology
Frontend Next.js 16, React 19, Tailwind CSS 4
Backend Next.js API Routes (serverless)
Database MongoDB, Mongoose
AI Google Gemini 2.5 Flash
Storage Pinata (IPFS)
Blockchain Polygon Amoy, Solidity, Viem

Challenges We Faced

1. PDF Parsing in Serverless

pdf-parse depends on pdfjs-dist, which expects canvas and DOM APIs. On Vercel, we saw DOMMatrix is not defined and @napi-rs/canvas missing. We solved this by:

  • Adding @napi-rs/canvas and listing it in serverExternalPackages
  • Dynamically importing pdf-parse only when handling PDFs
  • Providing clear errors if PDF parsing fails (e.g., suggest using .txt or .md)

2. Self-Referential Fetch on Vercel

The dashboard originally fetched data from the app’s own API (/api/promises, etc.). On Vercel, that meant requests to localhost:3000, which wasn’t available. We refactored to call the database directly in Server Components and removed the need for NEXT_PUBLIC_APP_URL.

3. Read-Only Filesystem on Vercel

artifacts/uploaded couldn’t be created because /var/task is read-only. We switched uploads to /tmp when VERCEL is set and made file moves a no-op in serverless, since /tmp is ephemeral.

4. Mongoose Buffering Timeout

The upload route used Mongoose models without calling connectDB() first. Mongoose buffered operations and eventually timed out. Adding connectDB() before any DB access fixed this.

5. Non-Serializable Props (Server → Client)

Populated Mongoose refs (e.g. sourceArtifact) and Set objects caused serialization errors when passed to Client Components. We fixed this by mapping results to plain objects and avoiding passing complex Mongoose documents or non-serializable types across the server–client boundary.

6. Hydration Mismatch from Browser Extensions

Extensions like Grammarly add attributes to <body>, which led to hydration mismatches. We used suppressHydrationWarning on html and body to avoid these false positives.


Vision for the Future

MVP today: Manual artifact upload for demo, AI classification, IPFS storage, blockchain records, and citizen voting.

Next: Automatic scraping from local newspapers and government sites based on the user’s selected location. The location selector will drive which sources are monitored and ingested.

Long term: Broader sources, RSS feeds, official press releases, and more real-time monitoring to make GovernancePulse a continuous, location-aware accountability layer for local government.


Conclusion

GovernancePulse shows how AI, decentralized storage, and blockchain can support civic accountability. Every pledge is traceable, every piece of evidence is immutable, and citizens can participate in tracking progress. We learned to work around serverless constraints, design reliable AI pipelines, and use blockchain for auditability rather than speculation. The result is a working platform at govpls.vercel.app that we’re ready to extend with automatic, location-based data ingestion.

Built With

Share this project:

Updates