Originally written for the Tabletop Society, this was cut out in the pandemic to avoid having to use the SU's voting platform. It is hosted at https://vote.uwcs.co.uk/ and the source is available here.
It uses Keycloak to proxy ITS login. It is currently hosted on Portainer from an image auto-built from the repo CI.
Here are some basic instructions on how to run an election. More detailed instructions are WIP below.
Step 1: Create the election
Login, go to the elections tab. An orange Admin button should be visible.
In that menu, click Create New
Fill out the name and description. I would recommend making the name unique so you can recognise it in lists that aren't always meaningfully sorted.
Vote type you can either have STV, First past the post, or Approval vote.
STV then needs the seat setting to the relevant number of people to select when it runs
Approval need the max votes set to the maximum number of candidates to allow each voter to select
First past the post ignores both of these values.
At this point, do not check the open checkbox.
Click Save
Step 2: Adding candidates
After clicking save, find the election in the top list shown in the admin panel.
Clicking on it should show the previous edit page with an additional section for adding candidates
For each candidate, click Create New, put in their name in the new dialogue (leave the description blank until they send it to you), and click save. Leave them as Standing for now.
They should then appear in the candidates list. You can edit or remove existing candidates using the provided blue and red buttons.
I would strongly recommend you add RON at this point (I forgot on my first election until a few minutes after opening voting...)
Repeat step 1 and 2 for all elections
Step 3: Generating tickets
For this step, you will need a list of eligible voter IDs extracted from the SU admin pages. Ask one of the current execs to provide this for you.
Go back to the admin menu.
Click Issue Tickets
Paste the list of whitespace separated uni IDs (without any letter prefix) into the top box
Select all the elections you are running this session in the bottom box (using ctrl or shift to select more than one)
Click Save
. This will take a while if you have a lot of uni ids or elections selected as it has to create a database entry for each pair
Step 4: Opening the election
At the start of the election period, select the election in the top list of the admin, check Open, and then click save.
All users with tickets will then be able to see that election in their elections section of the website.
Step 5: Closing the election and getting results
Once the election period is over, find it in the top list, uncheck Open
, and then click Save
.
To view the results, select the election in the bottom list in the admin panel
Note: Do not click on the results of a STV election before you have finished the election. It will run the calculator only once, and any further votes will not be reflected (Contact me (@anotherbruce on discord) if you need to fix having done this by accident)
The results page will list the number of votes for each candidate for Approval and FPtP elections, or the winners and an election log for STV. Feel free to contact me (@anotherbruce on discord) if you need any help interpreting the election log, as its not user friendly at all. A PR is pending that will make it a lot easier to understand.
Running an election requires that the returning officer be given the "Staff" property and at least the following permissions (which may have been combined into a role):
votes.view_election
votes.add_election
votes.change_election
votes.add_ticket
votes.add_candidate
votes.update_candidate
Elections typically progress through five main phases:
To create an election, first visit the vote admin page and select Create New
.
This then lets you setup the name (which appears in the voting list and the top of the voting page), the description (which is rendered as markdown on the voting page and provides a space to describe the role or motion being voted on), and which type of voting method it should use. Do not tick Open
at this point
The following voting methods are currently available:
Max votes
number), and the candidate who had the most votes across all voters wins.Seats
option. This is the preferred option for Exec electionsOnce you click save, the election will appear in the list of live elections on the admin page. Once nominations start coming in, you can select it from this list and add candidates at the bottom of the edit page.
Each candidate can have a name and a short description that will appear on the voting page. I'd strongly recommend limiting the description to about 30 words, as if it gets too long it can be hard to order the preferences in the voting screen. Leave the candidate's State
as Standing
at this point.
Tickets map users to elections. Each user needs a ticket in order to vote, and each ticket can only be used to vote once before it is spent.
Before opening an election, you need to issue all eligible people tickets. To do this, you need first need to download a list of University IDs from the SU system for all eligible members (as typically you have to have been a member for at least two before the election). This then needs to be formatted such that each ID is separated by whitespace, without any letter prefix. An example of a correctly formatted list is below:
1605235
1316485
1245671
Next, go to the admin page and select Manage Tickets
. Next select how you'd like to issue tickets, currently only ID list
is supported. Paste the list of IDs into the IDs
box, and then select all the elections you'd like to issue tickets for from the Elections
list.
Once you click Save
this will then create a ticket for each person for each election. This process may take a while when the membership is large.
It is safe to issue tickets multiple times for the same election, even after it has been opened, and the resulting ticket set will be the union of all issues. No user can ever be issued more than one ticket per election and no ticket can be used more than once (even after more tickets have been issued).
Once the candidates have all been entered, and the tickets issued, you can then open the voting.
For each election that needs opening, select it from the list in the admin page.
Pro tip: This is the perfect point to double check all the details are correct, as adding or removing candidates after you open it is likely to get the vote appealed. If this is an exec election, double check you've added a RON option!
Once you are sure all the details are correct, check the Open
option and click Save
. The vote will now appear on the main vote list, and will also appear on the admin panel under Live Votes
with an approximate vote count.
If someone comes to you saying they miscast their vote, you can reset it by using the Reset User Vote
button. The voter must have noted their vote UUID (which is shown on the success page after they voted) before this can be performed. Please be very careful when doing this that you are sure that the person is the actual person who cast it, and that they understand this removes their vote from the election unless they actually vote again. Misusing this feature can easily invalidate the result in the SU's eyes, so tread carefully.
Once the voting period is finished, you should then close the vote. If you want to close all votes simultaneously, you can use the Close all votes
button, alternatively you can select each election from the Change
list and untick Open
to only close a subset of the elections.
Assuming that at least one vote was cast, the newly closed vote will now appear under the Results
heading.
If any of the candidates have withdrawn since the vote opening (possibly as a result of having won a separate election), you can withdraw then from an election by editing the State
property on their candidacy from the Change Election form. You must do this before viewing the election result for the first time, as STV results are permanently cached (to prevent abusing random eliminations).
Once the elections are all finished and the appeals window is over (typically 7 days after the results are announced), you should delete the tickets for the elections. These technically permit (though with an intentionally painful amount of work) the reverse-engineering of who voted for what. This is needed in the case of an appeal to determine if votes were tampered with somehow, but should not be allowed to hang around indefinitely.
To do this go into Manage Tickets
, and select Delete Tickets
. Select all the elections that should be santized from the list, and then click Delete
This will then delete all the tickets for the votes, which may take a while.
Once an election is well and truly done with, it can be archived from the django-admin site, by selecting all the desired elections, and using the Archive selected elections (if closed)
option in the action dropdown. This will prevent it appearing anywhere in the main UI, useful to prevent previous years cluttering up the interface.