harden OTP for real SMS and close the second audit round
Kavenegar is being switched on, so every OTP request now costs credit: - phone numbers are normalised to 09XXXXXXXXX everywhere (login, OTP, family invite, TEST_LOGIN_PHONES keys) and existing rows are migrated; non-Iranian and landline numbers are rejected before any SMS - cooldown and a daily per-phone cap are counted in the database, so the three gunicorn workers no longer triple them - a global daily OTP SMS cap (default 300) stops SMS pumping - per-IP rates widened for CGNAT / school Wi-Fi (env-overridable) - provider message id is logged; SMS text warns not to share the code Second audit round: an offer no longer shortens a longer paid plan, Zarinpal error bodies no longer 500, island XP reaches the parent report, a non-numeric questionId no longer 500s after the answer is generated. 596 tests green. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -76,7 +76,13 @@ def node_playable_lesson_ids(node) -> list[int]:
|
||||
|
||||
|
||||
def verified_correct_count(user_id, *, lesson_id=None, node_id=None) -> int:
|
||||
"""تعدادِ سوالهای متمایزی از این درس/مبحث که کاربر درست جواب داده و ثبت شده."""
|
||||
"""
|
||||
تعدادِ سوالهای متمایزی از این درس/مبحث که کاربر درست جواب داده و ثبت شده.
|
||||
|
||||
«درست» یعنی *هر* جوابِ درست، حتی بعد از جوابِ غلط روی همان سوال. چون
|
||||
جوابِ غلط `correctOptionId` را برمیگرداند و تکرارِ جواب آزاد است، این عدد
|
||||
جلوی «جواب نداده امتیاز گرفتن» را میگیرد، نه «غلط زدن و بعد درست زدن».
|
||||
"""
|
||||
from .models import UserAnswer
|
||||
|
||||
qs = UserAnswer.objects.filter(user_id=user_id, correct=True)
|
||||
|
||||
Reference in New Issue
Block a user