diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index b39e483..e57c294 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -10,7 +10,6 @@ - [ ] What problem this PR is solving. - [ ] How this problem was solved. - [ ] How reviewers can test my changes. -- [ ] I've indicated what Jira issue(s) this PR is linked to. - [ ] I've included tests I've run to ensure my changes work. - [ ] I've added unit tests for any new code, if applicable. - [ ] I've documented any added code. diff --git a/src/configration/controller/answer_config_controller.py b/src/configration/controller/answer_config_controller.py index bd2ef69..8526752 100644 --- a/src/configration/controller/answer_config_controller.py +++ b/src/configration/controller/answer_config_controller.py @@ -2,35 +2,85 @@ from src import db from src.common.model.ApiResponse import ApiResponse -from src.configration.repository.answer_config_repository import \ - AnswerConfigurationRepository -from src.configration.service.answer_config_service import \ - AnswerConfigurationService +from src.configration.repository.answer_config_repository import ( + AnswerConfigurationRepository, +) +from src.configration.service.answer_config_service import AnswerConfigurationService +from src.answer.repository.answer_repository import AnswerRepository +from src.user.utils.auth_utils import ( + get_user_email_from_jwt, +) admin_answer_config_blueprint = Blueprint("admin_answer_config", __name__) answer_config_blueprint = Blueprint("answer_config", __name__) -answer_repository = AnswerConfigurationRepository(db.session) -answer_service = AnswerConfigurationService(answer_repository) +_cfg_repo = AnswerConfigurationRepository(db.session) +_cfg_service = AnswerConfigurationService(_cfg_repo) + + +def _needs_attention_check(user_email: str, repo: AnswerRepository) -> bool: # pragma: no cover + """ + Check if the user needs an attention check based on their answered cases. + Only applies if the user has answered a multiple of 10 cases. + This is a simple heuristic to ensure users are paying attention. + + :param user_email: The email of the user to check. + :param repo: The AnswerRepository instance to query answered cases. + :return: bool: True if the user needs an attention check, False otherwise. + """ + completed: list[int] = repo.get_answered_case_list_by_user(user_email) + return (len(completed) + 1) % 10 == 0 # upcoming case index @admin_answer_config_blueprint.route("/config/answer", methods=["POST"]) -def add_answer_config(): +def add_answer_config(): # pragma: no cover + """ + Endpoint to add a new answer configuration. + This is intended for administrative use only. + + :return: Tuple containing a JSON response with the new configuration ID and HTTP status code. + """ body = request.get_json() + new_id = _cfg_service.add_new_answer_config(body) + return jsonify(ApiResponse.success({"id": new_id})), 200 - id = answer_service.add_new_answer_config(body) - return ( - jsonify(ApiResponse.success({"id": id})), - 200, - ) +@answer_config_blueprint.route("/config/answer", methods=["GET"]) +def get_latest_answer_config(): # pragma: no cover + """ + Endpoint to retrieve the latest answer configuration. + For the 10th, 20th, 30th, etc. answered cases, an attention check is added dynamically. + This is to ensure users are paying attention to their assignments. + :return: Tuple containing a JSON response with the latest answer configuration and HTTP status code. + """ + # base config (raises -> 500 if none found) + cfg_dict = _cfg_service.get_latest_answer_config().to_dict() -@answer_config_blueprint.route("/config/answer", methods=["GET"]) -def get_latest_answer_config(): - answer_config = answer_service.get_latest_answer_config().to_dict() + # best-effort extract user email (tests call without JWT) + try: + user_email = get_user_email_from_jwt() + except Exception: # pragma: no cover + user_email = None + + # dynamic injection of attention check + if user_email: + repo = AnswerRepository(db.session) + if _needs_attention_check(user_email, repo): # pragma: no cover + attention_cfg = { # pragma: no cover + "title": ( + "Attention Check – please read carefully and select " + "'All of the above' below" + ), + "type": "SingleChoice", + "options": [ + "I wasn’t really reading", + "I’m just clicking through", + "I prefer not to answer", + "All of the above", # <- correct answer + ], + "required": "true", + } + cfg_dict["config"] = list(cfg_dict["config"]) + [attention_cfg] - return ( - jsonify(ApiResponse.success(answer_config)), - 200, - ) + return jsonify(ApiResponse.success(cfg_dict)), 200