# 📝 Changelog - ۳۰ آذر ۱۴۰۴ (20 December 2025)

> **Session**: رفع باگ‌های BackOffice UI و فعال‌سازی قابلیت‌های Products

---

## 🎯 خلاصه Session

این session شامل رفع چندین باگ در صفحات BackOffice و فعال‌سازی قابلیت‌های صفحه Products بود.

---

## 🐛 Bug Fixes

### 1. صفحه `/network/balances` - ValidationException ✅

**مشکل**: خطای ValidationException هنگام لود صفحه بالانس‌های هفتگی

**علت**: Mapster mapping برای `GetUserWeeklyBalancesRequest` → `GetUserWeeklyBalancesQuery` وجود نداشت

**راه‌حل**: اضافه کردن mapping در `CommissionProfile.cs`:
```csharp
config.NewConfig<GetUserWeeklyBalancesRequest, GetUserWeeklyBalancesQuery>()
    .Map(dest => dest.PaginationState, src => src.PaginationState);
```

**فایل**: `BackOffice.BFF/src/BackOffice.BFF.WebApi/Common/Mappings/CommissionProfile.cs`

---

### 2. صفحه `/club/members` - داده‌ها لود نمی‌شدند ✅

**مشکل**: صفحه خالی بود و هیچ داده‌ای نمایش نمی‌داد

**علت**: Mapster mappings برای `GetAllClubMemberships` در CMS و BFF وجود نداشت

**راه‌حل**: ایجاد `ClubMembershipProfile.cs` در هر دو لایه

**فایل‌های جدید/تغییر یافته**:
- `CMS/src/CMSMicroservice.WebApi/Common/Mappings/ClubMembershipProfile.cs` (NEW)
- `BackOffice.BFF/src/BackOffice.BFF.WebApi/Common/Mappings/ClubMembershipProfile.cs` (REWRITTEN)

**Mappings اضافه شده**:
```csharp
// CMS
GetAllClubMembershipsRequest → GetAllClubMembershipsQuery
GetAllClubMembershipsResponseDto → GetAllClubMembershipsResponse

// BFF  
BFF.GetAllClubMembershipsRequest → GetAllClubMembershipsQuery
CMS.GetAllClubMembershipsResponse → BFF.GetAllClubMembershipsResponse
```

---

### 3. صفحه `/club/statistics` - Unimplemented Error ✅

**مشکل**: خطای `Status(StatusCode="Unimplemented", Detail="Method cms.ClubMembershipContract/GetClubStatistics is unimplemented")`

**علت**: متد `GetClubStatistics` در BFF Service override نشده بود

**راه‌حل**: 
1. اضافه کردن override در `ClubMembershipService.cs`:
```csharp
public override async Task<GetClubStatisticsResponse> GetClubStatistics(
    GetClubStatisticsRequest request, ServerCallContext context)
{
    return await _dispatchRequestToCQRS.Handle<GetClubStatisticsRequest, GetClubStatisticsQuery, GetClubStatisticsResponse>(request, context);
}
```

2. اضافه کردن mappings برای Statistics در هر دو Profile

**فایل‌های تغییر یافته**:
- `BackOffice.BFF/src/BackOffice.BFF.WebApi/Services/ClubMembershipService.cs`
- `CMS/src/CMSMicroservice.WebApi/Common/Mappings/ClubMembershipProfile.cs`
- `BackOffice.BFF/src/BackOffice.BFF.WebApi/Common/Mappings/ClubMembershipProfile.cs`

---

## ✨ New Features

### 4. فعال‌سازی قابلیت‌های صفحه Products ✅

**قبل**: همه دکمه‌ها پیام "در حال توسعه" نشان می‌دادند (کد comment شده بود)

**بعد**: همه قابلیت‌ها فعال شدند

**متدهای فعال شده در `ProductsMainPage.razor.cs`**:
- ✅ `CreateNew()` - ایجاد محصول جدید با CreateDialog
- ✅ `Update()` - ویرایش محصول با UpdateDialog  
- ✅ `OpenGallery()` - مدیریت گالری تصاویر با GalleryDialog
- ✅ `OpenTagAssignment()` - اختصاص تگ به محصول با AssignTagsDialog

**فایل**: `BackOffice/src/BackOffice/Pages/Products/ProductsMainPage.razor.cs`

---

### 5. فیلد "تعداد موجودی" در Products ✅

**اضافات در UI**:

| فایل | تغییر |
|------|-------|
| `CreateDialog.razor` | اضافه شدن فیلد `RemainingCount` |
| `UpdateDialog.razor` | اضافه شدن فیلد `RemainingCount` |
| `ProductsMainPage.razor` | اضافه شدن ستون موجودی با رنگ‌بندی |

**نمایش موجودی در لیست**:
- 🔴 **ناموجود** - اگر موجودی `0` یا کمتر (Chip قرمز)
- 🟡 **کم موجود** - اگر موجودی کمتر از `10` (Chip زرد)
- 🟢 **موجود** - اگر موجودی `10` یا بیشتر (Chip سبز)

**فیکس در BFF** (مهم!):
فیلد `RemainingCount` در BFF Application Commands نبود و باعث می‌شد مقدار ارسال/دریافت نشه:

```csharp
// BackOffice.BFF.Application/ProductsCQ/Commands/CreateNewProducts/CreateNewProductsCommand.cs
public int RemainingCount { get; init; }  // ← اضافه شد

// BackOffice.BFF.Application/ProductsCQ/Commands/UpdateProducts/UpdateProductsCommand.cs  
public int RemainingCount { get; init; }  // ← اضافه شد
```

---

## 📁 لیست کامل فایل‌های تغییر یافته

### BackOffice.BFF (5 فایل)
| فایل | تغییر |
|------|-------|
| `WebApi/Common/Mappings/CommissionProfile.cs` | اضافه شدن mapping برای GetUserWeeklyBalances |
| `WebApi/Common/Mappings/ClubMembershipProfile.cs` | بازنویسی کامل با mappings جدید |
| `WebApi/Services/ClubMembershipService.cs` | اضافه شدن GetClubStatistics override |
| `Application/.../CreateNewProductsCommand.cs` | اضافه شدن RemainingCount |
| `Application/.../UpdateProductsCommand.cs` | اضافه شدن RemainingCount |

### CMS (1 فایل جدید)
| فایل | تغییر |
|------|-------|
| `WebApi/Common/Mappings/ClubMembershipProfile.cs` | فایل جدید با mappings کامل |

### BackOffice UI (4 فایل)
| فایل | تغییر |
|------|-------|
| `Pages/Products/ProductsMainPage.razor.cs` | فعال‌سازی CreateNew, Update, OpenGallery, OpenTagAssignment |
| `Pages/Products/ProductsMainPage.razor` | اضافه شدن ستون موجودی |
| `Pages/Products/Components/CreateDialog.razor` | اضافه شدن فیلد موجودی |
| `Pages/Products/Components/UpdateDialog.razor` | اضافه شدن فیلد موجودی |

---

## 📊 Build Status

```
✅ BackOffice.BFF: Build succeeded (0 errors)
✅ CMS: Build succeeded (0 errors)
✅ BackOffice UI: Build succeeded (0 errors)
```

---

## 🔧 نکات فنی

### Mapster با Proto Types
برای proto types که immutable هستند، از `MapWith` استفاده کنید:
```csharp
config.NewConfig<SourceDto, ProtoResponse>()
    .MapWith(src => new ProtoResponse
    {
        Field1 = src.Field1,
        RepeatedField = { src.List?.Select(...) ?? Enumerable.Empty<...>() }
    });
```

### Alias Imports برای Proto Disambiguation
```csharp
using BffProtos = BackOffice.BFF.ClubMembership.Protobuf.Protos.ClubMembership;
using CmsProtos = CMSMicroservice.Protobuf.Protos.ClubMembership;
```
