forked from quic-issues/427e7578-d7bf-49c8-aee9-2dd999e25316
2.6 KiB
2.6 KiB
status, created, tags, priority, created_at, depends_on, updated_at, completed_at, completed, transitions
| status | created | tags | priority | created_at | depends_on | updated_at | completed_at | completed | transitions | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| complete | 2026-03-16 |
|
high | 2026-03-16T07:57:36.544Z |
|
2026-03-16T10:01:29.167Z | 2026-03-16T10:01:29.167Z | 2026-03-16 |
|
Poll Snapshot Server
Status: ✅ Complete · Priority: High · Created: 2026-03-16 · Tags: server, infra
Overview
A minimal server that stores poll snapshots for public/offline viewing. This is the only server-side component — intentionally thin. No user accounts, no directory, no auth beyond signature verification.
Design
Tech Stack
- Runtime: Cloudflare Workers (or a simple Bun server if self-hosting)
- Storage: Cloudflare KV (or SQLite for self-hosted)
- Auth: Snapshot writes are signed with the poll owner's Ed25519 private key
API Endpoints
PUT /api/polls/:id/snapshot— Store/update snapshot (signed by poll owner)- Body:
{ pollId, ownerId, ownerPeerId, title, description, options[], voteCounts, status, signature }
- Body:
GET /api/polls/:id/snapshot— Fetch snapshot (public, no auth)
Security
- Write operations require a valid Ed25519 signature
- Verify signature against
ownerIdin the request body; bindpollId → ownerIdon first write; reject future writes ifownerIdchanges - No sessions, no cookies, no passwords
- Rate limiting on writes to prevent abuse
Data Model
// KV key: poll:{pollId}:snapshot → PollSnapshot
interface PollSnapshot {
pollId: string;
ownerId: string;
ownerPeerId: string;
title: string;
description: string;
options: { id: string; text: string }[];
voteCounts: Record<string, number>;
status: 'draft' | 'open' | 'closed';
updatedAt: number;
}
Plan
- Set up Cloudflare Workers project (or simple Bun server)
- Implement Ed25519 signature verification middleware
- Implement poll snapshot store/fetch endpoints
- Add rate limiting
- Deploy
Test
- Snapshot store with valid signature succeeds
- Snapshot store with invalid signature is rejected
- Snapshot fetch returns stored data (public, no auth)
- Second write from different ownerId is rejected
- Rate limiting works
Notes
- The P2P app works without this server — it just loses public sharing and offline snapshot viewing
- Future: user directory endpoints can be added here when peer discovery is implemented (see archived spec 007)
- Consider a TTL on snapshots (e.g., auto-expire 90 days after last update)