You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Realtime collaborative polling platform. Users create and manage polls through an authenticated dashboard; respondents vote via public slug-based URLs. Results and analytics update live through Socket.io.
The repository is organized as a monorepo with a React frontend and a Node.js/Express backend.
Authentication: Google OAuth 2.0 with rotating JWT refresh tokens and family-based reuse detection. Cookie-based sessions with automatic token refresh on the client via Axios interceptors.
Poll lifecycle: Create, edit, activate, and delete polls. Drag-and-drop option ordering in the poll builder.
Public voting: Slug-based public poll and results pages. Anonymous respondent deduplication via a 4-layer identity strategy (signed cookie, device fingerprint, Redis session token, hashed IP).
Realtime: Socket.io rooms per poll. Live presence counts, response counts, expiry events, and publish notifications pushed to connected clients.
Analytics: Live Redis counters with background aggregation into the database via BullMQ. Stale-while-revalidate caching with distributed stampede protection.
Result publishing: On-demand publish trigger snapshots final results and emits a socket event. Charts on the analytics page update via React Query invalidation.
Rate limiting: Redis sliding-window limiters per endpoint category.
Architecture Overview
State layers (frontend)
Layer
Tool
Responsibility
Server state
React Query
Polls, analytics, user data, paginated lists
Client state
Zustand
Auth session, UI preferences, socket metadata
Realtime
Socket.io
Push events that update Zustand or invalidate React Query
# Backend (from backend/)
npm run dev
# Starts API at http://localhost:3000# Frontend (from frontend/)
npm run dev
# Starts client at http://localhost:5173
Alternative: Full Docker stack
cd backend
# Production image
docker compose up --build
# Dev with hot reload and Drizzle Studio
docker compose --profile dev up --build
Scripts
Frontend
Script
Description
npm run dev
Start Vite development server
npm run build
Typecheck and build for production
npm run preview
Serve production build locally
npm run lint
Run ESLint
Backend
Script
Description
npm run dev
Hot-reload dev server via tsx watch
npm run build
Compile TypeScript to dist/
npm run start
Run compiled production build
npm run db:generate
Generate Drizzle migrations
npm run db:migrate
Apply pending migrations
npm run db:studio
Open Drizzle Studio GUI
npm run typecheck
Type-check without emitting
Frontend Routes
Path
Access
Description
/
Public
Landing page
/login
Public only
Login
/poll/:slug
Public
Vote on a poll
/results/:slug
Public
View published results
/dashboard
Protected
Poll management dashboard
/dashboard/new
Protected
Poll builder (create)
/dashboard/polls/:pollId/edit
Protected
Poll builder (edit)
/dashboard/polls/:slug/analytics
Protected
Live analytics
/dashboard/profile
Protected
User profile
About
Full-stack TypeScript polling platform using React Query, Zustand, Socket.io, Drizzle ORM, PostgreSQL, Redis, and BullMQ.