44from middleware .verifyToken import get_access_token
55from firebase_admin import auth
66from config import initialize
7+ from fastapi .responses import JSONResponse
78from botocore .exceptions import ClientError
89
910ans_app = FastAPI ()
1415
1516
1617class AnswerStruct (BaseModel ):
17- domain : str = Field (..., title = "Domain for the answers" )
18- questions : List [str ] = Field (..., title = "List of questions" )
19- answers : List [str ] = Field (..., title = "List of answers" )
20- score : Optional [int ] = Field (None , title = "Score for the domain, not compulsory" )
18+ domain : str = Field (...)
19+ questions : List [str ] = Field (...)
20+ answers : List [str ] = Field (...)
21+ score : Optional [int ] = Field (None )
2122 round : int
2223
24+ domain_mapping = {
25+ "UI/UX" : "ui" ,
26+ "Graphic Design" : "graphic" ,
27+ "Video Editing" : "video" ,
28+ 'Events' :'events' ,
29+ 'PnM' :'pnm' ,
30+ 'WEB' :'web' ,
31+ 'IOT' :'iot' ,
32+ 'APP' :'app' ,
33+ 'AI/ML' :'ai' ,
34+ 'RND' :'rnd'
35+ }
36+
2337@ans_app .post ("/submit" )
2438async def post_answers (answerReq : AnswerStruct , idToken : str = Depends (get_access_token )):
2539 try :
2640 decoded_token = auth .verify_id_token (idToken , app = resources ["firebase_app" ])
2741 email = decoded_token .get ("email" )
2842
2943 if not email :
30- raise HTTPException (status_code = 401 , detail = "Invalid or missing email in token." )
44+ return JSONResponse (status_code = 401 , content = "Invalid or missing email in token." )
3145
3246 response = user_table .get_item (Key = {"uid" : email })
3347 user = response .get ("Item" )
3448
3549 if not user :
36- raise HTTPException (status_code = 404 , detail = "User not found." )
50+ return JSONResponse (status_code = 404 , content = "User not found." )
3751
38- if len ( answerReq .questions ) != len ( answerReq . answers ):
39- raise HTTPException (
40- status_code = 400 ,
41- detail = "Questions and answers lists must have the same length."
42- )
52+ if answerReq .domain not in user . get ( 'domains' , [] ):
53+ return JSONResponse ( status_code = 408 , content = "Domain was not selected" )
54+ mapped_domain = domain_mapping . get ( answerReq . domain )
55+ domain_tables = resources [ 'domain_tables' ]
56+ domain_table = domain_tables . get ( mapped_domain )
4357
44- existing_round = user .get (f"round { answerReq .round } " , {})
58+ if not domain_table :
59+ raise HTTPException (status_code = 400 , detail = f"Domain '{ answerReq .domain } ' not recognized." )
4560
46- if answerReq .domain in existing_round :
47- raise HTTPException (
48- status_code = 400 ,
49- detail = f"Answers for domain '{ answerReq .domain } ' have already been submitted for round { answerReq .round } ."
50- )
61+ if len (answerReq .questions ) != len (answerReq .answers ):
62+ raise HTTPException (status_code = 400 , detail = "Questions and answers lists must have the same length." )
5163
52- answers_dict = [
53- {"question" : q , "answer" : a }
54- for q , a in zip (answerReq .questions , answerReq .answers )
55- ]
64+ answers_dict = [{"question" : q , "answer" : a } for q , a in zip (answerReq .questions , answerReq .answers )]
65+ response = domain_table .get_item (Key = {'email' : email })
5666
57- domain_data = {"answers" : answers_dict }
58- if answerReq .score is not None :
59- domain_data ["score" ] = answerReq .score
6067
61- existing_round [answerReq .domain ] = domain_data
6268
63- user_table .update_item (
64- Key = {"uid" : email },
65- UpdateExpression = "SET #round = :updated_round" ,
66- ExpressionAttributeNames = {"#round" : f"round { answerReq .round } " },
67- ExpressionAttributeValues = {":updated_round" : existing_round },
68- ReturnValues = "UPDATED_NEW" ,
69- )
69+ if answerReq .round == 1 :
70+ if 'Item' in response :
71+ return JSONResponse (status_code = 409 , content = "Answers already submitted" )
72+
73+ domain_table .put_item (
74+ Item = {
75+ "email" : email ,
76+ f"round{ answerReq .round } " : answers_dict ,
77+ f"score{ answerReq .round } " : answerReq .score
78+ }
79+ )
80+ else :
81+ result = domain_table .get_item (Key = {"email" : email })
82+ domain_response = result .get ('Item' )
83+ if not domain_response or not domain_response .get (f"round{ answerReq .round - 1 } " ):
84+ raise HTTPException (
85+ status_code = 400 ,
86+ detail = f"User '{ email } ' has not completed round { answerReq .round - 1 } in domain '{ answerReq .domain } '."
87+ )
88+ domain_table .update_item (Key = {"email" : email },
89+ UpdateExpression = """
90+ SET #new_answers = if_not_exists(#new_answers, :new_answers),
91+ #new_score = if_not_exists(#new_score, :new_score)
92+ """ ,
93+ ExpressionAttributeNames = {
94+ "#new_answers" : f"round{ answerReq .round } " ,
95+ "#new_score" : f"score{ answerReq .round } "
96+ },
97+ ExpressionAttributeValues = {
98+ ":new_answers" : answers_dict ,
99+ ":new_score" : answerReq .score
100+ },
101+ ReturnValues = "UPDATED_NEW"
102+ )
70103
104+ user_table .update_item (
105+ Key = {'uid' : email },
106+ UpdateExpression = f"SET round{ answerReq .round } = list_append(if_not_exists(round{ answerReq .round } , :empty_list), :new_value)" ,
107+ ExpressionAttributeValues = {
108+ ':new_value' : [answerReq .domain ],
109+ ':empty_list' : []
110+ },
111+ )
71112 return {"message" : f"Answers for domain '{ answerReq .domain } ' submitted successfully for round { answerReq .round } ." }
72113
73114 except ClientError as e :
74115 raise HTTPException (status_code = 500 , detail = f"DynamoDB error: { str (e )} " )
75116 except Exception as e :
76- raise HTTPException (status_code = 400 , detail = f"Error posting answers: { str (e )} " )
117+ raise HTTPException (status_code = 400 , detail = f"Error posting answers: { str (e )} " )
0 commit comments