Skip to main content

Election authoring

Org admins create org-wide elections — typically national board roles or other org-level votes. Chapter elections are managed by chapter officers. → Running an election (officers)

Deep dives for each surface: Authoring an election · Positions & candidates · Results & live tracking

Election model at a glance

A GreekManage election has:

  • Status: Draft → Open → Finalized
  • Opens at / Closes at timestamps (Celery tasks open and finalize automatically)
  • Eligible voter statuses — a list of Membership.Status values. When left blank, the server falls back to Membership.ACTIVE_MEMBER_STATUSES, which is ["undergrad", "associate"] — alumni and officer-only ballots require setting the field explicitly. The eligible voter set is snapshotted when the election opens.
  • One or more positions, each with a title and display order.
  • One or more candidates per position. Each candidate is a member with an optional bio.

Voters cast one vote per position. Votes can be for a specific candidate or an abstention. Each ballot is recorded with a hashed IP via VoteAuditLog. Live admin tracking is delivered over a WebSocket; final results are written to ElectionResult on finalize.

Create an org-wide election

Elections page with the New Election action and existing elections list. Elections page with the New Election action and existing elections list.

  1. Open Org → ElectionsNew election.
  2. Set:
    • Name and Year
    • Opens at / Closes at
    • Eligible statuses (leave blank to default to undergrad + associatenot officers; add officer or any alumni status explicitly if you want them to vote)
    • Optional Confirmation email subject / body sent to voters when their ballot is recorded
  3. Add positions (title + order).
  4. For each position, add candidates (members from your org with an optional bio).
  5. Save as Draft. The Celery task will flip the election to Open at opens_at and finalize at closes_at.

Eligibility

Eligibility is filtered only by membership status. Region- or chapter-scoped eligibility, custom-field filters, and delegate lists are not supported by the current model.

Audit and finalization

Every vote writes a VoteAuditLog with a hashed IP and timestamp. On finalize, GreekManage tallies votes per position, records ElectionResult rows with vote counts and percentages, and marks the winner per position based on highest vote count.

Results are accessible to admins and (per configuration) to members via the elections frontend. A finalized export to XLSX is available via the export endpoint.

What's not built today

  • No runoff handling, no second-round logic.
  • No multi-stage / nomination → vetting → ballot workflow.
  • No "constitutional amendment" / passing-threshold workflow distinct from the candidate vote model.
  • No re-authentication step at ballot submission.
  • No certification PDF generation. (You can export results to XLSX for board reports.)

Tips

  • Pilot with a low-stakes election first. Get comfortable with the open/close timing and ballot UX before high-stakes votes.
  • Publish the timeline early. A communicated open and close date prevents "I didn't know" disputes.
  • Snapshot your member statuses before opening. Eligibility is captured at open time; status changes after that don't affect the ballot.

Last verified against v0.63.18 (2026-06-18).