This repository contains a modern, full-stack live polling application built with cutting-edge web technologies. The application enables users to create, participate in, and analyze real-time polls with sophisticated authentication, role-based access control, and comprehensive analytics.
- Product Overview
- Technical Architecture
- Technology Stack
- Data Model & Schema
- Authentication & Authorization
- Frontend Architecture
- Backend Architecture
- User Experience Design
- Security Analysis
- Performance Considerations
- Development Workflow
- Scalability & Future Considerations
- Code Quality & Maintainability
The Live Poll Demo is a sophisticated polling platform designed to facilitate real-time engagement through interactive polls. It serves as both a practical tool for gathering opinions and a demonstration of modern web development best practices.
- Poll Creation: Intuitive interface for creating polls with multiple options
- Real-time Voting: Live voting with instant result updates
- Poll Management: Complete lifecycle management (create, active, complete)
- Analytics Dashboard: Comprehensive statistics and visualizations
- Role-based Access: Admin controls for platform management
- Responsive Design: Mobile-first approach with dark/light theme support
- Real-time Updates: Live synchronization of poll data across sessions
- Accessibility: Proper ARIA labels and keyboard navigation
- Progressive Enhancement: Works across different device capabilities
- Primary: Organizations needing quick feedback mechanisms
- Secondary: Educators conducting classroom polls
- Tertiary: Event organizers gathering audience input
graph TB
subgraph "Client Layer"
A[React Frontend]
B[TanStack Router]
C[TanStack Query]
end
subgraph "Authentication Layer"
D[Clerk Auth]
E[JWT Tokens]
end
subgraph "Backend Services"
F[Convex Backend]
G[Convex Functions]
H[Real-time Subscriptions]
end
subgraph "Data Layer"
I[Convex Database]
J[User Management]
K[Poll Storage]
end
subgraph "Infrastructure"
L[Vite Build System]
M[TanStack Start SSR]
N[Netlify Deployment]
end
A --> B
A --> C
A --> D
B --> F
C --> F
D --> E
F --> G
F --> H
G --> I
H --> I
I --> J
I --> K
A --> L
L --> M
M --> N
sequenceDiagram
participant U as User
participant C as Client
participant A as Clerk Auth
participant Q as TanStack Query
participant CV as Convex
participant DB as Database
U->>C: Interacts with UI
C->>A: Request Authentication
A->>C: Return JWT Token
C->>Q: Query/Mutation Request
Q->>CV: API Call with Auth
CV->>DB: Database Operation
DB->>CV: Data Response
CV->>Q: Real-time Update
Q->>C: Update UI State
C->>U: Display Updated Data
- React 19: Latest version with concurrent features
- TypeScript: Full type safety and developer experience
- Vite 6.3.5: Lightning-fast build tool and dev server
- TanStack Router: Type-safe routing with search params
- TanStack Query: Server state management with caching
- TanStack Start: Full-stack React framework with SSR
- Tailwind CSS 4.1.9: Utility-first CSS framework
- Radix UI: Accessible, unstyled UI primitives
- Lucide React: Modern icon library
- Recharts: Data visualization library
- React Hook Form: Performant forms with minimal re-renders
- Zod: Runtime type validation and schema parsing
- Convex: Real-time backend with TypeScript functions
- Convex React Query: Integration between Convex and TanStack Query
- Clerk: Complete authentication and user management
- JWT: Secure token-based authentication
- pnpm: Fast, disk space efficient package manager
- TypeScript: Static type checking across the stack
erDiagram
POLL {
string _id PK
string question
array options
string creator FK
boolean completed
timestamp _creationTime
}
VOTE {
string _id PK
id pollId FK
number optionIndex
string voter FK
timestamp _creationTime
}
USER {
string userId PK
string email
string role
object metadata
}
POLL ||--o{ VOTE : "receives"
USER ||--o{ POLL : "creates"
USER ||--o{ VOTE : "casts"
The application uses Convex's type-safe schema system:
// Poll Schema
poll: defineTable({
question: v.string(),
options: v.array(v.string()),
creator: v.string(), // Clerk user ID
completed: v.optional(v.boolean()),
})
.index("by_creator", ["creator"])
.index("by_option", ["options"]),
// Vote Schema
vote: defineTable({
pollId: v.id("poll"),
optionIndex: v.number(),
voter: v.string(), // Clerk user ID
})
.index("by_voter", ["voter"])
.index("by_poll", ["pollId"])
.index("by_option", ["optionIndex"])- User → Polls: One user can create multiple polls
- Poll → Votes: One poll can receive multiple votes
- User → Votes: One user can cast multiple votes (on different polls)
- One Vote Per Poll: Each user can only vote once per poll
- Creator Privileges: Poll creators can manage their polls
- Admin Override: Admins can manage any poll
flowchart TD
A[User Access] --> B{Authenticated?}
B -->|No| C[Clerk Sign-in]
B -->|Yes| D[Fetch JWT Token]
C --> E[Clerk Auth Flow]
E --> F[Set User Session]
F --> D
D --> G[Set Convex Auth]
G --> H[Access Application]
H --> I{Admin Route?}
I -->|Yes| J{Admin Role?}
I -->|No| K[Regular Access]
J -->|Yes| L[Admin Dashboard]
J -->|No| M[NoAccess Component]
type Roles = 'admin' | 'member'| Feature | Member | Admin |
|---|---|---|
| View Polls | ✅ | ✅ |
| Create Polls | ✅ | ✅ |
| Vote on Polls | ✅ | ✅ |
| Edit Own Polls | ✅ | ✅ |
| Complete Own Polls | ✅ | ✅ |
| Edit Any Poll | ❌ | ✅ |
| Complete Any Poll | ❌ | ✅ |
| Admin Dashboard | ❌ | ✅ |
| Analytics | ❌ | ✅ |
- JWT Tokens: Secure, stateless authentication
- Server-side Validation: All auth checks happen on the server
- Auto-refresh: Tokens refresh automatically
- Secure Headers: Proper CORS and security headers
- Route Protection: Protected routes check authentication status
- API Protection: All Convex functions require authentication
- Role Verification: Admin routes verify role membership
- Resource Ownership: Users can only modify their own resources
graph TD
A[App Root] --> B[Route Provider]
B --> C[Auth Provider]
C --> D[Theme Provider]
D --> E[Layout Components]
E --> F[Navigation]
E --> G[Main Content]
E --> H[Footer]
G --> I[Route Components]
I --> J[Home]
I --> K[Polls List]
I --> L[Poll Detail]
I --> M[Admin Dashboard]
subgraph "Shared UI"
N[Button]
O[Card]
P[Dialog]
Q[Form Components]
R[Charts]
end
J --> N
K --> O
L --> P
M --> R
- Polls Data: Cached and synchronized across components
- Vote Counts: Real-time updates via Convex subscriptions
- User Data: Cached authentication state
- Analytics: Dashboard statistics with automatic refetching
- UI State: Modal open/close, form inputs
- Theme State: Dark/light mode preference
- Navigation State: Active routes and breadcrumbs
graph LR
A[User Action] --> B[React Component]
B --> C[TanStack Query]
C --> D[Convex Function]
D --> E[Database Update]
E --> F[Real-time Subscription]
F --> G[Auto UI Update]
/ (public)
├── /_authed (requires auth)
│ ├── /polls (polls list)
│ │ └── /$pollId (poll detail)
│ └── /_admin (requires admin role)
│ └── /dashboard (admin analytics)
- Public Routes: Accessible to all users
- Authenticated Routes: Require sign-in
- Admin Routes: Require admin role
- Nested Protection: Child routes inherit parent protection
graph TB
subgraph "Query Functions (Read)"
A[getPolls]
B[getPoll]
C[getVoteCounts]
D[hasUserVoted]
E[getPollStats]
end
subgraph "Mutation Functions (Write)"
F[createPoll]
G[updatePoll]
H[deletePoll]
I[castVote]
J[updateVote]
K[togglePollCompletion]
end
subgraph "Database Tables"
L[polls]
M[votes]
end
A --> L
B --> L
C --> M
D --> M
E --> L
F --> L
G --> L
H --> L
I --> M
J --> M
K --> L
- Pure Functions: No side effects, cacheable
- Type Safety: Full TypeScript integration
- Real-time: Automatic subscription to changes
- Authorization: Built-in auth context
- Atomic Operations: Database consistency guaranteed
- Validation: Input validation with Convex validators
- Authorization: User-based access control
- Error Handling: Comprehensive error responses
- Poll Creation: New polls appear instantly
- Vote Casting: Vote counts update in real-time
- Poll Completion: Status changes propagate immediately
// Automatic real-time subscriptions
const { data: polls } = useQuery(
convexQuery(api.poll.getPolls, {})
);- Primary: Blue-purple gradient (
oklch(0.5854 0.2041 277.1173)) - Secondary: Neutral grays for balance
- Semantic: Green for success, red for errors/completion
- Theme Support: Comprehensive dark/light mode
- Primary Font: Plus Jakarta Sans (clean, modern)
- Monospace: Roboto Mono for code elements
- Serif: Lora for emphasis text
- Container: Max-width responsive containers
- Grid System: CSS Grid and Flexbox for layouts
- Spacing Scale: Consistent rem-based spacing
journey
title New User Poll Creation Journey
section Discovery
Visit Homepage: 5: User
View Features: 4: User
See Sign-in CTA: 3: User
section Authentication
Click Sign In: 5: User
Complete Auth: 4: User
Redirect to App: 5: User
section First Poll
View Empty State: 3: User
Click Create Poll: 5: User
Fill Form: 4: User
Submit Poll: 5: User
View Results: 5: User
journey
title Poll Participation Journey
section Discovery
Browse Polls: 4: User
Find Interesting Poll: 5: User
Click to View: 5: User
section Voting
Read Question: 5: User
Review Options: 4: User
Cast Vote: 5: User
See Results: 5: User
section Engagement
View Analytics: 4: User
Share Poll: 3: User
Create Own Poll: 4: User
- Keyboard Navigation: Full keyboard accessibility
- Screen Readers: Proper ARIA labels and roles
- Color Contrast: WCAG AA compliant color ratios
- Focus Management: Clear focus indicators
- Mobile First: Designed for mobile, enhanced for desktop
- Breakpoints: Tailored for phone, tablet, desktop
- Touch Targets: Minimum 44px touch targets
graph TD
A[Client Security] --> B[Network Security]
B --> C[Authentication Security]
C --> D[Authorization Security]
D --> E[Data Security]
A --> A1[Input Validation]
A --> A2[XSS Prevention]
A --> A3[CSRF Protection]
B --> B1[HTTPS Only]
B --> B2[Secure Headers]
B --> B3[CORS Policy]
C --> C1[JWT Tokens]
C --> C2[Token Refresh]
C --> C3[Session Management]
D --> D1[Role-based Access]
D --> D2[Resource Ownership]
D --> D3[API Authorization]
E --> E1[Input Sanitization]
E --> E2[SQL Injection Prevention]
E --> E3[Data Encryption]
- Client-side: React Hook Form with Zod validation
- Server-side: Convex validators for all inputs
- XSS Prevention: React's built-in XSS protection
- SQL Injection: N/A (NoSQL with typed queries)
- Token-based: JWT tokens for stateless auth
- Secure Storage: Tokens stored in HTTP-only cookies
- Auto-refresh: Automatic token renewal
- Logout: Proper session cleanup
- Route Guards: Protected routes check authentication
- API Guards: All functions require valid authentication
- Role Checks: Admin functions verify role
- Resource Guards: Users can only access their data
- ✅ HTTPS enforcement
- ✅ Secure authentication flow
- ✅ Input validation on all forms
- ✅ Role-based access control
- ✅ Resource ownership validation
- ✅ Error message sanitization
- 🔄 Rate limiting on poll creation
- 🔄 Audit logging for admin actions
- 🔄 Content Security Policy headers
- 🔄 Regular security dependency updates
graph TD
A[Performance Optimization] --> B[Code Splitting]
A --> C[Lazy Loading]
A --> D[Caching Strategy]
A --> E[Bundle Optimization]
B --> B1[Route-based Splitting]
B --> B2[Component Splitting]
C --> C1[React.lazy Components]
C --> C2[Image Lazy Loading]
D --> D1[TanStack Query Cache]
D --> D2[Browser Cache]
D --> D3[Service Worker]
E --> E1[Tree Shaking]
E --> E2[Minification]
E --> E3[Compression]
- Code Splitting: Route-based code splitting with TanStack Router
- Query Caching: Intelligent caching with stale-while-revalidate
- Bundle Optimization: Vite's optimized bundling
- Tree Shaking: Automatic dead code elimination
- First Contentful Paint: Target < 1.5s
- Largest Contentful Paint: Target < 2.5s
- Time to Interactive: Target < 3.5s
- Bundle Size: Optimized with dynamic imports
- Indexes: Strategic indexing on query patterns
- Query Optimization: Efficient query patterns
- Real-time Efficiency: Optimized subscription patterns
- Convex Scaling: Automatic horizontal scaling
- CDN: Static asset delivery optimization
- Caching: Multi-layer caching strategy
graph LR
A[Source Code] --> B[TypeScript Check]
B --> C[Vite Build]
C --> D[Asset Optimization]
D --> E[Bundle Generation]
E --> F[Deployment]
subgraph "Development"
G[Hot Reload]
H[Type Checking]
I[ESLint]
end
A --> G
A --> H
A --> I
# Start development server
pnpm dev
# Build for production
pnpm build
# Start production server
pnpm start- Vite: Fast HMR and development server
- TypeScript: Real-time type checking
- TanStack Router Devtools: Route debugging
- TanStack Query Devtools: State inspection
src/
├── components/ # Reusable UI components
│ ├── ui/ # Base UI primitives
│ └── [Feature]Dialog.tsx # Feature-specific components
├── routes/ # File-based routing
│ ├── __root.tsx # Root layout
│ ├── index.tsx # Home page
│ └── _authed/ # Protected routes
├── lib/ # Utility libraries
│ ├── utils/ # Helper functions
│ └── types/ # TypeScript types
└── styles/ # Global styles
// Consistent prop interface
interface ComponentProps {
readonly children?: React.ReactNode;
readonly className?: string;
readonly variant?: 'default' | 'secondary';
}
// Forward refs for composition
const Component = React.forwardRef<HTMLElement, ComponentProps>(
({ children, className, ...props }, ref) => {
return (
<Element
ref={ref}
className={cn(baseStyles, className)}
{...props}
>
{children}
</Element>
);
}
);// Query hooks for data fetching
function usePolls() {
return useQuery({
...convexQuery(api.poll.getPolls, {}),
staleTime: 5 * 60 * 1000, // 5 minutes
});
}
// Mutation hooks for data updates
function useCreatePoll() {
return useConvexMutation(api.poll.createPoll);
}graph TD
subgraph "Current Architecture"
A[Single Page App]
B[Convex Backend]
C[Clerk Auth]
end
subgraph "Scaling Options"
D[Multi-region Deploy]
E[CDN Distribution]
F[Database Sharding]
G[Microservices]
end
subgraph "Future Features"
H[Real-time Comments]
I[Poll Templates]
J[Advanced Analytics]
K[API for 3rd Party]
end
A --> D
B --> F
C --> G
D --> H
E --> I
F --> J
G --> K
- ✅ Type safety across the stack
- ✅ Modern React patterns
- ✅ Consistent code style
- ✅ Component reusability
- 🔄 Test coverage improvement
- 🔄 Error boundary implementation
- 🔄 Loading state standardization
- 🔄 Internationalization preparation
- 🔄 Comprehensive error handling
- 🔄 Performance monitoring
- 🔄 Accessibility audit
- 🔄 Security audit
- Poll Templates: Pre-built poll templates
- Advanced Voting: Ranked choice voting
- Poll Scheduling: Time-based poll activation
- Export Features: PDF/CSV export of results
- Poll Comments: Discussion on polls
- Poll Sharing: Social media integration
- Team Workspaces: Multi-user poll management
- Real-time Collaboration: Live poll editing
- Advanced Analytics: Demographic analysis
- Trend Analysis: Historical voting patterns
- Custom Reports: Automated report generation
- Integration APIs: Third-party tool integration
- TypeScript Coverage: 100% TypeScript usage
- Strict Mode: Enabled across the project
- Type Inference: Leveraging TypeScript inference
- Runtime Validation: Zod schemas for runtime safety
- ESLint: Consistent code formatting (ready for setup)
- Prettier: Code formatting (ready for setup)
- File Naming: Consistent naming conventions
- Import Organization: Clean import structure
// Dialog component with sub-components
<Dialog>
<DialogHeader>
<DialogTitle>Create Poll</DialogTitle>
</DialogHeader>
<DialogContent>
{/* Form content */}
</DialogContent>
</Dialog>// Encapsulated logic in custom hooks
function usePollManagement() {
const createPoll = useCreatePoll();
const updatePoll = useUpdatePoll();
return {
createPoll,
updatePoll,
isLoading: createPoll.isPending || updatePoll.isPending
};
}// Context providers for shared state
<ThemeProvider>
<AuthProvider>
<QueryProvider>
<App />
</QueryProvider>
</AuthProvider>
</ThemeProvider>- Components: React Testing Library
- Hooks: React Hooks Testing Library
- Utilities: Jest for pure functions
- API Functions: Convex testing utilities
- User Flows: Playwright for E2E testing
- API Integration: Test Convex functions
- Authentication: Test auth flows
- Real-time: Test subscription behavior
- Bundle Analysis: Webpack Bundle Analyzer
- Core Web Vitals: Lighthouse CI
- Load Testing: Test real-time scaling
- Memory Profiling: React DevTools Profiler
- Modern Stack: Cutting-edge technologies and patterns
- Type Safety: Full TypeScript coverage
- Real-time: Seamless live updates
- Performance: Optimized for speed and efficiency
- Fast Development: Hot reloading and instant feedback
- Type Safety: Compile-time error detection
- Tooling: Excellent debugging and development tools
- Documentation: Clear code and architecture patterns
- Responsive Design: Works across all devices
- Accessibility: Designed for all users
- Performance: Fast loading and interactions
- Intuitive: Clear user interface and flows
- Testing: Implement comprehensive test suite
- Error Handling: Enhance error boundaries and recovery
- Performance: Add performance monitoring
- Documentation: Expand inline code documentation
- Scalability: Prepare for high-volume usage
- Features: Expand poll functionality
- Integrations: API for third-party applications
- Analytics: Advanced reporting and insights
This codebase represents a well-architected, modern web application that balances developer experience, user experience, and technical excellence. It serves as an excellent foundation for a production polling platform with clear paths for enhancement and scaling.