--- status: planned created: '2026-03-16' tags: - voting - core priority: high created_at: '2026-03-16T07:51:50.525Z' depends_on: - 005-poll-creation-management updated_at: '2026-03-16T09:18:58.099Z' related: - 011-mobile-first-ui --- # Voting System & Anonymity > **Status**: πŸ—“οΈ Planned Β· **Priority**: High Β· **Created**: 2026-03-16 Β· **Tags**: voting, core ## Overview Core voting functionality: participants can add options to a poll and cast votes. Supports both anonymous and non-anonymous modes as configured at poll creation. Votes are sent to the poll owner via PeerJS. ## Design ### Adding Options - Participants and above can add options while the poll is `open` - Options have text only (keep it simple) - Owner validates the sender has permission before accepting ### Casting Votes - V1: single-choice (one vote per participant). Data model uses `optionId: string` which can later be extended to `optionIds: string[]` for multi-choice or a ranked array for ranked-choice. - Vote is signed with voter's private key for authenticity - In anonymous mode: owner records the vote but strips `voterId` before storing - In non-anonymous mode: `voterId` is stored alongside the vote - Vote changes: a participant can change their vote while the poll is open (replaces previous) ### Results - Results are visible to all roles (viewers included) - Show: option text, vote count, percentage - Non-anonymous: also show who voted for what - Results update in real-time via PeerJS messages ### Vote Flow ``` Participant Owner (relay) β”‚ β”‚ │─── poll:vote ───────────────▢│ validate permission β”‚ β”‚ if anonymous: strip voterId β”‚ β”‚ store vote │◀── poll:state:update ───────│ broadcast updated results ``` ## Plan - [ ] Build "add option" UI and message handler - [ ] Build voting UI (option list with vote button) - [ ] Implement vote submission (sign + send to owner) - [ ] Owner-side vote processing (validate, anonymize if needed, store) - [ ] Build results display (bar chart or simple percentage view) - [ ] Implement vote change (replace previous vote) ## Test - [ ] Participant can add an option - [ ] Participant can cast a vote - [ ] Anonymous vote does not leak voter identity - [ ] Results update in real-time across connected peers - [ ] Vote change replaces (not duplicates) previous vote - [ ] Viewers can see results but not vote