Add question bank mastery paths and gap questions

This commit is contained in:
hz
2026-07-31 23:46:46 -05:00
parent 012d0cf196
commit 8c439c6294
28 changed files with 1409 additions and 121 deletions
+36 -3
View File
@@ -53,6 +53,11 @@ var rating_request_token := ""
var report_request_token := ""
var pending_excluded_question_ids: Array = []
var pending_require_media := false
var pending_step3_system := ""
var pending_difficulty_min := 0
var pending_difficulty_max := 0
var pending_limit := 1
var targeted_fallback_used := false
var image_question_search_attempts := 0
func _ready() -> void:
@@ -107,7 +112,8 @@ func _ready() -> void:
_process_attempt_queue()
func load_questions_from_api(reset_retry: bool = true, excluded_question_ids: Array = [], require_media: bool = false) -> void:
func load_questions_from_api(reset_retry: bool = true, excluded_question_ids: Array = [], require_media: bool = false,
step3_system: String = "", difficulty_min: int = 0, difficulty_max: int = 0, requested_limit: int = 1) -> void:
if not AuthState.can_send_authenticated_request():
_set_load_error("Login required before loading questions.", false)
return
@@ -115,6 +121,11 @@ func load_questions_from_api(reset_retry: bool = true, excluded_question_ids: Ar
if reset_retry:
pending_excluded_question_ids = excluded_question_ids.duplicate()
pending_require_media = require_media
pending_step3_system = step3_system
pending_difficulty_min = difficulty_min
pending_difficulty_max = difficulty_max
pending_limit = clampi(requested_limit, 1, 40)
targeted_fallback_used = false
image_question_search_attempts = 0
retry_attempt = 0
next_retry_seconds = 0
@@ -144,11 +155,17 @@ func load_questions_from_api(reset_retry: bool = true, excluded_question_ids: Ar
"Authorization: Bearer %s" % questions_request_token
])
var payload := {
"limit": 1,
"limit": pending_limit,
"supportsChoicePools": true,
"requireMedia": pending_require_media,
"excludeExternalIds": pending_excluded_question_ids
}
if not pending_step3_system.is_empty():
payload["step3System"] = pending_step3_system
if pending_difficulty_min > 0:
payload["difficultyMin"] = pending_difficulty_min
if pending_difficulty_max > 0:
payload["difficultyMax"] = pending_difficulty_max
var err := request.request(questions_api_url, headers, HTTPClient.METHOD_POST, JSON.stringify(payload))
if err != OK:
_set_load_error("Unable to connect to the question service.")
@@ -177,6 +194,12 @@ func _on_api_questions_loaded(result: int, response_code: int, _headers: PackedS
api_questions.append(normalized)
if api_questions.is_empty():
if not pending_step3_system.is_empty() and (pending_difficulty_min > 0 or pending_difficulty_max > 0) and not targeted_fallback_used:
targeted_fallback_used = true
pending_difficulty_min = 0
pending_difficulty_max = 0
call_deferred("load_questions_from_api", false, pending_excluded_question_ids, pending_require_media)
return
_set_load_error("Questions API returned no usable questions.", false)
return
if pending_require_media and not _contains_question_with_media(api_questions):
@@ -200,6 +223,10 @@ func _on_api_questions_loaded(result: int, response_code: int, _headers: PackedS
questions_changed.emit()
func load_targeted_questions(step3_system: String, question_count: int, difficulty_min: int = 0, difficulty_max: int = 0) -> void:
load_questions_from_api(true, [], false, step3_system, difficulty_min, difficulty_max, question_count)
func retry_now() -> void:
retry_attempt = 0
next_retry_seconds = 0
@@ -256,6 +283,11 @@ func clear_questions() -> void:
pending_report_question_id = ""
pending_excluded_question_ids.clear()
pending_require_media = false
pending_step3_system = ""
pending_difficulty_min = 0
pending_difficulty_max = 0
pending_limit = 1
targeted_fallback_used = false
image_question_search_attempts = 0
questions_changed.emit()
ratings_changed.emit()
@@ -337,7 +369,7 @@ func get_questions_for_system(system_name: String) -> Array:
var filtered: Array = []
for question in questions:
if str(question.get("system", "")) == system_name:
if str(question.get("step3_system", question.get("system", ""))) == system_name or str(question.get("system", "")) == system_name:
filtered.append(question.duplicate(true))
return filtered
@@ -688,6 +720,7 @@ func _normalize_api_question(item: Variant) -> Dictionary:
"choice_selection_percentages": item.get("choiceSelectionPercentages", item.get("choice_selection_percentages", {})),
"discipline": str(item.get("discipline", "")),
"system": str(item.get("system", "")),
"step3_system": str(item.get("step3System", item.get("step3_system", ""))),
"performance_category": str(item.get("performanceCategory", item.get("performance_category", ""))),
"difficulty": int(item.get("difficulty", 1)),
"question_elo": int(item.get("questionElo", item.get("question_elo", 1000))),