feat: implement dynamic P2P polling app with real-time synchronization

- Add complete P2P polling application with React + TypeScript frontend
- Implement Node.js backend with Yjs WebSocket and WebRTC signaling
- Support dynamic poll creation, answer management, and voting
- Add CRDT-based state synchronization using Yjs for conflict-free merging
- Implement user tracking and vote prevention (one vote per user per option)
- Create modern UI with Tailwind CSS and visual feedback
- Add comprehensive documentation and setup instructions

Features:
- Users can create polls with custom questions
- Anyone can add answer options to any poll
- Real-time voting with instant cross-client synchronization
- Smart vote tracking with visual feedback for voted options
- User attribution showing who created polls and options
- Connection status indicators for WebSocket and P2P connections

Technical:
- Hybrid P2P architecture (WebSocket + WebRTC)
- CRDT-based state management with Yjs
This commit is contained in:
2026-03-25 11:51:33 +01:00
parent 4275cbd795
commit e14bb6d425
36 changed files with 8281 additions and 1 deletions

280
README.md
View File

@@ -1 +1,279 @@
# P2P Poll App
# P2P Poll App
A peer-to-peer polling application built with React, TypeScript, Tailwind CSS, Node.js, Yjs, and WebSocket for real-time collaborative voting.
**Users can create polls, add answers, and vote in real-time with automatic P2P synchronization across all connected clients.**
## Architecture
**Hybrid P2P Approach:**
- Backend serves as both a Yjs WebSocket provider (for state synchronization) and signaling server (for WebRTC peer discovery)
- Clients sync poll data via Yjs CRDT for conflict-free merging
- Direct P2P connections via WebRTC for real-time updates when possible
- Server fallback ensures reliability when P2P fails
## Tech Stack
**Backend:**
- Node.js + TypeScript
- Express.js
- WebSocket (ws)
- y-websocket (Yjs WebSocket provider)
- CORS support
**Frontend:**
- React 18 + TypeScript
- Vite (build tool)
- Tailwind CSS
- Yjs (CRDT library)
- y-websocket (server sync)
- y-webrtc (P2P sync)
- lucide-react (icons)
## Project Structure
```
quicgroup/
├── server/ # Backend Node.js server
│ ├── src/
│ │ ├── index.ts # Main server entry
│ │ ├── yjs-server.ts # Yjs WebSocket provider
│ │ ├── signaling-server.ts # WebRTC signaling
│ │ ├── types/ # TypeScript types
│ │ └── utils/ # Utilities
│ ├── package.json
│ └── tsconfig.json
└── frontend/ # React frontend
├── src/
│ ├── components/ # React components
│ ├── hooks/ # Custom React hooks
│ ├── lib/ # Yjs setup and utilities
│ ├── types/ # TypeScript types
│ └── styles/ # CSS styles
├── package.json
└── vite.config.ts
```
## Setup Instructions
### Prerequisites
- Node.js 18+ and npm
### Backend Setup
1. Navigate to server directory:
```bash
cd server
```
2. Install dependencies:
```bash
npm install
```
3. Copy environment file:
```bash
cp .env.example .env
```
4. Start the development server:
```bash
npm run dev
```
The server will run on `http://localhost:3000` with:
- Yjs WebSocket: `ws://localhost:3000/yjs`
- Signaling WebSocket: `ws://localhost:3000/signal`
### Frontend Setup
1. Navigate to frontend directory:
```bash
cd frontend
```
2. Install dependencies:
```bash
npm install
```
3. Copy environment file (optional):
```bash
cp .env.example .env
```
4. Start the development server:
```bash
npm run dev
```
The frontend will run on `http://localhost:5173`
## Running the Application
1. **Start Backend** (Terminal 1):
```bash
cd server
npm run dev
```
2. **Start Frontend** (Terminal 2):
```bash
cd frontend
npm run dev
```
3. **Open Browser:**
- Navigate to `http://localhost:5173`
- Open multiple tabs/windows to test P2P synchronization
## Features
### Dynamic Poll Creation
- **Create Polls** - Any user can create new polls with custom questions
- **Add Answers** - Anyone can add answer options to any poll
- **Real-time Voting** - Vote on options with instant updates across all clients
- **Smart Vote Tracking** - One vote per user per option (prevents duplicate voting)
- **Visual Feedback** - Green border and " Voted" indicator on voted options
- **User Attribution** - See who created each poll and option
- **Live Vote Counts** - See vote percentages and counts update in real-time
- **P2P Synchronization** - Uses Yjs CRDT for conflict-free state merging
- **Connection Status** - Visual indicator showing WebSocket and peer connections
- **Hybrid Architecture** - Combines WebSocket server sync with WebRTC P2P
- **Beautiful UI** - Modern gradient design with Tailwind CSS
## How to Use
### Create a Poll
1. Enter your question in the "Create a New Poll" form at the top
2. Click "Create Poll"
3. Your poll appears instantly for all connected users
### Add Answer Options
1. Find the poll you want to add an answer to
2. Type your answer in the "Add a new option..." field
3. Click "Add"
4. Your answer appears instantly for all users
### Vote on Options
1. Click the vote button (thumbs up icon) on any option
2. You can only vote once per option
3. Voted options show a green border and " Voted" indicator
4. Vote counts update in real-time across all clients
### Multi-User Testing
1. Open multiple browser tabs/windows
2. Create polls from different tabs
3. Add answers from different tabs
4. Vote from different tabs
5. Watch real-time synchronization in action!
## How It Works
### CRDT Synchronization
The app uses Yjs (a CRDT library) to ensure all clients converge to the same state without conflicts:
- Each client maintains a local Yjs document
- Changes are automatically synced via WebSocket to the server
- WebRTC provides direct P2P connections between clients
- Yjs handles merge conflicts automatically
- One vote per user per option is enforced via `votedBy` tracking
## Data Model
```typescript
{
polls: Array<{
id: string,
question: string,
createdBy: string,
timestamp: number,
options: Array<{
id: string,
text: string,
votes: number,
votedBy: string[], // Tracks which users have voted
createdBy: string,
timestamp: number
}>
}>
}
```
## Testing P2P Functionality
1. Open the app in multiple browser tabs/windows
2. **Create polls** from different tabs - they appear everywhere instantly
3. **Add answer options** from different tabs to the same poll
4. **Vote** from different tabs - watch vote counts update in real-time
5. Try voting twice on the same option - it won't let you!
6. Check the connection status indicator for peer count
7. Verify visual feedback (green border) on options you've voted on
## Development
### Backend Scripts
- `npm run dev` - Start development server with hot reload
- `npm run build` - Build for production
- `npm start` - Run production build
### Frontend Scripts
- `npm run dev` - Start Vite dev server
- `npm run build` - Build for production
- `npm run preview` - Preview production build
## Environment Variables
### Backend (.env)
```
PORT=3000
YJS_WS_PORT=1234
NODE_ENV=development
CORS_ORIGIN=http://localhost:5173
```
### Frontend (.env)
```
VITE_WS_URL=ws://localhost:3000
```
## Components
### Frontend Components
- **PollView** - Main view showing all polls and create poll form
- **CreatePoll** - Form to create new polls
- **PollCard** - Individual poll display with metadata
- **OptionList** - List of answer options with vote tracking
- **AddOption** - Form to add new answer options
- **VoteButton** - Vote button with disabled state for voted options
- **ConnectionStatus** - Shows WebSocket and P2P connection status
### Key Functions
- `createPoll(question)` - Create a new poll
- `addOption(pollId, text)` - Add an option to a specific poll
- `vote(pollId, optionId)` - Vote on an option (one vote per user)
- `hasVoted(option)` - Check if current user has voted on an option
## User Tracking
Each user gets a unique ID stored in localStorage:
- Format: `user-xxxxxxxxx`
- Used to track poll/option creators
- Used to prevent duplicate voting
- Persists across browser sessions
## Future Enhancements
- [ ] Edit/delete polls and options
- [ ] User nicknames instead of IDs
- [ ] Poll expiration/closing
- [ ] Vote history and analytics
- [ ] Export poll results
- [ ] Persistent storage (database)
- [ ] Dark mode toggle
- [ ] Mobile responsive improvements
- [ ] Poll categories/tags
- [ ] Search/filter polls
## License
MIT