Skip to content

AmrishS2004/CivicPulse

Folders and files

NameName
Last commit message
Last commit date

Latest commit

ย 

History

14 Commits
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 

Repository files navigation

๐Ÿ›๏ธ CivicPulse

AI-Powered Civic Intelligence Platform

Where government policy meets citizen voice โ€” AI bridges the gap, understands both sides, and delivers an informed decision.


Node.js Claude AI InsForge TinyFish Railway License: MIT


๐Ÿš€ Live Demo ยท โ–ถ๏ธ Watch on YouTube ยท ๐Ÿ“– Docs ยท ๐Ÿ› Issues



๐ŸŽฌ Demo Video

CivicPulse Demo

โ–ถ๏ธ Watch the full walkthrough on YouTube

See the complete flow โ€” from posting a government survey and uploading a policy PDF, to citizens submitting opinions and the AI generating a full decision report in real time.


๐Ÿ’ก To display images: Add your screenshots to a screenshots/ folder in the repo and uncomment the <img> tags below.

Landing Page ๐Ÿ  1. Landing Page
The entry point of CivicPulse โ€” choose between the Government Portal (dark) or Citizen Portal (light) to get started
Government Portal Login ๐Ÿ” 2. Government Portal Login
Secure, pre-authorised officer authentication โ€” no public registration allowed; credentials are configured by the system administrator
Gov Portal - Post Survey Tab ๐Ÿ“‹ 3. Government Portal โ€” Post Survey
Officers write a policy question, optionally upload a supporting PDF/DOCX, and set the minimum citizen response target before publishing
Gov Portal - My Surveys Tab ๐Ÿ“‚ 4. Government Portal โ€” My Surveys
Dashboard showing all published surveys with live response counts and completion status โ€” empty state before any surveys are posted
Gov Portal - Service Connections ๐Ÿ”— 5. Government Portal โ€” Service Connections
Real-time health status of all integrated services โ€” Claude AI, InsForge Database, TinyFish Research, and the CivicPulse server, all confirmed online
Citizen Portal Sign In ๐Ÿ—ณ๏ธ 6. Citizen Portal โ€” Sign In
Citizens sign in with their registered username and password to access and respond to open government surveys
Citizen Portal - Create Account โœ๏ธ 7. Citizen Portal โ€” Create Account
New citizens register with a unique username and password (min. 6 characters) โ€” passwords are bcrypt-hashed before storage
Citizen Portal - No Surveys Yet ๐Ÿ” 8. Citizen Portal โ€” Awaiting Government Posts
The citizen dashboard before any surveys are published โ€” surveys appear here automatically once a government officer posts one
Gov Portal - Survey with PDF Uploaded ๐Ÿ“„ 9. Government Portal โ€” Survey with PDF Attached
A policy question filled in and a PDF uploaded (7k characters extracted) โ€” AI will read the document to deeply understand government intent before analysis
Gov Portal - Survey Published, Collecting Opinions ๐Ÿ“ก 10. Government Portal โ€” Survey Published & Collecting Opinions
The survey is now live with 1 post recorded; the system waits for the target number of citizen responses before auto-triggering AI analysis
Citizen Portal - Active Survey Available ๐Ÿ’ฌ 11. Citizen Portal โ€” Active Survey Ready for Response
The government's published survey appears in the citizen dashboard; citizens write their opinion in free text โ€” AI understands the full reasoning, not just keywords
Gov Portal - Run Analysis Button โšก 12. Government Portal โ€” Target Reached, Run Analysis
Once the minimum response target is met (2/2 here), the "Run Analysis with N Responses Now" button appears โ€” government can trigger the AI pipeline on demand
InsForge - cp_surveys table ๐Ÿ—„๏ธ 13. InsForge DB โ€” cp_surveys Table
The government-posted survey persisted in InsForge cloud database, showing the survey ID, question text, author (Amrish), response target, and attached policy document JSON
InsForge - cp_users table ๐Ÿ‘ค 14. InsForge DB โ€” cp_users Table (Citizen Accounts)
Registered citizen accounts stored in InsForge โ€” passwords are securely bcrypt-hashed ($2a$10$...) and never stored in plain text
InsForge - cp_responses table ๐Ÿ“ 15. InsForge DB โ€” cp_responses Table (Citizen Answers)
Each citizen's free-text response stored with their username, linked survey ID, and submission timestamp โ€” this raw data feeds directly into the AI analysis pipeline
InsForge - cp_analysis table ๐Ÿ’พ 16. InsForge DB โ€” cp_analysis Table (AI Output Persisted)
The full AI decision report saved as 20 chunked string columns in InsForge โ€” ensuring the analysis survives server restarts and remains accessible at any time
Gov Portal - AI Decision Report Gov Portal - AI Decision Report Gov Portal - AI Decision Report ๐Ÿ† 17. Government Portal โ€” Live AI Decision Report
The complete AI-generated decision report displayed in the Government Portal: citizen sentiment bar (50% support / 50% neutral), win-win solution, recommended course of action, key statistics, urgency level, confidence score, and a "View Full Report" button โ€” all deployed live at civicpulse-production.up.railway.app

๐Ÿ“Œ What is CivicPulse?

CivicPulse is a full-stack civic engagement platform that connects government officers with citizens in real time. Governments post policy surveys, citizens respond in free text, and an AI pipeline analyses the data โ€” understanding government intent, citizen emotions, conflicts, and proposing win-win solutions.

โœจ Key Highlights

Feature Description
๐Ÿ›๏ธ Dual Portal System Government Portal (dark theme) + Citizen Portal (light theme)
๐Ÿค– AI Decision Report Sentiment breakdown, conflict analysis, win-win solution, course of action
๐Ÿ—„๏ธ Persistent Cloud DB InsForge PostgreSQL โ€” all data survives restarts
๐Ÿ”ฌ Real-World Research TinyFish web research pulls policy precedents from Wikipedia
๐Ÿ” JWT Auth bcrypt-hashed passwords, 7-day tokens
๐Ÿ“„ PDF/DOCX Upload Government attaches policy docs; AI reads up to 15,000 chars
โœ‰๏ธ Follow-up Questions Government can send targeted follow-up questions to citizens

๐Ÿ—๏ธ Architecture

๐Ÿ“ Project Structure

CivicPulse/
โ”œโ”€โ”€ server.js              โ† Single-file Express backend (889 lines)
โ”‚   โ”œโ”€โ”€ Config & env setup
โ”‚   โ”œโ”€โ”€ In-memory fallback store (no DB mode)
โ”‚   โ”œโ”€โ”€ InsForge REST helpers (ifGet/ifPost/ifPatch/ifDel)
โ”‚   โ”œโ”€โ”€ DB auto-init (creates 4 tables on startup)
โ”‚   โ”œโ”€โ”€ Auth middleware (JWT verify)
โ”‚   โ”œโ”€โ”€ REST API routes (10 endpoints)
โ”‚   โ”œโ”€โ”€ TinyFish SSE streaming client
โ”‚   โ””โ”€โ”€ triggerAnalysis() pipeline (6 steps)
โ”œโ”€โ”€ public/
โ”‚   โ””โ”€โ”€ index.html         โ† Full frontend SPA (1428 lines, vanilla JS)
โ”‚       โ”œโ”€โ”€ Landing page (dual portal selector)
โ”‚       โ”œโ”€โ”€ Government portal (login, post survey, my surveys, connections)
โ”‚       โ””โ”€โ”€ Citizen portal (login, register, browse & respond to surveys)
โ”œโ”€โ”€ .env.example           โ† Environment variable template
โ”œโ”€โ”€ package.json           โ† npm dependencies
โ””โ”€โ”€ skills-lock.json       โ† Dependency lock

๐Ÿ”„ System Architecture Overview

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚                        CLIENT BROWSER                           โ”‚
โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”    โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”  โ”‚
โ”‚  โ”‚   Government Portal   โ”‚    โ”‚      Citizen Portal          โ”‚  โ”‚
โ”‚  โ”‚  (dark theme)         โ”‚    โ”‚   (light theme)              โ”‚  โ”‚
โ”‚  โ”‚  - Post surveys       โ”‚    โ”‚   - Register / Login         โ”‚  โ”‚
โ”‚  โ”‚  - Upload PDF/DOCX    โ”‚    โ”‚   - Browse open surveys      โ”‚  โ”‚
โ”‚  โ”‚  - View AI reports    โ”‚    โ”‚   - Submit free-text opinion โ”‚  โ”‚
โ”‚  โ”‚  - Send follow-ups    โ”‚    โ”‚   - See AI decision result   โ”‚  โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜    โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜  โ”‚
โ”‚              โ”‚  REST + JWT Bearer Token       โ”‚                  โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
               โ”‚                                โ”‚
               โ–ผ                                โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚                   NODE.JS / EXPRESS SERVER                       โ”‚
โ”‚                                                                 โ”‚
โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”   โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”   โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚
โ”‚  โ”‚  Auth Layer    โ”‚   โ”‚  API Routes  โ”‚   โ”‚  AI Pipeline      โ”‚ โ”‚
โ”‚  โ”‚                โ”‚   โ”‚              โ”‚   โ”‚  triggerAnalysis()โ”‚ โ”‚
โ”‚  โ”‚ โ€ข JWT verify   โ”‚   โ”‚ POST /login  โ”‚   โ”‚                   โ”‚ โ”‚
โ”‚  โ”‚ โ€ข Gov creds    โ”‚   โ”‚ POST /survey โ”‚   โ”‚ Step 1: Re-fetch  โ”‚ โ”‚
โ”‚  โ”‚   from .env    โ”‚   โ”‚ POST /resp.  โ”‚   โ”‚ Step 2: Extract   โ”‚ โ”‚
โ”‚  โ”‚ โ€ข bcrypt hash  โ”‚   โ”‚ POST /upload โ”‚   โ”‚         gov doc   โ”‚ โ”‚
โ”‚  โ”‚ โ€ข 7-day tokens โ”‚   โ”‚ GET  /surveysโ”‚   โ”‚ Step 3: TinyFish  โ”‚ โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜   โ”‚ GET  /resp.  โ”‚   โ”‚         research  โ”‚ โ”‚
โ”‚                       โ”‚ POST /ai     โ”‚   โ”‚ Step 4: Build     โ”‚ โ”‚
โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”   โ”‚ POST /resrch โ”‚   โ”‚         prompt    โ”‚ โ”‚
โ”‚  โ”‚ In-Memory      โ”‚   โ”‚ PATCH/survey โ”‚   โ”‚ Step 5: TinyFish  โ”‚ โ”‚
โ”‚  โ”‚ Fallback Store โ”‚   โ”‚ POST /shoot  โ”‚   โ”‚         AI call   โ”‚ โ”‚
โ”‚  โ”‚ (no InsForge)  โ”‚   โ”‚ GET  /status โ”‚   โ”‚ Step 6: Save &    โ”‚ โ”‚
โ”‚  โ”‚ mem.users[]    โ”‚   โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜   โ”‚         cache     โ”‚ โ”‚
โ”‚  โ”‚ mem.surveys[]  โ”‚                      โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ”‚
โ”‚  โ”‚ mem.responses[]โ”‚                                             โ”‚
โ”‚  โ”‚ analysisCache{}โ”‚                                             โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜                                             โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
           โ”‚                        โ”‚               โ”‚
           โ–ผ                        โ–ผ               โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚   InsForge DB    โ”‚  โ”‚  Anthropic Claude   โ”‚  โ”‚  TinyFish AI  โ”‚
โ”‚ (Cloud Postgres) โ”‚  โ”‚  (AI Proxy /api/ai) โ”‚  โ”‚  (SSE stream) โ”‚
โ”‚                  โ”‚  โ”‚                     โ”‚  โ”‚               โ”‚
โ”‚  cp_users        โ”‚  โ”‚  claude-sonnet-4    โ”‚  โ”‚ Wikipedia     โ”‚
โ”‚  cp_surveys      โ”‚  โ”‚  max_tokens: 1000   โ”‚  โ”‚ scraping for  โ”‚
โ”‚  cp_responses    โ”‚  โ”‚  JWT-gated proxy    โ”‚  โ”‚ real-world    โ”‚
โ”‚  cp_analysis     โ”‚  โ”‚                     โ”‚  โ”‚ precedents    โ”‚
โ”‚  (20 chunks)     โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

๐Ÿ—„๏ธ Database Design (InsForge / PostgreSQL)

CivicPulse auto-creates all tables on startup and drops+recreates them to ensure correct column types.

cp_users
โ”œโ”€โ”€ id            uuid        PK (auto)
โ”œโ”€โ”€ username      string      NOT NULL, UNIQUE
โ”œโ”€โ”€ password_hash string      NOT NULL  โ† bcrypt $2a$10$...
โ”œโ”€โ”€ created_at    datetime
โ””โ”€โ”€ updated_at    datetime

cp_surveys
โ”œโ”€โ”€ id               uuid      PK (auto)
โ”œโ”€โ”€ question         string    NOT NULL
โ”œโ”€โ”€ author           string    NOT NULL  โ† gov officer username
โ”œโ”€โ”€ target_responses integer             โ† min responses before AI fires
โ”œโ”€โ”€ context_json     string              โ† JSON array with [GOV_DOC]: prefix
โ”œโ”€โ”€ status           string              โ† 'active' | 'complete'
โ”œโ”€โ”€ analysis_json    string              โ† legacy (unused, see cp_analysis)
โ””โ”€โ”€ published_at     datetime

cp_responses
โ”œโ”€โ”€ id           uuid      PK (auto)
โ”œโ”€โ”€ survey_id    string    FK โ†’ cp_surveys.id
โ”œโ”€โ”€ username     string    FK โ†’ cp_users.username
โ”œโ”€โ”€ answer       string    NOT NULL  โ† free-text citizen opinion
โ””โ”€โ”€ submitted_at datetime

cp_analysis                          โ† AI report stored in 20 chunks
โ”œโ”€โ”€ id           uuid      PK (auto)
โ”œโ”€โ”€ survey_id    string    UNIQUE FK โ†’ cp_surveys.id
โ”œโ”€โ”€ chunk_0      string    โ† 250 chars of JSON
โ”œโ”€โ”€ chunk_1      string
โ”œโ”€โ”€ ...
โ”œโ”€โ”€ chunk_19     string    โ† up to 5000 chars total JSON
โ””โ”€โ”€ created_at   datetime

Why chunking? InsForge string columns max out at ~255 chars. The AI report JSON can be 2000โ€“5000 chars, so it's split into 20 ร— 250-char chunks on write and reassembled on read via toChunks() / fromChunks().

Dual-mode storage: If INSFORGE_URL is not set, the server falls back to a plain in-memory JS object (mem.users, mem.surveys, mem.responses) so the app works without any database configured.


๐Ÿ” Authentication Flow

Government Login                    Citizen Login / Register
โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€                   โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
POST /api/auth/gov-login            POST /api/auth/register
  username + password                 username + password
       โ”‚                                     โ”‚
       โ–ผ                                     โ–ผ
  Check GOV_CREDS{}               bcrypt.hash(password, 10)
  (hardcoded in .env)             โ†’ store in cp_users (InsForge)
       โ”‚                                     โ”‚
       โ–ผ                                     โ–ผ
  jwt.sign({ role:'government' }) jwt.sign({ role:'citizen' })
       โ”‚                                     โ”‚
       โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ 7-day JWT โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                        โ”‚
                        โ–ผ
              Bearer token in Authorization header
              โ†’ auth() middleware verifies on every
                protected route (surveys, responses,
                uploads, AI proxy, analysis trigger)

๐Ÿค– AI Analysis Pipeline โ€” Deep Dive

Triggered automatically when responses.length >= target_responses, or manually via the government portal button.

triggerAnalysis(survey, responses)
โ”‚
โ”œโ”€โ”€ STEP 1 โ€” Re-fetch fresh data
โ”‚   โ””โ”€โ”€ GET /cp_surveys/:id + GET /cp_responses?survey_id=eq.:id
โ”‚       (ensures latest data even if called with stale input)
โ”‚
โ”œโ”€โ”€ STEP 2 โ€” Extract government policy document
โ”‚   โ””โ”€โ”€ Parse survey.context_json (JSON array)
โ”‚       Find message with role:'system' and content starting '[GOV_DOC]:'
โ”‚       Extract up to 3000 chars as govDocSnippet
โ”‚
โ”œโ”€โ”€ STEP 3 โ€” TinyFish Wikipedia research (two parallel lookups)
โ”‚   โ”œโ”€โ”€ Search Wikipedia for policy precedents
โ”‚   โ”‚   โ†’ "real countries that implemented similar policies,
โ”‚   โ”‚      statistics, measurable outcomes, lessons learned"
โ”‚   โ””โ”€โ”€ Search Wikipedia for environmental/social impact data
โ”‚       โ†’ SSE stream from https://agent.tinyfish.ai/v1/automation/run-sse
โ”‚          20s hard timeout, processes data: events line-by-line
โ”‚
โ”œโ”€โ”€ STEP 4 โ€” Build comprehensive analysis prompt
โ”‚   โ””โ”€โ”€ Combines: survey question + gov doc snippet (3000 chars)
โ”‚               + citizen opinions (numbered list)
โ”‚               + Wikipedia precedent data (1000 chars)
โ”‚               + impact data (1000 chars)
โ”‚       Requests strict JSON output (no markdown, 23-field schema)
โ”‚
โ”œโ”€โ”€ STEP 5 โ€” TinyFish AI call
โ”‚   โ””โ”€โ”€ Sends full prompt to TinyFish as 'goal'
โ”‚       Parses JSON from SSE COMPLETE event
โ”‚       Falls back to regex JSON extraction if parsing fails
โ”‚       Falls back to rule-based sentiment analysis if TinyFish fails
โ”‚       (counts support/oppose keywords in citizen answers)
โ”‚
โ””โ”€โ”€ STEP 6 โ€” Save & cache
    โ”œโ”€โ”€ analysisCache[survey.id] = analysisJson  โ† in-memory (instant access)
    โ”œโ”€โ”€ saveAnalysisToIF() โ†’ toChunks() โ†’ INSERT/UPDATE cp_analysis
    โ””โ”€โ”€ PATCH cp_surveys/:id { status: 'complete' }

Analysis JSON schema (23 fields):

{
  "final_decision": "2-3 sentence AI recommendation",
  "government_intent": "what the government wants to achieve",
  "government_concern": "core problem being solved",
  "citizen_emotions": "emotional tone of responses",
  "citizen_concerns": "main citizen issues raised",
  "sentiment_breakdown": {
    "support_percent": 60,
    "oppose_percent": 30,
    "neutral_percent": 10,
    "support_reasons": ["..."],
    "oppose_reasons": ["..."]
  },
  "conflict_analysis": "where gov intent and citizen needs clash",
  "win_win_solution": "creative solution satisfying both sides",
  "alternative_approaches": [{ "name": "", "description": "", "benefits": "", "tradeoffs": "" }],
  "recommended_course_of_action": ["Step 1", "Step 2", "..."],
  "statistics": {
    "key_stats": ["stat with number"],
    "comparable_cases": ["real city + outcome"],
    "projected_impact": "expected outcome"
  },
  "pros": ["..."],
  "cons": ["..."],
  "environmental_social_factors": "context",
  "urgency": "LOW | MEDIUM | HIGH",
  "confidence": 85
}

๐Ÿ›  Tech Stack

Layer Technology Details
Backend Node.js 18+ + Express Single server.js, 889 lines
Frontend Vanilla HTML/CSS/JS Single index.html SPA, 1428 lines, no framework
Database InsForge (Cloud PostgreSQL) REST API, auto-provisioned tables, chunked JSON storage
AI Analysis TinyFish AI SSE streaming, Wikipedia scraping, 20s timeout
AI Proxy Anthropic Claude (Sonnet 4) JWT-gated /api/ai proxy endpoint
Auth JWT + bcryptjs 7-day tokens, cost-10 bcrypt, role-based (gov/citizen)
File Upload multer + pdf-parse + mammoth PDF & DOCX โ†’ up to 15,000 chars extracted
Deployment Railway Auto-deploy from GitHub, env vars via Railway dashboard
In-memory fallback Plain JS objects Works without any database if InsForge not configured

๐Ÿš€ Quick Start

1. Clone & Install

git clone https://github.com/AmrishS2004/CivicPulse.git
cd CivicPulse
npm install

2. Configure Environment

cp .env.example .env

Open .env and fill in your keys:

Variable Where to Get
ANTHROPIC_API_KEY console.anthropic.com
INSFORGE_URL insforge.app โ†’ Create Project โ†’ copy URL
INSFORGE_ADMIN_KEY InsForge โ†’ Settings โ†’ API Keys
TINYFISH_API_KEY tinyfish.ai โ€” 500 free steps
JWT_SECRET Any long random string
GOV_CREDENTIALS username:password pairs, comma-separated

3. Start

npm start          # production
npm run dev        # development (auto-reload with nodemon)

4. Open

Visit http://localhost:3000

You should see:

โœ… InsForge ready
๐Ÿ›๏ธ CivicPulse โ†’ http://localhost:3000
   AI:       โœ… Claude
   Backend:  โœ… InsForge
   Research: โœ… TinyFish

๐Ÿ” Government Login

Government credentials are pre-configured in .env via GOV_CREDENTIALS. No self-registration is allowed for the government portal.

Default credentials (change in .env):

gov_admin     / Admin@2024
gov_officer   / Officer@2024
ministry_lead / Ministry@2024

๐Ÿ“Š Database Schema

CivicPulse auto-creates four tables in InsForge on startup:

Table Purpose
cp_users Citizen accounts (bcrypt hashed passwords)
cp_surveys Government surveys + uploaded document text
cp_responses Citizen free-text responses
cp_analysis AI analysis stored as 20 chunked string columns

๐Ÿค– AI Analysis Pipeline

When the target response count is reached (or manually triggered):

1. Fetch      โ†’ pulls fresh survey + responses from InsForge
2. Extract    โ†’ parses uploaded policy document from context_json
3. Research   โ†’ TinyFish browses Wikipedia for real-world policy precedents
4. Analyse    โ†’ sentiment engine classifies each response (support / neutral / oppose)
5. Report     โ†’ builds 14-section decision report with win-win solution
6. Save       โ†’ chunks JSON into InsForge cp_analysis table (persists across restarts)

๐Ÿ“‹ AI Decision Report includes

  • โš–๏ธ Final Decision โ€” AI-informed recommendation
  • ๐Ÿ“Š Citizen Sentiment Breakdown โ€” visual bar with percentages
  • โšก Conflict Analysis โ€” identifies tensions between government intent and citizen concern
  • ๐Ÿ† Win-Win Solution โ€” bridges both sides
  • ๐Ÿ—บ๏ธ Recommended Course of Action โ€” step-by-step implementation plan
  • ๐Ÿ“ˆ Statistics & Comparable Cases โ€” real-world data via TinyFish
  • ๐Ÿ’ก Alternative Approaches โ€” what else could be done
  • โœ… Pros & โŒ Cons โ€” balanced view

๐ŸŒ API Endpoints

Method Endpoint Auth Description
POST /api/auth/register None Register citizen
POST /api/auth/login None Citizen login
POST /api/auth/gov-login None Government login
GET /api/surveys None List all surveys
POST /api/surveys Gov Create survey
GET /api/responses/:id None Get responses
POST /api/responses Citizen Submit response
POST /api/upload-doc Gov Upload PDF/DOCX
POST /api/admin/trigger-analysis/:id Gov Manually trigger analysis
GET /api/config/status None Service health check

๐Ÿ“ฆ Dependencies

npm install   # installs everything from package.json

Core: express ยท cors ยท dotenv ยท node-fetch ยท bcryptjs ยท jsonwebtoken ยท multer ยท pdf-parse ยท mammoth


๐Ÿ”ฎ Roadmap

  • Email notifications when AI report is ready
  • Multi-language citizen portal support
  • Analytics dashboard for government officers
  • Mobile app (React Native)
  • Role-based access control within government portal

๐Ÿ‘ค Author

Amrish Sasikumar

Email LinkedIn GitHub

Aravind Chidambaram

Email LinkedIn GitHub

Nandita Ramkrishnan

Email LinkedIn GitHub

---

๐Ÿ“„ License

This project is licensed under the MIT License โ€” see the LICENSE file for details.


Made with โค๏ธ by Amrish Sasikumar, Aravind ยท Powered by Claude AI ยท InsForge ยท TinyFish

โญ Star this repo if you found it useful!

About

๐Ÿ›๏ธ Where government policy meets citizen voice. Governments post surveys, citizens respond freely, and AI analyses sentiment & delivers a win-win decision report. Powered by Claude AI ยท InsForge ยท TinyFish ยท Deployed on Railway.

https://civicpulse-production.up.railway.app/

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors