Add campaigns/ Add supervisor/ Add messaging features/ Separate SMS
This commit is contained in:
@@ -15,13 +15,14 @@ from rest_framework.throttling import ScopedRateThrottle
|
||||
from rest_framework.views import APIView
|
||||
|
||||
from .authentication import issue_access_token
|
||||
from .models import OTPCode, Session, User
|
||||
from .models import OTPCode, Profile, Session, User
|
||||
from .services import OTPDeliveryError, send_otp_sms
|
||||
from .serializers import (
|
||||
GuestSessionRequestSerializer,
|
||||
GuestSessionResponseSerializer,
|
||||
LoginRequestSerializer,
|
||||
LoginResponseSerializer,
|
||||
ProfileResponseSerializer,
|
||||
RefreshRequestSerializer,
|
||||
RefreshResponseSerializer,
|
||||
RequestOTPRequestSerializer,
|
||||
@@ -79,6 +80,12 @@ class GuestSessionView(APIView):
|
||||
defaults={'name': ''},
|
||||
)
|
||||
|
||||
# ثبتِ فعالیتِ کاربر: ایجاد/استفادهی سشنِ مهمان یک سشنِ واقعیِ
|
||||
# کاربره، پس last_activity_at بهروزرسانی میشه (بدونِ تأثیر روی
|
||||
# سایرِ رفتارِ endpoint).
|
||||
user.last_activity_at = timezone.now()
|
||||
user.save(update_fields=['last_activity_at'])
|
||||
|
||||
token = issue_access_token(user.id)
|
||||
|
||||
data = {
|
||||
@@ -285,6 +292,10 @@ class LoginView(APIView):
|
||||
user.is_guest = False
|
||||
user.save(update_fields=['is_guest'])
|
||||
|
||||
# ثبتِ فعالیتِ کاربر برای ورودِ موفق.
|
||||
user.last_activity_at = timezone.now()
|
||||
user.save(update_fields=['last_activity_at'])
|
||||
|
||||
if created:
|
||||
# آفرهای ثبتنام (مثل یک هفته رایگان) از طریق discount/receivers.py روی این سیگنال اعمال میشوند.
|
||||
from .signals import user_registered
|
||||
@@ -340,6 +351,9 @@ class RefreshTokenView(APIView):
|
||||
|
||||
old_session = Session.objects.get(refresh_token=refresh_token)
|
||||
|
||||
# ثبتِ فعالیتِ کاربر برای رفرشِ موفقِ توکن.
|
||||
User.objects.filter(pk=old_session.user_id).update(last_activity_at=timezone.now())
|
||||
|
||||
new_refresh_token = secrets.token_hex(32)
|
||||
new_session = Session.objects.create(
|
||||
user_id=old_session.user_id,
|
||||
@@ -384,3 +398,34 @@ class SetUserGradeView(APIView):
|
||||
|
||||
data = {'success': True, 'gradeId': grade_id}
|
||||
return Response(SetGradeResponseSerializer(data).data)
|
||||
|
||||
|
||||
class UserProfileView(APIView):
|
||||
"""GET /api/user/profile — اطلاعات پروفایل کاربر جاری (نیاز به احراز هویت)"""
|
||||
|
||||
permission_classes = [IsAuthenticated]
|
||||
|
||||
@extend_schema(
|
||||
responses=ProfileResponseSerializer,
|
||||
tags=['Identity & Profile (accounts)'],
|
||||
)
|
||||
def get(self, request):
|
||||
user = request.user
|
||||
# مدل Profile بهصورت lazy ساخته میشه چون هیچجای دیگهای (نه
|
||||
# GuestSessionView، نه LoginView) رکورد Profile رو از قبل نمیسازه؛
|
||||
# get_or_create اینجا امن است چون فقط توسطِ کاربرِ همون رکورد صدا
|
||||
# زده میشه (OneToOne روی user_id جاری، نه ورودیِ خارجی).
|
||||
profile, _ = Profile.objects.get_or_create(user_id=user.id)
|
||||
|
||||
data = {
|
||||
'userId': str(user.id),
|
||||
'phone': user.phone,
|
||||
'name': user.name,
|
||||
'avatar': user.avatar,
|
||||
'isGuest': user.is_guest,
|
||||
'gradeId': user.grade_id,
|
||||
'birthYear': profile.birth_year,
|
||||
'parentPhone': profile.parent_phone,
|
||||
'bio': profile.bio,
|
||||
}
|
||||
return Response(ProfileResponseSerializer(data).data)
|
||||
|
||||
Reference in New Issue
Block a user