Civic Compass is a neutral political values assessment prototype built with Next.js, React, TypeScript, and Tailwind CSS. It helps users explore their views across multiple civic dimensions without reducing the result to a single party label.
- Quick quiz for a preview profile
- Full randomized assessment
- Multi-axis political profile results
- Optional party-alignment reveal
- Political compass, radar chart, score cards, confidence meter, and issue breakdowns
- Transparent answer-by-answer scoring view
- Educational context for each issue area
- Anonymous-by-default experience
- Optional encrypted local profile saving
- Optional account login and server-side saved assessment history
- Admin portal prototype for question governance, scoring review, analytics, version management, and bias review
The prototype is designed around privacy and transparency:
- No account is required to complete the assessment.
- Results are stored only in the browser unless the user chooses to save them.
- Saved profiles are encrypted locally with a passphrase.
- Political profile data should never be sold, shared, or used for advertising.
- Scoring should remain explainable and reviewable by the user.
- Next.js
- React
- TypeScript
- Tailwind CSS
- Lucide React icons
- MySQL via
mysql2
Install dependencies:
npm installRun the development server:
npm run devBuild for production:
npm run buildRun the production build:
npm startCreate a local environment file before using database-backed routes:
cp .env.example .env.localThen set DB_PASSWORD in .env.local. The MySQL health endpoint is available at
/api/db/health and runs a server-side SELECT 1 check.
For the hosted site, use the local MySQL target provided by the host, usually
DB_HOST=localhost. If the host provides a Unix socket, set DB_SOCKET; it will
take precedence over DB_HOST and DB_PORT.
The app also accepts common hosting aliases:
DB_DATABASE,MYSQL_DATABASE,MYSQL_DB, orDATABASE_NAMEforDB_NAMEDB_PASS,MYSQL_PASSWORD, orDATABASE_PASSWORDforDB_PASSWORDMYSQL_USERorDATABASE_USERforDB_USERMYSQL_HOSTorDATABASE_HOSTforDB_HOST
Create the database tables with:
npm run db:migrate
npm run db:seed:assessmentOr apply individual migrations manually:
mysql -h srv2104.hstgr.io -u u130206374_civicAdmin -p u130206374_civic < sql/001_create_assessment_profiles.sql
mysql -h srv2104.hstgr.io -u u130206374_civicAdmin -p u130206374_civic < sql/002_create_users_sessions_profiles.sqlThe /api/profiles endpoint stores opt-in anonymous assessment snapshots for
aggregate question-quality review.
Database records use UUID public_id columns for application-facing identifiers.
Numeric primary keys remain internal implementation details for joins and legacy
foreign keys.
Account routes:
/account- login, signup, logout, and saved assessment history/api/auth/signup- create an account and session/api/auth/login- create a session for an existing account/api/auth/logout- revoke the current session/api/auth/me- return the current session user/api/account/profiles- list or save authenticated assessment profiles/api/account/profiles/[id]- fetch, rename, or delete a saved profile owned by the current user/api/account- fetch account details, update display name/password, or delete the account/api/admin/metrics- role-protected MySQL metrics for admins and researchers/api/admin/bias-review- list or create persisted bias review items/api/admin/bias-review/[id]- assign, approve, request revision, or resolve review items/api/admin/bias-review/[id]/comments- list or add review comments/api/admin/questions- list live questions with health metrics or create draft questions/api/admin/questions/generate- generate AI-assisted draft question candidates/api/admin/questions/[id]- update editable question fields/api/admin/questions/[id]/status- move questions through draft, review, approval, publish, archive, or rejection/api/admin/questions/[id]/comments- list or add question review comments
Run verification:
npm run verifyapp/page.tsx- main assessment, quiz flow, results, and profile UIapp/account/page.tsx- account login, signup, and saved profile history UIapp/data.ts- dimensions, categories, questions, answer choices, and scoring weightsapp/admin/page.tsx- admin portal prototypeapp/globals.css- application styling and responsive layoutlib/auth.ts- password hashing, session cookies, and user lookup helperslib/db.ts- server-only MySQL connection poolnext.config.ts- Next.js configuration and browser security headersSECURITY.md- security notes and implementation caveats
The admin portal is currently a frontend prototype. It includes:
- Question health monitoring
- Skip-rate and polarization signals
- Editorial and bias review queues
- Assessment version management
- Scoring sandbox
- Category coverage checks
- AI-assisted question draft generation
- Educational content review cards
- MySQL-backed analytics summaries
- User feedback management
Before production use, the admin portal should be backed by authenticated APIs, role-based access control, audit logs, server-side validation, CSRF protection, and rate limiting.
- Admin overview and analytics counts are read from MySQL.
- Percentiles are illustrative and not demographic predictions.
- The admin portal does not yet persist edits to a backend.
- The admin portal route is protected by login and requires
adminorresearcherrole. Bias review and question workflow are persisted in MySQL; broader content editing screens are still read-only prototypes. - AI-assisted question generation requires
OPENAI_API_KEYin server environment variables. Generated questions are candidates only; admins must explicitly save them as drafts before review. - Anonymous research snapshots are persisted only when a user explicitly submits one from the results screen.
- Account-saved assessment history is persisted only for logged-in users who explicitly choose to save a profile to their account.
- Educational reading entries are placeholders for curated source links.
- Party alignment is an optional estimate based on issue responses, not a definitive label.
- Neutral and transparent
- Educational rather than persuasive
- Easy to complete
- Respectful of diverse viewpoints
- Privacy-preserving by default
- Explainable scoring with no hidden logic