list a user's own support tickets, Persian digits in completion notifications, rewrite .env.example to match the code

GET /api/support/tickets returns the caller's last 20 tickets with their
support-reply count, on the read throttle so listing never spends the
30/hour create quota. Before it the app kept ticket ids only in one
browser's localStorage, so a ticket and its answer vanished with the device.

Completion notifications now use Persian digits and drop the
'with 0 stars ... 0 points' sentence when nothing was earned.

.env.example: NUM_PROXIES=2 (ArvanCloud + nginx), KAVENEGAR_OTP_TEMPLATE,
BAZAAR_PISHKHAN_API_SECRET, sandbox off by default; removed variables the
code no longer reads.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-09-29 21:18:12 +03:30
parent 8321dc22c3
commit 93b451d422
7 changed files with 192 additions and 163 deletions

View File

@@ -189,6 +189,19 @@ def _record_streak(user_id):
logger.exception('streak: ثبتِ فعالیتِ کاربر %s شکست خورد', user_id)
_FA_DIGITS = str.maketrans('0123456789', '۰۱۲۳۴۵۶۷۸۹')
def _completion_body(title, stars, xp):
"""
متنِ اعلانِ «تمام کردی». عددها فارسی، چون اپ متنِ اعلان را همان‌طور که
هست نشان می‌دهد؛ و بی‌امتیاز جمله‌ی «با ۰ ستاره … ۰ امتیاز» ساخته نمی‌شود.
"""
if not xp:
return f'«{title}» را تمام کردی.'
return f'«{title}» را با {stars} ستاره تمام کردی و {xp} امتیاز گرفتی.'.translate(_FA_DIGITS)
def _node_status(lesson_ids, completed_ids, is_first_unlocked_candidate, quiz_completed=False):
# آزمونِ مبحث تمام شده → مبحث تمام است، مستقل از تک‌تکِ درس‌ها.
if quiz_completed:
@@ -639,7 +652,7 @@ class LessonCompleteView(APIView):
user_id=user_id,
type='lesson_completed',
title='درس را کامل کردی',
body=f'«{lesson.title}» را با {stars} ستاره تمام کردی و {xp_earned} امتیاز گرفتی.',
body=_completion_body(lesson.title, stars, xp_earned),
related_id=lesson.id,
)
except IntegrityError:
@@ -970,10 +983,7 @@ class NodeQuizCompleteView(APIView):
user_id=user_id,
type='node_completed',
title='جزیره را تمام کردی',
body=(
f'«{node.title}» را با {stars} ستاره تمام کردی و '
f'{completion.xp_earned} امتیاز گرفتی.'
),
body=_completion_body(node.title, stars, completion.xp_earned),
related_id=node.id,
)
except IntegrityError: