Skip to content

Commit

Permalink
Added candidate nomination structs to openapi
Browse files Browse the repository at this point in the history
  • Loading branch information
Lionqueen94 committed Mar 6, 2025
1 parent 3e91919 commit 4dd8743
Show file tree
Hide file tree
Showing 5 changed files with 130 additions and 6 deletions.
93 changes: 92 additions & 1 deletion backend/openapi.json
Original file line number Diff line number Diff line change
Expand Up @@ -1787,6 +1787,42 @@
"X"
]
},
"CandidateNominationResult": {
"type": "object",
"description": "The result of the candidate nomination procedure.\nThis contains the preference threshold and percentage that was used.\nIt contains a list of all chosen candidates in alphabetical order.\nIt also contains the preferential nomination of candidates, the remaining\nnomination of candidates and the final ranking of candidates for each political group.",
"required": [
"preference_threshold_percentage",
"preference_threshold",
"chosen_candidates",
"political_group_candidate_nomination"
],
"properties": {
"chosen_candidates": {
"type": "array",
"items": {
"$ref": "#/components/schemas/Candidate"
},
"description": "List of chosen candidates in alphabetical order"
},
"political_group_candidate_nomination": {
"type": "array",
"items": {
"$ref": "#/components/schemas/PoliticalGroupCandidateNomination"
},
"description": "List of chosen candidates and candidate list ranking per political group"
},
"preference_threshold": {
"$ref": "#/components/schemas/Fraction",
"description": "Preference threshold number of votes"
},
"preference_threshold_percentage": {
"type": "integer",
"format": "int64",
"description": "Preference threshold percentage",
"minimum": 0
}
}
},
"CandidateVotes": {
"type": "object",
"required": [
Expand Down Expand Up @@ -1997,7 +2033,7 @@
},
"ElectionApportionmentResponse": {
"type": "object",
"description": "Election details response, including the election's candidate list (political groups) and its polling stations",
"description": "Election apportionment response, including the seat assignment, candidate nomination and election summary",
"required": [
"seat_assignment",
"election_summary"
Expand Down Expand Up @@ -2442,6 +2478,57 @@
}
}
},
"PoliticalGroupCandidateNomination": {
"type": "object",
"description": "Contains information about the chosen candidates and the candidate list ranking\nfor a specific political group.",
"required": [
"pg_number",
"pg_name",
"pg_seats",
"preferential_candidate_nomination",
"other_candidate_nomination",
"candidate_ranking"
],
"properties": {
"candidate_ranking": {
"type": "array",
"items": {
"$ref": "#/components/schemas/CandidateVotes"
},
"description": "The ranking of the whole candidate list, can be empty"
},
"other_candidate_nomination": {
"type": "array",
"items": {
"$ref": "#/components/schemas/CandidateVotes"
},
"description": "The list of other chosen candidates, can be empty"
},
"pg_name": {
"type": "string",
"description": "Political group name for which this nomination applies"
},
"pg_number": {
"type": "integer",
"format": "int32",
"description": "Political group number for which this nomination applies",
"minimum": 0
},
"pg_seats": {
"type": "integer",
"format": "int32",
"description": "The number of seats assigned to this group",
"minimum": 0
},
"preferential_candidate_nomination": {
"type": "array",
"items": {
"$ref": "#/components/schemas/CandidateVotes"
},
"description": "The list of chosen candidates via preferential votes, can be empty"
}
}
},
"PoliticalGroupSeatAssignment": {
"type": "object",
"description": "Contains information about the final assignment of seats for a specific political group.",
Expand Down Expand Up @@ -3069,6 +3156,10 @@
}
},
"tags": [
{
"name": "apportionment",
"description": "Election apportionment API"
},
{
"name": "authentication",
"description": "Authentication and user API"
Expand Down
2 changes: 1 addition & 1 deletion backend/src/apportionment/api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ use crate::{
summary::ElectionSummary,
};

/// Election details response, including the election's candidate list (political groups) and its polling stations
/// Election apportionment response, including the seat assignment, candidate nomination and election summary
#[derive(Serialize, Deserialize, ToSchema, Debug)]
pub struct ElectionApportionmentResponse {
pub seat_assignment: SeatAssignmentResult,
Expand Down
9 changes: 6 additions & 3 deletions backend/src/apportionment/candidate_nomination.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ pub struct CandidateNominationResult {
pub political_group_candidate_nomination: Vec<PoliticalGroupCandidateNomination>,
}

/// Create a vector containing just the political group numbers from an iterator of the current standing
/// Create a vector containing just the candidate numbers from an iterator of candidate votes
fn candidate_numbers(candidate_votes: &[CandidateVotes]) -> Vec<CandidateNumber> {
candidate_votes
.iter()
Expand Down Expand Up @@ -122,7 +122,7 @@ fn other_candidate_nomination(
fn candidate_nomination_per_political_group(
totals: &ElectionSummary,
preference_threshold: Fraction,
final_standing: Vec<PoliticalGroupSeatAssignment>,
final_standing: &[PoliticalGroupSeatAssignment],
political_groups: Vec<PoliticalGroup>,
) -> Result<Vec<PoliticalGroupCandidateNomination>, ApportionmentError> {
let mut political_group_candidate_nomination: Vec<PoliticalGroupCandidateNomination> = vec![];
Expand All @@ -134,12 +134,14 @@ fn candidate_nomination_per_political_group(
candidates_meeting_preference_threshold(preference_threshold, candidate_votes);
let preferential_candidate_nomination =
preferential_candidate_nomination(&candidates_meeting_preference_threshold, pg_seats)?;

Check warning on line 136 in backend/src/apportionment/candidate_nomination.rs

View check run for this annotation

Codecov / codecov/patch

backend/src/apportionment/candidate_nomination.rs#L122-L136

Added lines #L122 - L136 were not covered by tests

// [Artikel P 17 Kieswet](https://wetten.overheid.nl/jci1.3:c:BWBR0004627&afdeling=II&hoofdstuk=P&paragraaf=3&artikel=P_17&z=2025-02-12&g=2025-02-12)
let other_candidate_nomination = other_candidate_nomination(
&preferential_candidate_nomination,
candidate_votes,
pg_seats as usize - preferential_candidate_nomination.len(),
);

// TODO: #1045 Article P 19 reordering of political group candidate list if seats have been assigned
// [Artikel P 19 Kieswet](https://wetten.overheid.nl/jci1.3:c:BWBR0004627&afdeling=II&hoofdstuk=P&paragraaf=3&artikel=P_19&z=2025-02-12&g=2025-02-12)
let candidate_ranking = vec![];
Expand All @@ -161,7 +163,7 @@ pub fn candidate_nomination(
election: Election,
quota: Fraction,
totals: &ElectionSummary,
final_standing: Vec<PoliticalGroupSeatAssignment>,
final_standing: &[PoliticalGroupSeatAssignment],
) -> Result<CandidateNominationResult, ApportionmentError> {
info!("Candidate nomination");

Check warning on line 168 in backend/src/apportionment/candidate_nomination.rs

View check run for this annotation

Codecov / codecov/patch

backend/src/apportionment/candidate_nomination.rs#L162-L168

Added lines #L162 - L168 were not covered by tests

Expand All @@ -185,6 +187,7 @@ pub fn candidate_nomination(
final_standing,
election.political_groups.unwrap_or_default(),
)?;

Check warning on line 189 in backend/src/apportionment/candidate_nomination.rs

View check run for this annotation

Codecov / codecov/patch

backend/src/apportionment/candidate_nomination.rs#L184-L189

Added lines #L184 - L189 were not covered by tests

// TODO: Create ordered chosen candidates list
let chosen_candidates = vec![];

Expand Down
3 changes: 3 additions & 0 deletions backend/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -188,9 +188,11 @@ pub fn create_openapi() -> utoipa::openapi::OpenApi {
schemas(
ErrorResponse,
apportionment::AssignedSeat,
apportionment::CandidateNominationResult,
apportionment::DisplayFraction,
apportionment::LargestAverageAssignedSeat,
apportionment::LargestRemainderAssignedSeat,
apportionment::PoliticalGroupCandidateNomination,
apportionment::PoliticalGroupStanding,
apportionment::SeatAssignmentResult,
apportionment::SeatAssignmentStep,
Expand Down Expand Up @@ -232,6 +234,7 @@ pub fn create_openapi() -> utoipa::openapi::OpenApi {
),
),
tags(
(name = "apportionment", description = "Election apportionment API"),
(name = "authentication", description = "Authentication and user API"),
(name = "election", description = "Election API"),
(name = "polling_station", description = "Polling station API"),
Expand Down
29 changes: 28 additions & 1 deletion frontend/lib/api/gen/openapi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,20 @@ export interface Candidate {
*/
export type CandidateGender = "Male" | "Female" | "X";

/**
* The result of the candidate nomination procedure.
This contains the preference threshold and percentage that was used.
It contains a list of all chosen candidates in alphabetical order.
It also contains the preferential nomination of candidates, the remaining
nomination of candidates and the final ranking of candidates for each political group.
*/
export interface CandidateNominationResult {
chosen_candidates: Candidate[];
political_group_candidate_nomination: PoliticalGroupCandidateNomination[];
preference_threshold: Fraction;
preference_threshold_percentage: number;
}

export interface CandidateVotes {
number: number;
votes: number;
Expand Down Expand Up @@ -247,7 +261,7 @@ export interface Election {
}

/**
* Election details response, including the election's candidate list (political groups) and its polling stations
* Election apportionment response, including the seat assignment, candidate nomination and election summary
*/
export interface ElectionApportionmentResponse {
election_summary: ElectionSummary;
Expand Down Expand Up @@ -424,6 +438,19 @@ export interface PoliticalGroup {
number: number;
}

/**
* Contains information about the chosen candidates and the candidate list ranking
for a specific political group.
*/
export interface PoliticalGroupCandidateNomination {
candidate_ranking: CandidateVotes[];
other_candidate_nomination: CandidateVotes[];
pg_name: string;
pg_number: number;
pg_seats: number;
preferential_candidate_nomination: CandidateVotes[];
}

/**
* Contains information about the final assignment of seats for a specific political group.
*/
Expand Down

0 comments on commit 4dd8743

Please sign in to comment.