feat: certification rules, content sanitization, handle draft course updates and reset content, better redis logging

This commit is contained in:
Rotimi Best
2026-03-30 08:24:55 +01:00
parent ff2ad59377
commit 5a8f50f67b
131 changed files with 5643 additions and 2134 deletions
@@ -1118,7 +1118,11 @@
"answers_required": "Перед отправкой дайте хотя бы один ответ.",
"checking_submission": "Проверка вашей заявки...",
"answer_required": "Пожалуйста, ответьте на этот вопрос, прежде чем продолжить.",
"instructor_feedback": "Отзывы инструктора"
"instructor_feedback": "Отзывы инструктора",
"attempt_counter": "Попытка {текущая} из {total}",
"previous_try": "Предыдущая попытка",
"next_try": "Следующая попытка",
"try_again": "Попробуйте еще раз"
},
"edit_mode": {
"delete_modal": "Удалить упражнение",
@@ -1371,7 +1375,11 @@
"not_set": "Не установлено",
"incorrect_badge": "Неправильный"
}
}
},
"settings": "Настройки",
"settings_allow_multiple": "Разрешить несколько попыток",
"settings_allow_multiple_helper": "Учащиеся могут отправлять заявки несколько раз и просматривать предыдущие попытки на экране результатов.",
"settings_save": "Сохранить настройки"
},
"new_exercise_modal": {
"heading": "Новое упражнение",
@@ -1632,18 +1640,29 @@
"later": "Закрыть"
}
},
"certificates": {
"progress_hint": "Выполнено {current}% (для загрузки требуется {required}%)"
},
"certification": {
"rules_heading": "Правила сертификации",
"rules_heading": "Правила",
"deadline_label": "Срок сертификации",
"deadline_helper": "Учащиеся должны достичь процента завершения до этой даты и времени (по местному времени). Оставьте пустым, если срок не установлен.",
"threshold_label": "Минимальное завершение (%)",
"threshold_helper": "Для получения сертификата необходим совмещенный прогресс урока и упражнений (0–100). По умолчанию — 100%.",
"email_message_label": "Сертификационное письмо по электронной почте",
"email_message_helper": "Дополнительное сообщение, отображаемое в электронном письме, когда учащийся соответствует требованиям. Ссылка на страницу сертификата всегда включена.",
"final_exercise_label": "Заключительное упражнение (по желанию)",
"final_exercise_none": "нет",
"final_exercise_helper": "Если этот параметр установлен, учащиеся должны набрать хотя бы минимальный балл за это упражнение (засчитывается лучшая попытка) в дополнение к указанному выше проценту выполнения.",
"min_exercise_score_label": "Минимальный балл за финальное упражнение (%)",
"min_exercise_score_helper": "Оценка представляет собой процент от общего количества баллов, возможных за это упражнение (0–100).",
"blocker_progress": "Ваш прогресс по курсу составляет {current}%; Требуется {required}%.",
"blocker_deadline": "Срок сертификации прошел.",
"blocker_no_content": "В этом курсе нет уроков или упражнений, которые необходимо выполнить.",
"blocker_final_not_submitted": "Чтобы получить сертификат, отправьте необходимое упражнение «{exercisionTitle}».",
"blocker_final_pending": "Ваша попытка выполнения \"{exercisionTitle}\" все еще оценивается.",
"blocker_final_score": "Ваш лучший результат в «{exercisionTitle}» — {bestPercent}%; Требуется {requiredPercent}%.",
"blocker_final_misconfigured": "Для сертификационного упражнения «{exercisionTitle}» не настроены баллы; попросите инструктора это исправить.",
"email_message_label": "Сообщение электронной почты",
"email_message_placeholder": "например Мы гордимся вашим прогрессом — продолжайте учиться!"
},
"certificates": {
"progress_hint": "Выполнено {current}% (для загрузки требуется {required}%)"
}
},
"courses": {