USRSE / USRSE/usrse.github.io

feat(elections): build elections.us-rse.org to replace ElectionBuddy [epic]

Open
#1,933 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
HTML
Stars
33
Forks
104
Avg merge
12h 3m
Merged PRs (30d)
10

Description

Summary

Build a ranked-choice voting application at elections.us-rse.org that replaces our dependency on ElectionBuddy. The app will live in this repo alongside the marketing site, share the design-system, and support both single-winner (IRV) and multi-winner (STV) races used by US-RSE elections.

Goals

  • Eliminate recurring ElectionBuddy cost and give US-RSE full control over the election platform.
  • Support ranked-choice voting (IRV for single seats, STV for multi-seat board elections).
  • Preserve ballot secrecy: voter identity is separated from the submitted ballot.
  • Provide a trustworthy audit trail for each election.
  • Meet WCAG 2.2 AA accessibility for the voter-facing ballot.

Architectural decisions

  • Monorepo tooling: Turborepo (apps/web for marketing, apps/elections for the voting app, packages/design-system for shared CSS tokens).
  • Backend: Convex (reactive DB, serverless functions, scheduled jobs, built-in auth helpers).
  • Voter authentication: Emailed unique voting tokens. Admin uploads voter roll; each voter receives a one-time magic link. Ballot anonymized on submission.
  • Tabulation: Both IRV and STV implemented as configurable race types.

Scope (child issues)

Foundation

  • #1934 — chore(repo): migrate to Turborepo monorepo
  • #1935 — feat(elections): scaffold elections app + Convex backend
  • #1936 — build(elections): deploy elections.us-rse.org (DNS, hosting, CI/CD)

Data & admin

  • #1937 — feat(elections): Convex schema for elections, races, candidates, voters, ballots
  • #1938 — feat(elections): admin UI for election and race configuration
  • #1939 — feat(elections): admin voter roll CSV import and token generation
  • #1940 — feat(elections): transactional email delivery for voting tokens

Voting experience

  • #1941 — feat(elections): accessible ranked-choice ballot UI
  • #1942 — feat(elections): token-gated voting route with one-time-use and ballot secrecy

Tabulation & results

  • #1943 — feat(elections): IRV tabulation engine with test fixtures
  • #1944 — feat(elections): STV tabulation engine with test fixtures
  • #1945 — feat(elections): results UI with round-by-round visualization

Trust & ops

  • #1946 — feat(elections): audit log and election lifecycle state machine

Suggested sequencing

  1. Foundation: #1934 → #1935 → #1936
  2. Data: #1937 → #1938 → #1939 → #1940
  3. Voting: #1941 in parallel with #1942
  4. Tabulation: #1943 → #1944 → #1945
  5. Trust: #1946 (can start once #1937 and #1938 land; finalize after #1940)

Out of scope (for now)

  • Multi-org/tenant support (only US-RSE elections).
  • Live streaming / real-time result broadcasting during open voting.
  • Voter identity verification beyond token possession.
  • Importing historical ElectionBuddy results.

Non-negotiables

  • Ballot secrecy is preserved end-to-end — no admin query can map a submitted ballot back to a voter identity.
  • One-person-one-ballot is enforced at the token layer.
  • Every state change on an election (config, open, close, publish) is recorded in an audit log.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.