USRSE / USRSE/usrse.github.io

feat(elections): Convex schema for elections, races, candidates, voters, ballots

Open
#1,937 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

Define the Convex schema that backs the entire elections domain. This is the foundation for admin UIs, ballot submission, and tabulation.

Part of #1933.

Requirements

  • `elections` table: title, description, opensAt, closesAt, status (draft|open|closed|published), createdBy, createdAt
  • `races` table: electionId, title, description, seats, method (irv|stv), order
  • `candidates` table: raceId, name, bio, order
  • `voters` table: electionId, email, name, status (invited|voted|revoked)
  • `voterTokens` table: voterId, tokenHash, expiresAt, usedAt — stores only hashed tokens, never plaintext
  • `ballots` table: electionId, raceId, rankings (ordered candidateId array), submittedAt — no voterId link (enforced by schema, not just convention)
  • `tokenRedemptions` table: tokenHash, redeemedAt — separate table so ballot has no timing correlation with a specific voter
  • `auditLog` table: electionId, actor, action, metadata, createdAt
  • Add appropriate indexes for each common query pattern
  • Seed script that creates a dev election with sample races/candidates/voters for local testing
  • Document the ballot-secrecy guarantee in a schema-level comment

Context

  • Epic: #1933
  • Depends on the elections app scaffold issue
  • This schema is the contract for every downstream issue — changes after this lands will cascade.

Implementation notes

  • Enforce ballot secrecy in schema shape, not just code conventions — the `ballots` table should physically not have a column that could identify a voter
  • Token hash: sha256 with a per-election salt stored in Convex env
  • Consider whether `rankings` needs a separate `ballotEntries` table if we want per-rank queries later — probably not; arrays are fine

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.

Research direction

Start with the elections app scaffold from #1933 and the repository’s existing Convex schema conventions. Define the listed tables, indexes, seed data, and schema-level ballot-secrecy comment, then verify locally with the development election and downstream schema checks if available. Done means the required fields, secrecy constraints, token-hashing requirements, and sample records are represented.

Written by the indexing model from the issue text.

Assessment

Domain
backend, database, security
Issue type
Feature
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
55/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.