Files
427e7578-d7bf-49c8-aee9-2dd…/README.md
yannickschuchmann a7b81d5791 Add README documentation and refactor test suite
Replace minimal README with full project docs (setup, usage, architecture).
Remove trivial tests and add meaningful edge case coverage.
2026-03-08 20:39:15 +00:00

92 lines
3.4 KiB
Markdown

# P2P Poll App
A peer-to-peer polling application where users can create polls, add options, and vote — all without a central server. Built for the [Evocracy democratic coding research experiment](https://demcode.evocracy.org/).
## How It Works
Data is synchronized directly between peers using [Automerge](https://automerge.org/) CRDTs (Conflict-free Replicated Data Types). There is no backend database — every client holds a full copy of the poll document and changes merge automatically, even when made offline or concurrently.
**Sync layers:**
- **WebSocket** (`wss://sync.automerge.org`) — cross-device sync via a public relay
- **BroadcastChannel** — instant cross-tab sync within the same browser
- **IndexedDB** — local persistence across page reloads and offline use
## Requirements
- [Bun](https://bun.sh/) (standalone runtime, no Node.js needed)
## Getting Started
```bash
bun install # Install dependencies
bun run dev # Start dev server (http://localhost:3000)
```
## Usage
1. **Create a poll** — Enter a title on the home page and click "Create"
2. **Share it** — Copy the shareable link and send it to others
3. **Vote** — Click an option to vote; click again to unvote
4. **Add options** — Anyone with the link can add new poll options
Each browser gets a stable peer ID (stored in localStorage) so votes are tracked per-device and double-voting is prevented.
## Tech Stack
| Layer | Technology |
|---|---|
| Runtime | [Bun](https://bun.sh/) |
| Framework | [Waku](https://waku.gg/) (React Server Components) |
| Styling | Tailwind CSS v4 |
| P2P sync | Automerge + automerge-repo |
| Storage | IndexedDB (client-side) |
## Project Structure
```
src/
├── pages/ # Waku page router
│ ├── _root.tsx # HTML document shell
│ ├── _layout.tsx # Root layout + Providers
│ ├── index.tsx # Home page (create/join polls)
│ └── poll/[id].tsx # Poll view page
├── components/
│ ├── Providers.tsx # Automerge Repo initialization
│ ├── HomeClient.tsx # Create/join poll UI
│ ├── PollPageClient.tsx # Poll ID validation
│ ├── PollView.tsx # Poll display, voting, options
│ └── ConnectionStatus.tsx # P2P connection indicator
├── lib/
│ ├── types.ts # Poll & PollOption interfaces
│ ├── repo.ts # Automerge Repo singleton
│ ├── poll.ts # Pure poll mutation functions
│ ├── peer.ts # Peer ID management
│ └── __tests__/ # Unit tests
└── styles/
└── global.css # Tailwind CSS
```
## Testing
```bash
bun test
```
Covers poll creation, voting/unvoting, double-vote prevention, option management, and peer ID persistence.
## Architecture Notes
- **Pure business logic** — Poll mutations in `src/lib/poll.ts` are pure functions, used inside Automerge's `changeDoc()` for CRDT-safe updates
- **No server state** — The WebSocket relay only forwards sync messages; it never stores or processes poll data
- **Offline-first** — The app works fully offline; changes sync when connectivity resumes
- **Conflict-free** — Concurrent edits (e.g., two users voting at the same time) merge automatically without conflicts
## Built With
This project was built in collaboration with [Claude Code](https://claude.ai/code), Anthropic's agentic coding tool.
## License
MIT