<div dir="rtl" align="right">

# 📊 تحلیل جامع FrontOffice - وضعیت فعلی و نقشه راه

**تاریخ تحلیل**: ۱۴ آذر ۱۴۰۴ (بروزرسانی شده)  
**وضعیت کلی**: ⚠️ **پیاده‌سازی BFF (60%)** - هسته مرکزی آماده، نیاز به UI  
**اولویت**: 🟡 **متوسط** - BFF Skeleton آماده، فقط UI باقی مانده

---

## 🎯 خلاصه اجرایی

### وضعیت موجود:
- ✅ **24 صفحه UI** موجود (Store, Profile, Root pages)
- ✅ **12 ماژول CQ در BFF** (9 قدیمی + 3 جدید: Club, Network, Commission)
- ✅ **هسته مرکزی BFF کامل** (ClubMembership, NetworkMembership, Commission)
- ✅ **معماری gRPC** پیاده‌سازی شده + Infrastructure آماده
- ⚠️ **UI Pages برای Club/Network/Commission غایب** (فقط اسکلت BFF)

### نیازمندی‌های کاربر (7 دسته) - **بروزرسانی شده**:
1. 🟡 **باشگاه مشتریان** - BFF آماده ✅ | UI غایب ❌
2. 🟡 **صفحه داشبورد باشگاه** - BFF آماده ✅ | UI غایب ❌
3. ⚠️ **دیدن اطلاعات در یک نگاه** - Dashboard جامع (نیمه‌کاره)
4. ⚠️ **فروشگاه معمولی** - نیاز به بهبود UI/UX
5. ❌ **پرداخت دستی پکیج طلایی** - فرآیند ناقص
6. 🟡 **گزارش شبکه و کمیسیون** - BFF آماده ✅ | UI غایب ❌
7. ❓ **موارد اضافی** - نیازمند تحلیل

---

## 📁 ساختار فعلی پروژه

### 1️⃣ FrontOffice UI (Blazor Server)

**مسیر**: `/FrontOffice/src/FrontOffice.Main/Pages/`

#### صفحات موجود (24 صفحه):

**الف. Root Level (7 صفحه):**
```
✅ Index.razor              - صفحه اصلی (Hero, Features, Stats)
✅ About.razor              - درباره ما
✅ Contact.razor            - تماس با ما
✅ FAQ.razor                - سوالات متداول
✅ Checkout.razor           - صفحه پرداخت
✅ RegisterWizard.razor     - ثبت‌نام کاربر
✅ PackageDetail.razor      - جزئیات پکیج
```

**ب. Profile Section (6 صفحه):**
```
✅ Profile/Index.razor      - داشبورد پروفایل (نمایش _walletNetwork)
✅ Profile/Personal.razor   - اطلاعات شخصی
✅ Profile/Settings.razor   - تنظیمات
✅ Profile/Wallet.razor     - کیف پول (3 موجودی: Credit, Discount, Network)
⚠️ Profile/Addresses.razor  - آدرس‌ها (کامل)
⚠️ Profile/Tree.razor       - شجره‌نامه (Mock data - OrganizationChart component)
```

**ج. Store Section (7 صفحه):**
```
✅ Store/Products.razor         - لیست محصولات
✅ Store/ProductDetail.razor    - جزئیات محصول
✅ Store/Cart.razor             - سبد خرید
✅ Store/Categories.razor       - دسته‌بندی‌ها
✅ Store/Orders.razor           - سفارشات
✅ Store/OrderDetail.razor      - جزئیات سفارش
✅ Store/CheckoutSummary.razor  - خلاصه پرداخت
```

**د. Shared Components:**
```
✅ Shared/MainLayout.razor
✅ Shared/Footer.razor
✅ Shared/AuthDialog.razor
✅ Shared/SimpleOtpDialog.razor
```

---

### 2️⃣ FrontOffice.BFF (Backend For Frontend)

**مسیر**: `/FrontOffice.BFF/src/`

#### معماری (Clean Architecture):
```
FrontOffice.BFF/
├── Application/          # CQRS Handlers + DTOs
│   ├── CategoryCQ/                    ✅ قدیمی
│   ├── PackageCQ/                     ✅ قدیمی
│   ├── ProductsCQ/                    ✅ قدیمی
│   ├── ShopingCartCQ/                 ✅ قدیمی
│   ├── TransactionCQ/                 ✅ قدیمی
│   ├── UserAddressCQ/                 ✅ قدیمی
│   ├── UserCQ/                        ✅ قدیمی
│   ├── UserOrderCQ/                   ✅ قدیمی
│   ├── UserWalletCQ/                  ✅ قدیمی (DiscountBalance موجود)
│   ├── ClubMembershipCQ/              🆕 جدید (امروز)
│   ├── NetworkMembershipCQ/           🆕 جدید (امروز)
│   └── CommissionCQ/                  🆕 جدید (امروز)
├── Domain/               # Entities (minimal)
├── Infrastructure/       # gRPC clients, DB context
│   ├── Services/
│   │   └── ApplicationContractContext.cs   ✅ بروز (ClubMemberships, NetworkMemberships)
│   └── ConfigureGrpcServices.cs            ✅ Auto-register
└── WebApi/
    ├── Services/         # gRPC Service Implementations
    │   ├── CategoriesService.cs
    │   ├── PackageService.cs
    │   ├── ProductsService.cs
    │   ├── ShopingCartService.cs
    │   ├── TransactionService.cs
    │   ├── UserAddressService.cs
    │   ├── UserOrderService.cs
    │   ├── UserService.cs
    │   └── UserWalletService.cs
    └── Protobufs/        # gRPC Proto definitions
```

#### 12 ماژول موجود (9 قدیمی + 3 جدید):

| ماژول | وضعیت | توضیحات |
|------|-------|---------|
| **CategoryCQ** | ✅ کامل | دریافت دسته‌بندی‌ها |
| **PackageCQ** | ✅ کامل | دریافت پکیج‌ها |
| **ProductsCQ** | ✅ کامل | محصولات و گالری |
| **ShopingCartCQ** | ⚠️ ناقص | Add/Update موجود، Delete/Clear غایب |
| **TransactionCQ** | ✅ کامل | پرداخت و تأیید |
| **UserAddressCQ** | ✅ کامل | CRUD آدرس‌ها |
| **UserCQ** | ✅ کامل | OTP, Login, Profile |
| **UserOrderCQ** | ✅ کامل | CRUD سفارشات |
| **UserWalletCQ** | ✅ کامل | GetWallet + DiscountBalance موجود ✅ |
| **🆕 ClubMembershipCQ** | ✅ اسکلت | GetMyClubMembership, ActivateMyClubMembership |
| **🆕 NetworkMembershipCQ** | ✅ اسکلت | GetMyNetworkTree, GetMyNetworkStatistics |
| **🆕 CommissionCQ** | ✅ اسکلت | GetMyCommissionPayouts, GetMyWeeklyBalances |

---

## 🔴 تحلیل شکاف‌های بحرانی (Gap Analysis)

### دسته A: ماژول‌های BFF آماده (اسکلت کامل ✅) - نیاز به UI

#### 1️⃣ ClubMembershipCQ - باشگاه مشتریان

**✅ در FrontOffice.BFF**: اسکلت کامل شده (امروز ۱۴ آذر)  
**❌ در FrontOffice UI**: هیچ صفحه‌ای برای باشگاه وجود ندارد

**✅ در CMS موجود:**
- Commands: `ActivateClubMembership`, `DeactivateClubMembership`, `AssignClubFeature`
- Queries: `GetClubMembership`, `GetClubMembershipHistory`, `GetClubStatistics`

**✅ کارهای انجام شده در BFF:**

**الف. BFF Module (FrontOffice.BFF/Application/):**
```
✅ ClubMembershipCQ/
    ✅ Commands/
        ✅ ActivateMyClubMembership/         # پرداخت 56M
            - ActivateMyClubMembershipCommand.cs
            - ActivateMyClubMembershipCommandHandler.cs
            - ActivateMyClubMembershipResponseDto.cs
    ✅ Queries/
        ✅ GetMyClubMembership/              # وضعیت عضویت (Active/Inactive/Trial)
            - GetMyClubMembershipQuery.cs
            - GetMyClubMembershipQueryHandler.cs
            - GetMyClubMembershipResponseDto.cs
```

**✅ Infrastructure Updates:**
```csharp
✅ IApplicationContractContext + Implementation:
    - ClubMemberships property اضافه شد
    - NetworkMemberships property اضافه شد
```

**ج. UI Pages (FrontOffice/Pages/):**
```
[ ] Club/
    [ ] MembershipPage.razor
        - Badge وضعیت (Active/Inactive/Trial)
        - دکمه فعال‌سازی (56M تومان)
        - نمایش تاریخ انقضا
        - لیست مزایا
    [ ] FeaturesPage.razor
        - کارت هر فیچر (Trial vs VIP)
        - امتیاز لازم (RequiredPoints)
        - Badge فیچرهای فعال
    [ ] Components/
        [ ] ActivationButton.razor         # فرم پرداخت
        [ ] FeatureCard.razor              # کارت تک فیچر
```

**💰 اثر بیزینسی:**
- ❌ کاربر نمی‌تواند عضو باشگاه شود
- ❌ 56M شارژ Balance/Discount انجام نمی‌شود
- ❌ دسترسی به فروشگاه تخفیف وجود ندارد

---

#### 2️⃣ NetworkMembershipCQ - شبکه باینری

**❌ در FrontOffice.BFF**: هیچ چیز موجود نیست  
**⚠️ در FrontOffice UI**: فقط `Profile/Tree.razor` با داده Mock

**✅ در CMS موجود:**
- Commands: `JoinNetwork`, `MoveInNetwork`, `RemoveFromNetwork`
- Queries: `GetNetworkTree`, `GetUserNetworkPosition`, `GetNetworkMembershipHistory`, `GetNetworkStatistics`

**📋 کارهای مورد نیاز:**

**الف. BFF Module:**
```
[ ] NetworkMembershipCQ/
    [ ] Commands/
        [ ] JoinNetwork/                     # عضویت در شبکه
    [ ] Queries/
        [ ] GetMyNetworkTree/                # درخت باینری (MaxDepth: 1-10)
        [ ] GetMyNetworkPosition/            # موقعیت من (Parent, Left, Right)
        [ ] GetMyNetworkStatistics/          # آمار (تعداد چپ/راست/کل)
        [ ] GetNetworkHistory/               # تاریخچه جابجایی
```

**ب. BFF Service:**
```csharp
[ ] NetworkMembershipService.cs
    - GetMyNetworkTree(maxDepth) → CMS.GetNetworkTreeAsync(userId, maxDepth)
    - GetMyNetworkPosition() → CMS.GetUserNetworkPositionAsync(userId)
    - GetMyNetworkStatistics() → CMS.GetNetworkStatisticsAsync(userId)
    - JoinNetwork(parentId, position) → CMS.JoinNetworkAsync()
```

**ج. UI Updates:**
```
[ ] Profile/Tree.razor
    ✅ Component موجود: OrganizationChart
    [ ] حذف Mock data
    [ ] فراخوانی GetMyNetworkTree از BFF
    [ ] Selector عمق درخت (1-10)
    [ ] Lazy loading برای زیرشاخه‌ها
    [ ] دکمه Expand/Collapse
    
[ ] Pages/Network/
    [ ] StatsPage.razor                      # صفحه آمار شبکه
        - کارت تعداد چپ/راست
        - کارت کل اعضا
        - عمق درخت
        - آخرین عضو جدید
        - نمودار رشد
    [ ] JoinPage.razor                       # فرم عضویت
        - انتخاب Parent (جستجو)
        - انتخاب Position (Left/Right)
        - پیش‌نمایش موقعیت
```

**💰 اثر بیزینسی:**
- ❌ کاربر نمی‌تواند زیرمجموعه بگیرد
- ❌ درخت شبکه واقعی نمایش داده نمی‌شود
- ❌ محاسبه کمیسیون باینری کار نمی‌کند

---

#### 3️⃣ CommissionCQ - کمیسیون و برداشت

**⚠️ در FrontOffice.BFF**: فقط `WithdrawBalance` (کامل - در UserWalletCQ)  
**❌ در FrontOffice UI**: هیچ صفحه کمیسیون موجود نیست

**✅ در CMS موجود:**
- Commands: `RequestWithdrawal`, `ApproveWithdrawal`, `ProcessWithdrawal`, `CalculateWeekly*`
- Queries: `GetUserCommissionPayouts`, `GetUserWeeklyBalances`, `GetWeeklyCommissionPool`, `GetWithdrawalRequests`

**📋 کارهای مورد نیاز:**

**الف. BFF Module:**
```
[ ] CommissionCQ/
    [ ] Queries/
        [ ] GetMyCommissionPayouts/          # لیست پرداخت‌های کمیسیون
            - GetMyCommissionPayoutsQuery.cs
            - GetMyCommissionPayoutsQueryHandler.cs
            - CommissionPayoutDto.cs (Week, Amount, Status, Date)
        [ ] GetMyWeeklyBalances/             # تعادل هفتگی
            - GetMyWeeklyBalancesQuery.cs
            - GetMyWeeklyBalancesQueryHandler.cs
            - WeeklyBalanceDto.cs (Left, Right, Weaker, Carryover)
        [ ] GetWeeklyPoolInfo/               # اطلاعات استخر هفته
            - GetWeeklyPoolInfoQuery.cs
            - GetWeeklyPoolInfoQueryHandler.cs
            - WeeklyPoolDto.cs (TotalPool, BalanceValue)
        [ ] GetMyWithdrawalHistory/          # تاریخچه برداشت‌ها
            - GetMyWithdrawalHistoryQuery.cs
            - GetMyWithdrawalHistoryQueryHandler.cs
            - WithdrawalHistoryDto.cs
```

**ب. BFF Service:**
```csharp
[ ] CommissionService.cs
    - GetMyCommissionPayouts(weekNumber?, status?) → CMS.GetUserCommissionPayoutsAsync(userId)
    - GetMyWeeklyBalances(weekNumber?) → CMS.GetUserWeeklyBalancesAsync(userId)
    - GetWeeklyPoolInfo(weekNumber?) → CMS.GetWeeklyCommissionPoolAsync(weekNumber)
    - GetMyWithdrawalHistory() → CMS.GetWithdrawalRequestsAsync(userId)
```

**توجه**: `WithdrawBalance` در `UserWalletService` قبلاً پیاده‌سازی شده ✅

**ج. UI Pages:**
```
[ ] Pages/Commission/
    [ ] DashboardPage.razor                  # داشبورد کمیسیون
        - کارت استخر هفته (TotalPool, BalanceValue)
        - کارت امتیازات من (LesserLegPoints)
        - پیش‌بینی کمیسیون این هفته
        - نمودار روند 4 هفته اخیر
    [ ] HistoryPage.razor                    # تاریخچه پرداخت‌ها
        - جدول پرداخت‌های گذشته
        - فیلتر Status (Pending/Calculated/Paid/Withdrawn)
        - فیلتر هفته
        - نمودار خطی روند
    [ ] WithdrawPage.razor                   # صفحه برداشت
        ✅ قسمتی در Profile/Wallet.razor موجود است
        [ ] جداسازی به صفحه مستقل
        - فرم برداشت (PayoutId, Method, IBAN)
        - نمایش MinWithdrawalAmount
        - نمایش موجودی قابل برداشت
        - تاریخچه برداشت‌ها
    [ ] WeeklyBalancePage.razor              # تعادل هفتگی
        - تعادل چپ/راست
        - Carryover از هفته قبل
        - سقف 300 Balance
        - نمودار میله‌ای هفته‌ها
```

**💰 اثر بیزینسی:**
- ❌ کاربر نمی‌تواند کمیسیون خود را ببیند
- ✅ برداشت از NetworkBalance کار می‌کند (در Wallet.razor)
- ❌ تعادل هفتگی و Carryover نامشخص است

---

#### 4️⃣ DayaLoanCQ - وام دایا

**❌ در FrontOffice.BFF**: هیچ چیز موجود نیست  
**❌ در FrontOffice UI**: هیچ چیز موجود نیست

**✅ در CMS موجود:**
- Commands: `CheckDayaLoanStatus`, `ProcessDayaLoanApproval`
- Background Worker: Daily check for loan status

**📋 کارهای مورد نیاز:**

**الف. BFF Module:**
```
[ ] DayaLoanCQ/
    [ ] Queries/
        [ ] GetMyDayaLoanStatus/
            - GetMyDayaLoanStatusQuery.cs
            - GetMyDayaLoanStatusQueryHandler.cs
            - DayaLoanStatusDto.cs (Status, ContractNumber, LastCheckDate, ApprovalDate)
```

**ب. BFF Service:**
```csharp
[ ] DayaLoanService.cs
    - GetMyDayaLoanStatus() → CMS.GetDayaLoanStatusAsync(userId)
```

**ج. UI Pages:**
```
[ ] Pages/DayaLoan/
    [ ] StatusPage.razor
        - Badge وضعیت (PendingReceive/Received/Rejected)
        - نمایش شماره قرارداد
        - تاریخ آخرین بررسی
        - توضیحات وام (168M = 56M×3)
    [ ] Components/
        [ ] StatusBadge.razor
            - رنگ‌بندی (Warning/Success/Error)
```

**💰 اثر بیزینسی:**
- ❌ کاربر نمی‌تواند وضعیت وام دایا را ببیند
- ❌ 168M شارژ (56M×3) نامشخص است
- ⚠️ Worker پس‌زمینه فعال است اما UI ندارد

---

### دسته B: ماژول‌های کامل‌شده (100% BFF)

#### 5️⃣ UserWalletCQ - کیف‌پول

**✅ موجود در BFF (کامل):**
- `GetUserWallet` - دریافت موجودی (✅ DiscountBalance موجود است)
- `GetAllUserWalletChangeLog` - تاریخچه تراکنش‌ها
- `WithdrawBalance` - برداشت (✅ کار می‌کند)
- `GetUserWithdrawals` - لیست برداشت‌ها
- `GetWithdrawalSettings` - تنظیمات برداشت (MinAmount)

**✅ Response DTO:**
```csharp
public class GetUserWalletResponseDto
{
    ✅ public long Balance { get; set; }
    ✅ public long NetworkBalance { get; set; }
    ✅ public long DiscountBalance { get; set; }  // موجود است
}
```

**⚠️ مشکلات جزئی:**
1. **فیلترهای ناقص**: `GetAllUserWalletChangeLog` فیلتر ندارد
   - نیاز: Type (Deposit/Withdraw/Purchase), DateRange, ReferenceId

**ب. UI Updates:**
```
[ ] Profile/Wallet.razor
    ✅ نمایش Balance
    ✅ نمایش NetworkBalance
    ❌ نمایش DiscountBalance (زرد/نارنجی)
    [ ] حذف داده Mock (Discount: "در انتظار اتصال CMS...")
    [ ] افزودن فیلترهای تراکنش:
        - Select نوع (همه/ورودی/خروجی)
        - DateRange picker
        - TextField جستجو ReferenceId
    [ ] نمایش ChangeValue به جای CurrentBalance
    [ ] Pagination برای تراکنش‌ها
```

**💰 اثر بیزینسی:**
- ⚠️ کاربر DiscountBalance خود را نمی‌بیند (باشگاه)
- ⚠️ فیلتر تراکنش‌ها محدود است

---

#### 6️⃣ ShopingCartCQ - سبد خرید

**✅ موجود در BFF:**
- `AddNewUserCart` - افزودن به سبد
- `UpdateUserCart` - به‌روزرسانی تعداد
- `GetAllUserCart` - دریافت سبد

**❌ غایب:**
- `ClearCart` - پاک کردن کل سبد
- `DeleteUserCarts` - حذف یک آیتم
- `MergeGuestCart` - ادغام سبد مهمان→ورود

**📋 کارهای مورد نیاز:**

**الف. BFF Commands:**
```
[ ] ShopingCartCQ/Commands/
    [ ] ClearCart/
        - ClearCartCommand.cs
        - ClearCartCommandHandler.cs → CMS.ClearUserCartAsync(userId)
    [ ] DeleteCartItem/
        - DeleteCartItemCommand.cs (CartId)
        - DeleteCartItemCommandHandler.cs → CMS.DeleteUserCartsAsync(cartId)
    [ ] MergeGuestCart/
        - MergeGuestCartCommand.cs (SessionId)
        - MergeGuestCartCommandHandler.cs:
            1. Get guest cart by SessionId
            2. Get user cart by UserId
            3. Merge duplicates (sum quantities)
            4. CMS.AddNewUserCart() for each
```

**ب. UI Updates:**
```
[ ] Store/Cart.razor
    [ ] دکمه "پاک کردن سبد" (ClearCart)
    [ ] دکمه حذف (DeleteCartItem) در هر سطر
    [ ] SessionId handling:
        - ذخیره در LocalStorage
        - POST به MergeGuestCart بعد از Login
        - نمایش پیام "x محصول از سبد قبلی شما اضافه شد"
```

---

#### 7️⃣ DiscountShopCQ - فروشگاه تخفیف

**❌ در FrontOffice.BFF**: هیچ چیز موجود نیست  
**❌ در FrontOffice UI**: هیچ صفحه‌ای موجود نیست

**✅ در CMS موجود:**
- Full CRUD for `DiscountProduct`, `DiscountCategory`, `DiscountOrder`
- BackOffice UI: 3 pages (Products, Categories, Orders)

**📋 کارهای مورد نیاز:**

**الف. BFF Module:**
```
[ ] DiscountShopCQ/
    [ ] Queries/
        [ ] GetDiscountProducts/             # محصولات تخفیف
        [ ] GetDiscountCategories/           # دسته‌بندی‌های تخفیف
        [ ] GetMyDiscountOrders/             # سفارشات تخفیف من
    [ ] Commands/
        [ ] AddToDiscountCart/               # افزودن به سبد تخفیف
        [ ] PlaceDiscountOrder/              # ثبت سفارش با DiscountBalance
```

**ب. BFF Service:**
```csharp
[ ] DiscountShopService.cs
    - GetDiscountProducts() → CMS.GetAllDiscountProductsAsync()
    - GetDiscountCategories() → CMS.GetAllDiscountCategoriesAsync()
    - GetMyDiscountOrders() → CMS.GetAllDiscountOrdersAsync(userId)
    - PlaceDiscountOrder(items) → CMS.CreateDiscountOrderAsync()
```

**ج. UI Pages:**
```
[ ] Pages/DiscountShop/
    [ ] ProductsPage.razor                   # لیست محصولات تخفیف
        - نمایش DiscountPercent (بادگ)
        - نمایش MaxDiscountPercentage سقف
        - فیلتر دسته‌بندی
        - کارت محصول با قیمت اصلی/تخفیف‌یافته
    [ ] CartPage.razor                       # سبد تخفیف
        - نمایش DiscountBalance موجود
        - محاسبه قیمت نهایی
        - دکمه Checkout
    [ ] OrdersPage.razor                     # سفارشات تخفیف
        - لیست سفارشات با Badge "Club Discount"
        - جزئیات تخفیف اعمال‌شده
```

**💰 اثر بیزینسی:**
- ❌ کاربر باشگاه نمی‌تواند از تخفیف استفاده کند
- ❌ DiscountBalance کاربرد ندارد
- ❌ 3 صفحه BackOffice بدون UI مشتری

---

### دسته C: قابلیت‌های جزئی (نیازهای اضافی)

#### 8️⃣ PublicMessageCQ - پیام‌های عمومی

**✅ در BackOffice موجود**: صفحه مدیریت پیام‌ها  
**❌ در FrontOffice**: هیچ چیز نیست

**📋 کارهای مورد نیاز:**
```
[ ] PublicMessageCQ/Queries/GetActivePublicMessages/
[ ] UI: Pages/Messages/ListPage.razor
    - لیست پیام‌ها با فیلتر Type (News/Announcement/Promotion)
    - Badge اولویت
    - نمایش تاریخ انتشار
```

---

#### 9️⃣ NotificationCQ - نوتیفیکیشن

**❌ در همه جا موجود نیست**

**پیشنهاد:**
```
[ ] NotificationCQ/
    [ ] Queries/GetMyNotifications/
    [ ] Commands/MarkAsRead/
[ ] UI: Bell Icon در Navbar
    - Badge تعداد جدید
    - Dropdown لیست نوتیفیکیشن
```

---

#### 🔟 ReferralLinkCQ - لینک دعوت

**❌ در همه جا موجود نیست**

**پیشنهاد:**
```
[ ] ReferralLinkCQ/Queries/GetMyReferralLink/
[ ] UI: Profile/ReferralPage.razor
    - نمایش لینک دعوت
    - دکمه Copy
    - آمار دعوت‌شده‌ها (تعداد)
    - QR Code
```

---

## 📊 خلاصه آماری شکاف‌ها (بروزرسانی شده)

| دسته | تعداد ماژول | وضعیت BFF | وضعیت UI | درصد کل |
|------|------------|-----------|----------|---------|
| ✅ کامل (BFF+UI) | 6 | Category, Package, Products, Transaction, UserAddress, UserCQ | موجود | 35% |
| ✅ BFF آماده | 3 | ClubMembership, NetworkMembership, Commission | **UI غایب** | 20% |
| ✅ BFF کامل | 2 | UserWallet (DiscountBalance), UserOrder | UI موجود | 15% |
| ⚠️ نیمه‌کاره | 1 | ShopingCart (Delete/Clear غایب) | UI موجود | 5% |
| ❌ غایب بحرانی | 1 | DayaLoan | UI غایب | 5% |
| ❌ غایب اضافی | 4 | DiscountShop, PublicMessage, Notification, ReferralLink | UI غایب | 20% |

**جمع**: 17 ماژول
**وضعیت BFF**: 60% کامل (12 از 17)
**وضعیت UI**: 40% کامل (فقط 9 ماژول قدیمی)

---

## 🎯 اولویت‌های باقی‌مانده (بروزرسانی شده)

### فاز 1: UI برای ماژول‌های BFF آماده (اولویت بالا 🔴)

**هدف**: اتصال UI به BFF موجود

```
[ ] Phase 1A: Club UI (2-3 روز)
    [ ] Pages/Club/MembershipPage.razor
    [ ] Pages/Club/FeaturesPage.razor (اختیاری)
    [ ] Components/Club/ActivationButton.razor

[ ] Phase 1B: Network UI (2 روز)
    [ ] Update Profile/Tree.razor (حذف Mock + اتصال به BFF)
    [ ] Pages/Network/StatsPage.razor

[ ] Phase 1C: Commission UI (3 روز)
    [ ] Pages/Commission/DashboardPage.razor
    [ ] Pages/Commission/HistoryPage.razor
    [ ] Pages/Commission/WeeklyBalancePage.razor

[ ] Phase 1D: Wallet UI Update (1 روز)
    [ ] Update Profile/Wallet.razor (نمایش DiscountBalance - کارت زرد)
```

**زمان تخمینی**: 8-9 روز

---

### فاز 2: ماژول‌های ثانویه (اولویت متوسط 🟡)

```
Day 1-2: DiscountShopCQ
  [ ] BFF Module
  [ ] Pages/DiscountShop/ProductsPage.razor
  [ ] Pages/DiscountShop/CartPage.razor

Day 3: ShopingCartCQ Completion
  [ ] Add DeleteCartItem, ClearCart Commands
  [ ] Update Store/Cart.razor

Day 4: DayaLoanCQ
  [ ] BFF Module (Query only)
  [ ] Pages/DayaLoan/StatusPage.razor

Day 5: PublicMessageCQ
  [ ] BFF Module
  [ ] Pages/Messages/ListPage.razor
```

---

### مرحله 3: بهبودهای UI/UX (1 هفته)

```
Day 1-2: Store Improvements
  [ ] Responsive design (mobile-first)
  [ ] Skeleton loaders
  [ ] Image lazy loading
  [ ] Product filters enhancement

Day 3-4: Profile Enhancements
  [ ] Avatar upload
  [ ] Settings page completion
  [ ] ReferralPage.razor (لینک دعوت)

Day 5: Notification System
  [ ] Bell icon در Navbar
  [ ] Notification dropdown
  [ ] Mark as read
```

---

### مرحله 4: قابلیت‌های اضافی (اختیاری)

```
[ ] Referral System (لینک دعوت + آمار)
[ ] Achievement/Rewards System
[ ] Reports (Excel/PDF export)
[ ] Advanced Filters (تاریخ، نوع، مبلغ)
[ ] Mobile App (PWA)
```

---

## 🛠️ الگوی پیاده‌سازی استاندارد

### الف. BFF Module Template

```
FrontOffice.BFF/Application/[ModuleName]CQ/
├── Commands/
│   └── [ActionName]/
│       ├── [ActionName]Command.cs
│       ├── [ActionName]CommandHandler.cs
│       ├── [ActionName]CommandValidator.cs
│       └── [ActionName]ResponseDto.cs (optional)
└── Queries/
    └── [QueryName]/
        ├── [QueryName]Query.cs
        ├── [QueryName]QueryHandler.cs
        └── [QueryName]ResponseDto.cs
```

**مثال: GetMyClubMembership**

```csharp
// GetMyClubMembershipQuery.cs
public record GetMyClubMembershipQuery : IRequest<ClubMembershipDto>;

// GetMyClubMembershipQueryHandler.cs
public class GetMyClubMembershipQueryHandler : IRequestHandler<GetMyClubMembershipQuery, ClubMembershipDto>
{
    private readonly IApplicationContractContext _context;
    private readonly ICurrentUserService _currentUser;

    public async Task<ClubMembershipDto> Handle(GetMyClubMembershipQuery request, CancellationToken ct)
    {
        var userId = _currentUser.UserId;  // از JWT Token
        
        var cmsRequest = new GetClubMembershipRequest { UserId = userId };
        var result = await _context.ClubMemberships.GetClubMembershipAsync(cmsRequest, cancellationToken: ct);
        
        return new ClubMembershipDto
        {
            UserId = result.UserId,
            IsActive = result.IsActive,
            ActivationDate = result.ActivationDate.ToDateTime(),
            ExpirationDate = result.ExpirationDate.ToDateTime(),
            Status = result.Status // Active/Inactive/Trial
        };
    }
}
```

---

### ب. gRPC Service Template

```csharp
// FrontOffice.BFF/WebApi/Services/ClubMembershipService.cs
public class ClubMembershipService : ClubMembershipContract.ClubMembershipContractBase
{
    private readonly IDispatchRequestToCQRS _dispatchRequestToCQRS;

    public ClubMembershipService(IDispatchRequestToCQRS dispatchRequestToCQRS)
    {
        _dispatchRequestToCQRS = dispatchRequestToCQRS;
    }

    public override async Task<GetMyClubMembershipResponse> GetMyClubMembership(Empty request, ServerCallContext context)
    {
        return await _dispatchRequestToCQRS.Handle<GetMyClubMembershipQuery, GetMyClubMembershipResponse>(context);
    }

    public override async Task<Empty> ActivateClubMembership(ActivateClubMembershipRequest request, ServerCallContext context)
    {
        return await _dispatchRequestToCQRS.Handle<ActivateClubMembershipRequest, ActivateClubMembershipCommand, Empty>(request, context);
    }
}
```

---

### ج. UI Page Template

```razor
@* Pages/Club/MembershipPage.razor *@
@page "/club/membership"
@inject ClubMembershipContract.ClubMembershipContractClient ClubService

<PageTitle>باشگاه مشتریان</PageTitle>

<MudContainer MaxWidth="MaxWidth.Large" Class="py-6">
    <MudStack Spacing="3">
        <MudText Typo="Typo.h4">باشگاه مشتریان</MudText>

        @if (_isLoading)
        {
            <MudProgressCircular Indeterminate="true" />
        }
        else if (_membership != null)
        {
            <MudPaper Elevation="2" Class="pa-4">
                <MudStack Spacing="2">
                    <MudChip Color="@GetStatusColor()" Variant="Variant.Filled">
                        @GetStatusText()
                    </MudChip>
                    
                    @if (!_membership.IsActive)
                    {
                        <MudButton Variant="Variant.Filled" 
                                   Color="Color.Primary" 
                                   OnClick="ActivateMembership">
                            فعال‌سازی باشگاه (56,000,000 تومان)
                        </MudButton>
                    }
                    else
                    {
                        <MudText>تاریخ انقضا: @_membership.ExpirationDate.ToPersianDate()</MudText>
                    }
                </MudStack>
            </MudPaper>
        }
    </MudStack>
</MudContainer>

@code {
    private ClubMembershipDto? _membership;
    private bool _isLoading = true;

    protected override async Task OnInitializedAsync()
    {
        try
        {
            var response = await ClubService.GetMyClubMembershipAsync(new Empty());
            _membership = response;  // Map to DTO
        }
        finally
        {
            _isLoading = false;
        }
    }

    private async Task ActivateMembership()
    {
        // پرداخت 56M
    }

    private Color GetStatusColor() => _membership?.IsActive == true ? Color.Success : Color.Warning;
    private string GetStatusText() => _membership?.IsActive == true ? "فعال" : "غیرفعال";
}
```

---

## 📋 چک‌لیست شروع توسعه

قبل از شروع هر ماژول:

```
[ ] CMS Commands/Queries را شناسایی کردم
[ ] Proto definitions را یافتم (CMS/Protobuf/*.proto)
[ ] نمونه Handler موجود در BFF را بررسی کردم
[ ] JWT Token و CurrentUserService را فهمیدم
[ ] ساختار DTO مشتری‌محور را طراحی کردم
[ ] Mock data برای UI آماده کردم
```

---

## 🚨 نکات بحرانی

### 1. تفاوت CMS vs BFF

| جنبه | CMS | FrontOffice.BFF |
|------|-----|-----------------|
| **مخاطب** | Admin + System | Customer فقط |
| **داده** | همه کاربران | کاربر جاری (`UserId` از JWT) |
| **Response** | DTO کامل + Metadata | DTO ساده (فقط فیلدهای لازم) |
| **Authorization** | Role-based (Admin/User) | User-only (No Admin) |
| **Input** | `UserId` required | `UserId` از Token (خودکار) |

### 2. احراز هویت

**JWT Token Structure:**
```json
{
  "sub": "123",                    // UserId
  "email": "user@example.com",
  "phone": "09123456789",
  "IsSignMainContract": "True",
  "exp": 1234567890
}
```

**استخراج UserId:**
```csharp
public class GetMyDataQueryHandler
{
    private readonly ICurrentUserService _currentUser;
    
    public async Task<Response> Handle(Query request, CancellationToken ct)
    {
        var userId = _currentUser.UserId;  // از JWT
        // Call CMS with userId
    }
}
```

### 3. DTO Mapping Pattern

**CMS DTO (خام):**
```csharp
public class CommissionPayoutDto
{
    public long Id { get; set; }
    public long UserId { get; set; }
    public int WeekNumber { get; set; }
    public long TotalAmount { get; set; }
    public CommissionPayoutStatus Status { get; set; }
    // ... 10 فیلد دیگر
}
```

**BFF Response DTO (مشتری‌محور):**
```csharp
public class MyCommissionPayoutDto
{
    public long Id { get; set; }
    public string WeekLabel { get; set; }        // "هفته 45 - آذر 1403"
    public string AmountFormatted { get; set; }  // "1,250,000 تومان"
    public string StatusText { get; set; }       // "پرداخت شده"
    public string StatusBadgeColor { get; set; } // "success"
    public string DatePersian { get; set; }      // "25 آذر 1403"
}
```

---

## 📞 مسائل و سوالات

### سوالات باز:

1. **پرداخت دستی پکیج طلایی** (نیازمندی #5):
   - منظور چیست؟ آیا جدا از فعال‌سازی باشگاه (56M) است؟
   - آیا در CMS Handler مربوطه وجود دارد؟

2. **فروشگاه "معمولی"** (نیازمندی #4):
   - چه بهبودهای خاصی مدنظر است؟
   - آیا Discount Shop جداست یا همان Store معمولی؟

3. **Dashboard "در یک نگاه"** (نیازمندی #3):
   - آیا `Profile/Index.razor` همان Dashboard است؟
   - یا نیاز به صفحه جداگانه `/dashboard` داریم؟

4. **گزارش شبکه و کمیسیون** (نیازمندی #6):
   - چه گزارش‌های دقیقی مدنظر است؟
   - PDF/Excel export لازم است؟

---

## 📈 معیارهای موفقیت (Success Metrics)

### مرحله 1 (بحرانی):
- [ ] کاربر بتواند عضو باشگاه شود (پرداخت 56M)
- [ ] کاربر 3 موجودی کیف‌پول را ببیند (Balance, Network, Discount)
- [ ] کاربر درخت شبکه واقعی خود را ببیند (نه Mock)
- [ ] کاربر کمیسیون هفتگی خود را ببیند
- [ ] کاربر بتواند برداشت کند (WithdrawBalance)

### مرحله 2 (ثانویه):
- [ ] کاربر از فروشگاه تخفیف خرید کند
- [ ] کاربر وضعیت وام دایا را ببیند
- [ ] کاربر پیام‌های عمومی را ببیند
- [ ] سبد خرید: Delete/Clear کار کند

### مرحله 3 (UI/UX):
- [ ] تمام صفحات Responsive باشند
- [ ] Skeleton loaders در همه جا
- [ ] لینک دعوت (Referral) فعال باشد
- [ ] نوتیفیکیشن Bell icon در Navbar

---

## 🎉 نتیجه‌گیری

**وضعیت فعلی**: 40% تکمیل (9 ماژول پایه)  
**هدف**: 95% تکمیل (17 ماژول کامل)  
**زمان تخمینی**: 4 هفته (3 مرحله اصلی + 1 اختیاری)

**اولویت‌های کلیدی**:
1. 🔴 ClubMembership + Dashboard (هفته 1)
2. 🔴 Network + Commission (هفته 2)
3. 🟡 DiscountShop + Enhancements (هفته 3)
4. 🟢 UI/UX Improvements (هفته 4)

**نکته مهم**: دقت کنیم که هیچ چیزی را جا نیندازیم و خارج از ساختار حرکت نکنیم ✅

</div>
