Conversation
ArendPeter
left a comment
There was a problem hiding this comment.
Mostly nitpicks, but overall it looks good!
| @@ -0,0 +1,12 @@ | |||
| import { Uid } from "./Uid"; | |||
There was a problem hiding this comment.
Note that @recursivesquircle is working on shorter IDs at the moment.
#733
Depending on when this is merged you may need to rebase so that the race id uses the new format
There was a problem hiding this comment.
Good to know and I'll keep an eye out, but this is just the Uid type which is just a string which I doubt will change.
| const candidateNames = race.candidates.map((Candidate: any) => (Candidate.candidate_name)) | ||
| const candidateIDs = race.candidates.map((Candidate: any) => (Candidate.candidate_id)) | ||
| const useWriteIns = race.enable_write_in && race.write_in_candidates && race.write_in_candidates.length>0 | ||
| const writeInCandidates = useWriteIns && race.write_in_candidates ? race.write_in_candidates : [] |
There was a problem hiding this comment.
nit, I think you can avoid the terinary expression by doing ```race.write_in_candidates ?? []``
There was a problem hiding this comment.
I'll give that a shot but I may have tried that. Typescript wasn't very cooperative in this section.
| const writeInCandidateIndex = writeInCandidates.findIndex(candidate => candidate.aliases.includes(write_in_name) && candidate.approved) | ||
| if (writeInCandidateIndex >= 0) { | ||
| row[writeInCandidateIndex + candidateNames.length] = score.score | ||
| } |
There was a problem hiding this comment.
Should we add an else clause to throw (or log) a warning?
Feels like the writeInCandidateIndex is expected to always resolve
There was a problem hiding this comment.
It wouldn't in the case that the write in candidate wasn't approved by the admin. But maybe that should be a separate check? First check if they are an alias to a candidate, if not throw error and admin can revisit write in section. Then check if approved, then add score.
There was a problem hiding this comment.
Actually, maybe it would be better to have a counter for unprocessed write ins. That way the results can still be retrieved live and display with the results that X write in names are still unprocessed.
There was a problem hiding this comment.
Updated results to have an unprocessed write in candidate count
There was a problem hiding this comment.
Nice! Yeah I was just thinking that we should have some default write-in behavior in addition to allowing the admin to configure the aliases
Counting each new variation as it's own candidate is a good starting point, but I could also see us performing some minimal typo checks by default.
| if (!election.races[race_index].enable_write_in) { | ||
| throw new BadRequest('Write-In not enabled for this race') | ||
| } | ||
| election.races[race_index].write_in_candidates = write_in_results.write_in_candidates |
There was a problem hiding this comment.
Should we also update write_in_candidates during the cast vote flow to ensure that any new write ins are added as new candidates or alias?
There was a problem hiding this comment.
I'd rather not update the election every time a vote is cast. I was thinking the write in processing would occur after all votes are entered. Or the admin can do processing as the election is running.
|
Write-in issue number: #730 |
Description
Work in progress, do not merge! Just wanted to get some eyes on it.
This adds write in fields to the domain models, adds routes for getting the write in names and setting the processed write in names, and updates to the results processing to check for write ins in the ballots and assign the scores to the correct candidates.
In the race object, enable_write_in has been added which will be a setting in the race menu. This enables the write in field on the ballot and allows the backend to include them for tabulation.
On the score object in the ballot, a write in name has been added.
A new route getWriteIns provides the admin with a list of all write in names and their number of occurrences for each race. The admin then processes the names, groups any similar or misspelled names together, and approves or rejects them the candidates.
Admin then uses a new route setWriteInResults to save the processed write in data to the election.
While processing the results, if it comes across a vote with an invalid candidate ID but with a write in name, it checks if that write in name is an alias of an approved write in candidate and maps the scores. This required updating the code to check all of the candidate IDs of the votes and make sure they map to the candidate IDs in the race.