1- import logging
21import re
32from datetime import datetime
43
76
87import database
98import elections
9+ import elections .crud
1010import elections .tables
11+ from elections .models import ElectionModel , NomineeApplicationModel , NomineeInfoModel
1112from elections .tables import Election , NomineeApplication , NomineeInfo , election_types
1213from officers .constants import OfficerPosition
1314from officers .crud import get_active_officer_terms
1415from permission .types import ElectionOfficer , WebsiteAdmin
16+ from utils .shared_models import SuccessFailModel
1517from utils .urls import is_logged_in
1618
17- _logger = logging .getLogger (__name__ )
18-
1919router = APIRouter (
2020 prefix = "/elections" ,
2121 tags = ["elections" ],
@@ -28,9 +28,9 @@ def _slugify(text: str) -> str:
2828async def _validate_user (
2929 request : Request ,
3030 db_session : database .DBSession ,
31- ) -> tuple [bool , str , str ]:
31+ ) -> tuple [bool , str | None , str | None ]:
3232 logged_in , session_id , computing_id = await is_logged_in (request , db_session )
33- if not logged_in :
33+ if not logged_in or not computing_id :
3434 return False , None , None
3535
3636 # where valid means elections officer or website admin
@@ -44,7 +44,8 @@ async def _validate_user(
4444
4545@router .get (
4646 "/list" ,
47- description = "Returns a list of all elections & their status"
47+ description = "Returns a list of all elections & their status" ,
48+ response_model = list [ElectionModel ]
4849)
4950async def list_elections (
5051 _ : Request ,
@@ -53,7 +54,7 @@ async def list_elections(
5354 election_list = await elections .crud .get_all_elections (db_session )
5455 if election_list is None or len (election_list ) == 0 :
5556 raise HTTPException (
56- status_code = status .HTTP_404_INTERNAL_SERVER_ERROR ,
57+ status_code = status .HTTP_404_NOT_FOUND ,
5758 detail = "no elections found"
5859 )
5960
@@ -71,7 +72,8 @@ async def list_elections(
7172 Retrieves the election data for an election by name.
7273 Returns private details when the time is allowed.
7374 If user is an admin or elections officer, returns computing ids for each candidate as well.
74- """
75+ """ ,
76+ response_model = ElectionModel
7577)
7678async def get_election (
7779 request : Request ,
@@ -92,6 +94,11 @@ async def get_election(
9294
9395 election_json = election .private_details (current_time )
9496 all_nominations = await elections .crud .get_all_registrations_in_election (db_session , slugified_name )
97+ if not all_nominations :
98+ raise HTTPException (
99+ status_code = status .HTTP_404_NOT_FOUND ,
100+ detail = "no registrations found"
101+ )
95102 election_json ["candidates" ] = []
96103
97104 available_positions_list = election .available_positions .split ("," )
@@ -166,6 +173,7 @@ def _raise_if_bad_election_data(
166173@router .post (
167174 "/{election_name:str}" ,
168175 description = "Creates an election and places it in the database. Returns election json on success" ,
176+ response_model = ElectionModel
169177)
170178async def create_election (
171179 request : Request ,
@@ -251,7 +259,8 @@ async def create_election(
251259 name produces the same slug.
252260
253261 Returns election json on success.
254- """
262+ """ ,
263+ response_model = ElectionModel
255264)
256265async def update_election (
257266 request : Request ,
@@ -310,7 +319,8 @@ async def update_election(
310319
311320@router .delete (
312321 "/{election_name:str}" ,
313- description = "Deletes an election from the database. Returns whether the election exists after deletion."
322+ description = "Deletes an election from the database. Returns whether the election exists after deletion." ,
323+ response_model = SuccessFailModel
314324)
315325async def delete_election (
316326 request : Request ,
@@ -337,7 +347,8 @@ async def delete_election(
337347
338348@router .get (
339349 "/registration/{election_name:str}" ,
340- description = "get your election registration(s)"
350+ description = "get your election registration(s)" ,
351+ response_model = list [NomineeApplicationModel ]
341352)
342353async def get_election_registrations (
343354 request : Request ,
@@ -358,7 +369,7 @@ async def get_election_registrations(
358369 detail = f"election with slug { slugified_name } does not exist"
359370 )
360371
361- registration_list = await elections .crud .get_all_registrations (db_session , computing_id , slugified_name )
372+ registration_list = await elections .crud .get_all_registrations_of_user (db_session , computing_id , slugified_name )
362373 if registration_list is None :
363374 return JSONResponse ([])
364375 return JSONResponse ([
@@ -367,7 +378,7 @@ async def get_election_registrations(
367378
368379@router .post (
369380 "/registration/{election_name:str}" ,
370- description = "register for a specific position in this election, but doesn't set a speech"
381+ description = "register for a specific position in this election, but doesn't set a speech" ,
371382)
372383async def register_in_election (
373384 request : Request ,
@@ -414,7 +425,7 @@ async def register_in_election(
414425 status_code = status .HTTP_400_BAD_REQUEST ,
415426 detail = "registrations can only be made during the nomination period"
416427 )
417- elif await elections .crud .get_all_registrations (db_session , computing_id , slugified_name ):
428+ elif await elections .crud .get_all_registrations_of_user (db_session , computing_id , slugified_name ):
418429 raise HTTPException (
419430 status_code = status .HTTP_400_BAD_REQUEST ,
420431 detail = "you are already registered in this election"
@@ -482,7 +493,7 @@ async def update_registration(
482493 detail = "speeches can only be updated during the nomination period"
483494 )
484495
485- elif not await elections .crud .get_all_registrations (db_session , ccid_of_registrant , slugified_name ):
496+ elif not await elections .crud .get_all_registrations_of_user (db_session , ccid_of_registrant , slugified_name ):
486497 raise HTTPException (
487498 status_code = status .HTTP_404_NOT_FOUND ,
488499 detail = "applicant not yet registered in this election"
@@ -531,7 +542,7 @@ async def delete_registration(
531542 status_code = status .HTTP_400_BAD_REQUEST ,
532543 detail = "registration can only be revoked during the nomination period"
533544 )
534- elif not await elections .crud .get_all_registrations (db_session , computing_id , slugified_name ):
545+ elif not await elections .crud .get_all_registrations_of_user (db_session , computing_id , slugified_name ):
535546 raise HTTPException (
536547 status_code = status .HTTP_404_NOT_FOUND ,
537548 detail = "you are not yet registered in this election"
@@ -544,7 +555,8 @@ async def delete_registration(
544555
545556@router .get (
546557 "/nominee/info" ,
547- description = "Nominee info is always publically tied to elections, so be careful!"
558+ description = "Nominee info is always publically tied to elections, so be careful!" ,
559+ response_model = NomineeInfoModel
548560)
549561async def get_nominee_info (
550562 request : Request ,
@@ -568,7 +580,8 @@ async def get_nominee_info(
568580
569581@router .put (
570582 "/nominee/info" ,
571- description = "Will create or update nominee info. Returns an updated copy of their nominee info."
583+ description = "Will create or update nominee info. Returns an updated copy of their nominee info." ,
584+ response_model = NomineeInfoModel
572585)
573586async def provide_nominee_info (
574587 request : Request ,
0 commit comments