# 👤 سفر کاربر، ثبت‌نام و چرخه عضویت > **منابع ادغام‌شده:** `club-membership-contract-system.md`, `REGISTRATION-FLOW-FIXES.md`, `chatika-integration.md`, `club-feature-management-services.md`, `ADMIN-CUSTOMER-SEPARATION-FIX.md`, `ICURRENTUSERSERVICE-IMPLEMENTATION.md` > **آخرین بروزرسانی:** اسفند ۱۴۰۴ --- ## ۱. فلوی کامل چرخه کاربر ``` ورود به سایت │ ▼ ثبت‌نام (موبایل + OTP) │ ▼ تکمیل پروفایل │ ▼ ┌─────────────────────┬────────────────────────┐ │ مسیر عادی │ مسیر باشگاه │ ├─────────────────────┼────────────────────────┤ │ خرید از فروشگاه │ خرید پکیج طلایی (56M) │ │ مشاهده بلاگ │ امضای قرارداد (OTP) │ │ استفاده از خدمات │ فعالسازی (25M) │ │ │ عضویت در درخت باینری │ │ │ دسترسی فروشگاه تخفیفی │ │ │ دسترسی فیچرهای باشگاه │ │ │ کسب کمیسیون هفتگی │ └─────────────────────┴────────────────────────┘ ``` --- ## ۲. ثبت‌نام و احراز هویت ### ۲.۱ فلوی ثبت‌نام ``` صفحه ثبت‌نام │ ▼ ورود شماره موبایل │ ▼ ارسال OTP (Kavenegar SMS API) │ ▼ تأیید کد OTP │ ├─→ کاربر جدید: ساخت User + JWT Token └─→ کاربر موجود: ورود + JWT Token JWT Claims: • UserId • PhoneNumber • IsClubMember (bool) • Roles[] (Admin, Customer) • ReferralCode ``` ### ۲.۲ اصلاحات ثبت‌نام | مشکل | راه‌حل | وضعیت | |------|---------|--------| | OTP تکراری | Cooldown: ۶۰ ثانیه بین درخواست‌ها | ✅ | | شماره نامعتبر | Regex validation ایران `^09\d{9}$` | ✅ | | حمله brute-force | MaxAttempts: ۵ تلاش برای تأیید کد | ✅ | | انقضای کد | TTL: ۲ دقیقه | ✅ | | طول کد | ۶ رقم | ✅ | | قالب SMS | Kavenegar template: `Afrino` | ✅ | --- ## ۳. جداسازی Admin/Customer ### ۳.۱ مشکل قبلی ``` قبل: Admin و Customer هر دو از یک DbContext و Identity استفاده می‌کردند یک ادمین می‌توانست به صورت Customer هم ظاهر شود ← تداخل Claims بعد (اصلاح‌شده): ✅ ICurrentUserService → تشخیص دقیق نقش فعلی ✅ جداسازی Authorization Policy ✅ Admin claims فقط در BackOffice ✅ Customer claims فقط در FrontOffice ``` ### ۳.۲ ICurrentUserService ```csharp public interface ICurrentUserService { Guid UserId { get; } string PhoneNumber { get; } bool IsClubMember { get; } bool IsAdmin { get; } string[] Roles { get; } Guid? ReferrerId { get; } } // پیاده‌سازی: از HttpContext.User.Claims خوانده می‌شود // ثبت: services.AddScoped() ``` --- ## ۴. قرارداد عضویت باشگاه ### ۴.۱ فلوی امضای قرارداد ``` خرید پکیج طلایی → Redirect به صفحه قرارداد │ ▼ نمایش Modal غیرقابل‌بسته‌شدن │ ▼ ReadContract RPC → نمایش متن قرارداد (Markdown/HTML) │ ▼ کاربر باید تا انتهای متن اسکرول کند │ ▼ فعال شدن دکمه "ارسال کد تأیید" │ ▼ RequestContractOtp → ارسال SMS │ ▼ ورود کد ← VerifyContractOtp │ ├─→ معتبر: AcceptContract → فعالسازی عضویت └─→ نامعتبر: پیام خطا (حداکثر ۵ تلاش) ``` ### ۴.۲ ذخیره‌سازی قرارداد ```csharp // از کد: UserContract : BaseAuditableEntity public class UserContract { public long UserId { get; set; } public virtual User User { get; set; } public long ContractId { get; set; } // FK → Contract public virtual Contract Contract { get; set; } public string SignGuid { get; set; } // GUID یکتای امضا public string SignedPdfFile { get; set; } // فایل PDF امضاشده // فیلدهای BaseAuditableEntity: CreatedAt, ModifiedAt, ... } ``` --- ## ۵. فیچرهای باشگاه (Club Features) ### ۵.۱ سرویس مدیریت ```csharp public interface IClubFeatureService { Task> GetUserFeaturesAsync(Guid userId); Task ActivateFeatureAsync(Guid userId, string featureCode); Task DeactivateFeatureAsync(Guid userId, string featureCode); Task HasFeatureAsync(Guid userId, string featureCode); } ``` ### ۵.۲ فیچرهای موجود | کد فیچر | نام | توضیح | وضعیت | |----------|------|--------|--------| | `DISCOUNT_STORE` | فروشگاه تخفیفی | دسترسی به فروشگاه ۳۰% تخفیف | ✅ فعال | | `CHATIKA_AI` | چاتیکا | مشاوره هوش مصنوعی | ✅ فعال | | `COMMISSION` | کمیسیون | دریافت کمیسیون هفتگی | ✅ فعال | | `NETWORK_VIEW` | نمای شبکه | مشاهده درخت باینری | ✅ فعال | | `DAYA_LOAN` | وام دایا | درخواست وام | ⚠️ بلاک‌شده | ### ۵.۳ UserClubFeature Entity ```csharp public class UserClubFeature { public Guid Id { get; set; } public Guid UserId { get; set; } public string FeatureCode { get; set; } public bool IsActive { get; set; } public DateTime ActivatedAt { get; set; } public DateTime? DeactivatedAt { get; set; } } ``` --- ## ۶. ناوبری Auth-Aware ```csharp // صفحه اصلی — مسیردهی هوشمند if (IsAuthenticated && IsClubMember) → نمایش داشبورد باشگاه + فروشگاه تخفیفی else if (IsAuthenticated) → نمایش فروشگاه عادی + پروفایل else → نمایش Landing Page + ثبت‌نام ``` --- ## ۷. کدهای معرف (Referral) ``` هر عضو باشگاه → یک ReferralCode یکتا لینک: https://foursat.ir/register?ref={ReferralCode} ثبت‌نام با لینک: │ ▼ ذخیره ReferrerId در پروفایل کاربر جدید │ ▼ هنگام خرید پکیج → زیرمجموعه Referrer در درخت باینری │ ▼ Referrer → دریافت bonus (طبق شرایط باشگاه) ``` --- ## ۸. خلاصه وضعیت | ماژول | وضعیت | درصد | |-------|--------|------| | ثبت‌نام OTP | ✅ | 100% | | جداسازی Admin/Customer | ✅ | 100% | | ICurrentUserService | ✅ | 100% | | قرارداد باشگاه + OTP | ✅ | 100% | | فیچرهای باشگاه | ✅ | 100% | | Referral System | ✅ | 100% | | ناوبری Auth-Aware | ✅ | 100% | | مشاهده درخت شبکه (FrontOffice) | ✅ | 100% |