diff --git a/docs/BUILD-FIX-STATUS.md b/docs/BUILD-FIX-STATUS.md deleted file mode 100644 index fa8fbda..0000000 --- a/docs/BUILD-FIX-STATUS.md +++ /dev/null @@ -1,501 +0,0 @@ -# BackOffice Build Fix Status - -> آخرین بروزرسانی: December 20, 2025 - -## وضعیت فعلی - -**Build Status**: ✅ SUCCESS - 0 Error - -### BackOffice.BFF Solution: -- **Build**: ✅ موفق - 0 Error -- **Proto Projects فعال**: - - ✅ BackOffice.BFF.Tag.Protobuf - - ✅ BackOffice.BFF.ProductTag.Protobuf - - ✅ BackOffice.BFF.DiscountProduct.Protobuf - - ✅ BackOffice.BFF.DiscountCategory.Protobuf - - ✅ BackOffice.BFF.DiscountOrder.Protobuf - - ✅ BackOffice.BFF.DiscountShoppingCart.Protobuf - - ✅ BackOffice.BFF.PublicMessage.Protobuf - - ✅ BackOffice.BFF.ManualPayment.Protobuf - - ✅ BackOffice.BFF.ClubMembership.Protobuf - - ✅ BackOffice.BFF.Commission.Protobuf - -### BackOffice UI: -- **Build**: ✅ موفق - 0 Error -- **Framework**: Blazor WebAssembly .NET 9.0 -- **UI Library**: MudBlazor 8.14.0 - -### CMS Microservice: -- **Build**: ✅ موفق - 0 Error - -**پیشرفت کلی**: از 60+ خطا به 0 خطا رسیدیم ✨ - ---- - -## ⚠️ ملاحظات مهم Proto Packages - -> **هشدار مهم**: هر تغییری در Proto files نیاز به این 3 مرحله دارد: - -### چک‌لیست اجباری بعد از تغییر Proto: - -1. **افزایش Version** در `.csproj`: - ```xml - 0.0.1420.0.143 - ``` - -2. **Pack کردن** Proto project: - ```bash - cd path/to/proto/project - dotnet pack -c Release - # ✅ خودکار push می‌شه به GitLab Registry - ``` - -3. **Update Version** در پروژه‌های وابسته (لایه بالاتر): - ```xml - - ``` - -**مثال**: تغییر در CMS Proto → Pack → Update در BFF Protos → Pack → Update در UI - -**⚠️ فراموش کردن این مراحل = Build Error یا Runtime Bug** - ---- - -## ماژول‌های فعال شده (Enabled Modules) - -### ✅ کاملاً فعال و تست شده: - -1. **DiscountShop Module** (فروشگاه تخفیفی) - - ✅ DiscountProductsMainPage - مدیریت محصولات تخفیفی - - ✅ DiscountCategoriesMainPage - مدیریت دسته‌بندی‌ها (با MudDataGrid) - - ✅ DiscountOrdersMainPage - مدیریت سفارشات - - ✅ SalesReports - گزارش فروش - - ✅ ProductImageGallery - گالری تصاویر (با MudBlazor 8 fixes) - - Services: IDiscountProductService, IDiscountCategoryService, IDiscountOrderService - -2. **PublicMessages Module** (پیام‌های عمومی) - - ✅ PublicMessagesMainPage - مدیریت پیام‌ها - - ✅ MessageFormDialog - فرم ایجاد/ویرایش - - ✅ MessageViewDialog - نمایش جزئیات - - ✅ MessageTemplatesDialog - قالب‌های آماده - - Services: IPublicMessageService - - Proto: BackOffice.BFF.PublicMessage.Protobuf - -3. **ManualPayment Module** (پرداخت‌های دستی) - - ✅ ManualPayments - صفحه اصلی مدیریت - - ✅ ManualPaymentDialog - فرم ایجاد و تایید/رد - - Services: Direct gRPC to ManualPaymentContract - - Proto: BackOffice.BFF.ManualPayment.Protobuf - -4. **Tag Module** (برچسب‌ها) - - ✅ TagManagementPage - مدیریت تگ‌ها - - ✅ TagEditDialog - ویرایش تگ - - Services: ITagService, IProductTagService - - Proto: BackOffice.BFF.Tag.Protobuf, BackOffice.BFF.ProductTag.Protobuf - -5. **Dashboard Widgets** - - ✅ DiscountShopWidget - آمار فروشگاه تخفیفی (7 روز اخیر) - -6. **Payment Pages** - - ✅ Transactions - صفحه تراکنش‌ها - -7. **DragDrop Pages** - - ✅ CategoryProductsDragDropPage - مدیریت محصولات دسته - - ✅ ProductCategoriesDragDropPage - مدیریت دسته‌های محصول - -8. **BulkEdit Module** - - ✅ BulkEdit - ویرایش گروهی محصولات (قیمت، موجودی، وضعیت) - - Proto: BackOffice.BFF.Products.Protobuf (BulkUpdateProductPrices, BulkUpdateProductStock, ToggleProductStatus) - - Note: استفاده از `BackOffice.BFF.Protobuf.Common.PaginationState` با using alias - -9. **Product Image Management** - ✅ FULLY OPERATIONAL - - ✅ GalleryDialog - گالری تصاویر محصول - - ✅ CreateDialog - ایجاد محصول با آپلود تصویر - - ✅ UpdateDialog - ویرایش محصول با آپلود تصویر - - ✅ Proto: GetProductGallery, AddProductImage, RemoveProductImage - - ✅ Messages: ImageFileModel, ProductGalleryItem - - ✅ Backend: ProductsService methods uncommented and active - - ✅ CQRS Handlers: AddProductImageCommandHandler, GetProductGalleryQueryHandler, RemoveProductImageCommandHandler - - ✅ CMS Integration: ProductGalleries microservice connected - - ✅ Image Optimization: SixLabors.ImageSharp (1200x1200 + 300x300 thumbnail) - ---- - -## ماژول‌های Exclude شده (نیاز به کار اضافی) - -**هیچ فایلی Exclude نیست!** ✅ - -تمامی صفحات و کامپوننت‌ها build می‌شوند. فقط Backend implementation برای Image Upload لازمه. - ---- - -## تغییرات مهم MudBlazor 8 - -### Breaking Changes برطرف شده: - -1. **MudDialogInstance → IMudDialogInstance** - ```csharp - // قبلی: - [CascadingParameter] MudDialogInstance MudDialog { get; set; } - - // جدید: - [CascadingParameter] IMudDialogInstance MudDialog { get; set; } - ``` - -2. **MudSwitch نیاز به T parameter** - ```razor - - - - - - ``` - -3. **MudChip نیاز به T parameter** - ```razor - - Text - - - Text - ``` - -4. **MudTreeView تغییر API** - - راه‌حل: جایگزینی با `MudDataGrid` در DiscountCategoriesMainPage - -5. **MudFileUpload تغییر signature** - ```csharp - // FilesChanged حالا IBrowserFile می‌گیرد نه IReadOnlyList - - ``` - -6. **DragEventArgs.PreventDefault() حذف شد** - ```razor - - @ondragover:preventDefault - ``` - ---- - -## تغییرات Proto - -### 1. Google.Protobuf.WellKnownTypes Simplification - -در همه جا از wrapper به مقدار مستقیم تغییر یافت: - -```csharp -// قبلی (اشتباه): -request.UserId = new Google.Protobuf.WellKnownTypes.Int64Value { Value = userId }; -request.Status = new Google.Protobuf.WellKnownTypes.Int32Value { Value = status }; -request.ReferenceNumber = new Google.Protobuf.WellKnownTypes.StringValue { Value = refNum }; - -// جدید (صحیح): -request.UserId = userId; -request.Status = status; -request.ReferenceNumber = refNum; -``` - -### 2. Timestamp to DateTime Conversion - -```csharp -// Proto Timestamp به DateTime تبدیل می‌شود: -var dateTime = timestamp.ToDateTime(); // به جای ToLocalTime() -``` - ---- - -## تغییرات معماری - -### BasePageComponent Pattern - -صفحات با فیلتر از `BasePageComponent` استفاده می‌کنند ولی `ReloadAsync()` ندارد. -راه‌حل: استفاده مستقیم از `MudDataGrid.ReloadServerData()`: - -```csharp -private MudDataGrid? _dataGrid; - -private async Task OnFilterSubmit() -{ - if (_dataGrid != null) - await _dataGrid.ReloadServerData(); -} -``` - ---- -- `ProductGalleryImage` -- `GetCategoriesRequest/Response` -- `UpdateProductCategoriesRequest` -- `GetProductsForCategoryRequest/Response` -- `UpdateCategoryProductsRequest` - -### 3. تغییرات csproj - -**Products از NuGet به ProjectReference تغییر کرد**: -```xml - - - - - -``` - -### 4. فیکس‌های MudBlazor - -**MudSwitch T parameter**: -- `Pages/Settings/UserSettings.razor` -- `Pages/Club/ClubMembers.razor` -- `Pages/Configuration/Configuration.razor` - -```razor - - - - - -``` - -### 5. فیکس Snackbar Duplicate - -در فایل‌های زیر `[Inject] ISnackbar Snackbar` حذف شد (چون در `_Imports.razor` inject شده): -- `ApplyDiscountDialog.razor.cs` -- `CancelOrderDialog.razor.cs` -- `ChangeOrderStatusDialog.razor.cs` - -### 6. فیکس ConfigureService.cs - -Using های زیر comment شدند: -```csharp -// using BackOffice.Services.DiscountProduct; -// using BackOffice.Services.DiscountCategory; -// using BackOffice.Services.DiscountOrder; -// using BackOffice.Services.Tag; -// using BackOffice.Services.ProductTag; -// using BackOffice.Services.PublicMessage; -``` - ---- - -## کارهای باقیمانده (TODO) - -### فوری - نیاز به Proto Methods: - -#### 1. Product Image Management -**فایل‌های Excluded**: -- `Pages/Products/Components/GalleryDialog.razor` -- `Pages/Products/Components/CreateDialog.razor` -- `Pages/Products/Components/UpdateDialog.razor` - -**Proto Methods مورد نیاز در `products.proto`**: -```protobuf -service ProductsContract { - // برای GalleryDialog: - rpc AddProductImage(AddProductImageRequest) returns (AddProductImageResponse); - rpc RemoveProductImage(RemoveProductImageRequest) returns (google.protobuf.Empty); - - // برای Create/Update Dialogs: - rpc CreateProductWithImage(CreateProductWithImageRequest) returns (CreateProductResponse); - rpc UpdateProductWithImage(UpdateProductWithImageRequest) returns (google.protobuf.Empty); -} - -message ImageFileModel { - bytes file = 1; - string mime = 2; - string file_name = 3; -} - -message AddProductImageRequest { - int64 product_id = 1; - string title = 2; - ImageFileModel image_file = 3; -} - -message AddProductImageResponse { - int64 product_gallery_id = 1; -} - -message RemoveProductImageRequest { - int64 product_gallery_id = 1; -} - -message CreateProductWithImageRequest { - // ... سایر فیلدهای محصول - ImageFileModel image_file = 1; - ImageFileModel thumbnail_file = 2; -} - -message UpdateProductWithImageRequest { - int64 id = 1; - // ... سایر فیلدها - ImageFileModel image_file = 2; - ImageFileModel thumbnail_file = 3; -} -``` - -**وضعیت**: 🔴 نیاز به پیاده‌سازی در Backend - ---- - -#### 2. BulkEdit Refactoring -**فایل Excluded**: `Pages/Products/BulkEdit.razor` - -**مشکل**: استفاده مستقیم از `CMSMicroservice.Protobuf.Protos` - -**راه‌حل**: -1. حذف dependency به `CMSMicroservice.Protobuf` -2. افزودن bulk update methods به `products.proto`: - -```protobuf -service ProductsContract { - rpc BulkUpdateProducts(BulkUpdateProductsRequest) returns (BulkUpdateProductsResponse); -} - -message BulkUpdateProductsRequest { - repeated int64 product_ids = 1; - google.protobuf.Int64Value new_price = 2; - google.protobuf.Int32Value new_discount = 3; - google.protobuf.Int32Value new_club_discount_percent = 4; - StockUpdateOperation stock_operation = 5; - google.protobuf.BoolValue status_enable = 6; -} - -enum StockUpdateOperation { - STOCK_NO_CHANGE = 0; - STOCK_SET = 1; - STOCK_ADD = 2; - STOCK_SUBTRACT = 3; -} - -message BulkUpdateProductsResponse { - int32 updated_count = 1; - repeated int64 failed_product_ids = 2; -} -``` - -**وضعیت**: 🔴 نیاز به پیاده‌سازی در Backend - ---- - -### اختیاری - بهبودها: - -#### 3. Transactions API Implementation -**فایل**: `Pages/Payment/Transactions.razor` - -**وضعیت فعلی**: ✅ Enabled ولی متد `LoadData` فقط `TODO` دارد - -**نیاز**: پیاده‌سازی Transaction API در Backend - ---- - -## آمار نهایی - -### ماژول‌های فعال: 7 ✅ -1. DiscountShop (Products, Categories, Orders, Reports) -2. PublicMessages -3. ManualPayments -4. Tag Management -5. Dashboard DiscountShopWidget -6. Transactions Page -7. DragDrop Pages (Category ↔ Products) - -### ماژول‌های Excluded: 3 ❌ -1. GalleryDialog (نیاز به Image Upload API) -2. CreateDialog/UpdateDialog (نیاز به Image Upload API) -3. BulkEdit (نیاز به Refactoring + Bulk API) - -### Build Errors: 0 🎉 -### Proto Projects: 14 فعال -### صفحات فعال: ~30+ -### کامپوننت‌های فعال: ~50+ - ---- - ---- - -## Handler های موقتاً Exclude شده در BackOffice.BFF.Application - -### فایل‌های Exclude شده: -```xml - - - - - -``` - -### دلیل Exclude: -این Handler ها فیلدهای متفاوتی با proto های CMS دارند و نیاز به بازنویسی دارند. - -### مثال عدم تطابق DiscountOrder: -**Handler انتظار دارد:** -- Request: `UserId`, `AddressId`, `DiscountBalanceAmount`, `GatewayAmount` -- Response: `OrderId`, `TrackingCode`, `RequiresGatewayPayment`, `GatewayPayableAmount` - -**Proto CMS دارد:** -- Request: `user_id`, `user_address_id`, `discount_balance_to_use`, `notes` -- Response: `success`, `message`, `order_id`, `gateway_amount`, `payment_url` - ---- - -## Proto Update های مورد نیاز - -### UserOrder.Protobuf -متدهای زیر باید اضافه شوند: -- `CancelOrderAsync(CancelOrderRequest)` -- `ApplyDiscountToOrderAsync(ApplyDiscountToOrderRequest)` -- `UpdateOrderStatusAsync(UpdateOrderStatusRequest)` - -فیلدهای زیر باید اضافه شوند: -- `VatAmount` -- `VatPercentage` -- `VatBaseAmount` -- `VatTotalAmount` -- `PaymentStatus.None` - -### Products.Protobuf -متدهای زیر باید اضافه شوند: -- `AddProductImageAsync` -- `RemoveProductImageAsync` - -فیلدهای زیر باید اضافه شوند: -- `ImageFile` (bytes) -- `ThumbnailFile` (bytes) -- `ImageFileModel` message - ---- - -## دستورات برای ادامه کار - -### 1. اجرای build برای دیدن خطاهای فعلی: -```bash -cd /home/masoud/Apps/project/FourSat/BackOffice/src/BackOffice -dotnet build 2>&1 | grep -E "error CS|Error" -``` - -### 2. فایل‌های مهم برای بررسی: -- `BackOffice.csproj` - لیست exclude ها و references -- `ConfigureService.cs` - DI registrations -- `_Imports.razor` - global using و inject ها - -### 3. Proto فایل‌های مهم: -- `BackOffice.BFF/src/Protobufs/BackOffice.BFF.Products.Protobuf/Protos/products.proto` -- `BackOffice.BFF/src/Protobufs/BackOffice.BFF.UserOrder.Protobuf/Protos/userorder.proto` - ---- - -## چک‌لیست برای chat جدید - -- [ ] خطاهای build رو چک کن -- [ ] `PaginationState` namespace رو فیکس کن -- [ ] `WithdrawalReports` binding رو فیکس کن -- [ ] `OpenGalleryDialog` رو comment کن در `ProductsMainPage` -- [ ] `DiscountShopWidget` رو از `SystemOverview` حذف کن -- [ ] تست build موفق - ---- - -## نکات مهم - -1. **هیچ فایلی حذف نشده** - فقط از build exclude شدند -2. **Proto های local** از ProjectReference استفاده می‌کنند نه NuGet -3. **MudBlazor 8.14.0** نیاز به `T` parameter برای generic components دارد -4. **Snackbar** در `_Imports.razor` inject شده، نباید در component ها duplicate بشه diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md deleted file mode 100644 index dcbd157..0000000 --- a/docs/CHANGELOG.md +++ /dev/null @@ -1,118 +0,0 @@ -# BackOffice Changelog - -> تاریخچه تغییرات پروژه BackOffice - ---- - -## December 20, 2025 - -### 🐛 Bug Fixes - -#### 1. صفحه `/network/balances` - ValidationException -**مشکل**: خطای ValidationException هنگام لود صفحه - -**راه‌حل**: اضافه کردن Mapster mapping در `CommissionProfile.cs`: -```csharp -config.NewConfig() - .Map(dest => dest.PaginationState, src => src.PaginationState); -``` - ---- - -#### 2. صفحه `/club/members` - داده‌ها لود نمی‌شدند -**مشکل**: صفحه خالی بود و داده‌ای نمایش نمی‌داد - -**راه‌حل**: ایجاد `ClubMembershipProfile.cs` در CMS و BFF با mappings کامل: -- `GetAllClubMembershipsRequest` ↔ `GetAllClubMembershipsQuery` -- `GetAllClubMembershipsResponseDto` ↔ `GetAllClubMembershipsResponse` - -**فایل‌های جدید**: -- `CMS/WebApi/Common/Mappings/ClubMembershipProfile.cs` -- `BackOffice.BFF/WebApi/Common/Mappings/ClubMembershipProfile.cs` (بازنویسی) - ---- - -#### 3. صفحه `/club/statistics` - Unimplemented Error -**مشکل**: خطای `Status(StatusCode="Unimplemented")` - -**راه‌حل**: -1. اضافه کردن override `GetClubStatistics` در `ClubMembershipService.cs` -2. اضافه کردن mappings برای Statistics در هر دو Profile - ---- - -### ✨ New Features - -#### 4. فعال‌سازی قابلیت‌های Products -**قبل**: همه دکمه‌ها "در حال توسعه" نشان می‌دادند - -**بعد**: همه قابلیت‌ها فعال شدند: -- ✅ ایجاد محصول جدید (CreateDialog) -- ✅ ویرایش محصول (UpdateDialog) -- ✅ گالری تصاویر (GalleryDialog) -- ✅ مدیریت تگ‌ها (AssignTagsDialog) - -**فایل**: `ProductsMainPage.razor.cs` - ---- - -#### 5. فیلد "تعداد موجودی" در Products -**اضافات**: -- فیلد موجودی در فرم ایجاد محصول -- فیلد موجودی در فرم ویرایش محصول -- ستون موجودی در لیست با رنگ‌بندی: - - 🔴 ناموجود (0 یا کمتر) - - 🟡 کم موجود (کمتر از 10) - - 🟢 موجود (10 یا بیشتر) - -**فایل‌های تغییر یافته**: -- `CreateDialog.razor` -- `UpdateDialog.razor` -- `ProductsMainPage.razor` -- `CreateNewProductsCommand.cs` (BFF) -- `UpdateProductsCommand.cs` (BFF) - ---- - -## December 6, 2025 - -### ✅ Major Milestones - -- Build Errors: 60+ → 0 -- MudBlazor 8 Migration Complete -- All Product Image Management APIs Implemented -- BulkEdit Module Enabled -- All Files Unexcluded - -### 🔧 Technical Changes - -- `IMudDialogInstance` جایگزین `MudDialogInstance` -- `MudSwitch T="bool"` اضافه شد -- `MudChip T="string"` اضافه شد -- Products از NuGet به ProjectReference تغییر کرد - ---- - -## December 1, 2025 - -### ✅ Network & Commission System - -- Commission Dashboard Complete -- Network Members Page Complete -- Club Members Page Complete -- Weekly Pool Management -- Withdrawal System -- Payout System - ---- - -## November 29, 2025 - -### ✅ Initial Setup - -- SystemConfigurations Table Created -- Base Configuration Values Added: - - `Network.MaxDepth`: 10 - - `Club.DefaultMembershipDurationMonths`: 12 - - `Commission.MinimumPayoutAmount`: 100000 - - `System.MaintenanceMode`: false diff --git a/docs/DISCOUNT-PRODUCT-FORM-REFACTORING.md b/docs/DISCOUNT-PRODUCT-FORM-REFACTORING.md deleted file mode 100644 index fc24687..0000000 --- a/docs/DISCOUNT-PRODUCT-FORM-REFACTORING.md +++ /dev/null @@ -1,274 +0,0 @@ -# Refactoring DiscountProduct Form - Session 2026-01-05 - -## هدف -یکسان‌سازی فرم ایجاد/ویرایش محصولات تخفیفی (DiscountProduct) با فرم محصولات عادی (Product) برای بهبود تجربه کاربری و افزودن قابلیت‌های حرفه‌ای. - -## تغییرات انجام شده - -### 1. Frontend - ProductFormDialog.razor - -#### قبل: -- استفاده از MudGrid -- TextField ساده برای مسیر تصویر (بدون قابلیت آپلود) -- TextField چند خطی برای توضیحات -- MudSelect ساده برای دسته‌بندی‌ها -- فاقد پیش‌نمایش تصویر - -#### بعد: -- **تغییر Layout**: از MudGrid به MudStack -- **آپلود تصویر**: - - MudFileUpload برای انتخاب تصویر اصلی و بندانگشتی - - پیش‌نمایش تصویر قبل از آپلود - - نمایش تصویر موجود در حالت ویرایش -- **ویرایشگر HTML**: - - استفاده از MudHtmlEditor برای FullInformation - - قابلیت فرمت‌دهی متن (bold, italic, لیست و...) -- **دسته‌بندی**: - - استفاده از MudSelect با MultiSelection - - لود خودکار DiscountCategory ها (نه Category های عادی) - - نمایش تعداد دسته‌بندی‌های انتخاب شده -- **فیلدهای اختصاصی حفظ شده**: - - MaxDiscountPercent - - IsActive - - SortOrder - -**فایل**: `/home/masoud/Apps/project/FourSat/BackOffice/src/BackOffice/Pages/DiscountShop/Components/ProductFormDialog.razor` - -### 2. Proto File - discountproduct.proto - -#### تغییرات: -```protobuf -message CreateDiscountProductRequest { - // ... فیلدهای قبلی - ImageFileModel image_file = 12; // جدید - ImageFileModel thumbnail_file = 13; // جدید -} - -message UpdateDiscountProductRequest { - // ... فیلدهای قبلی - ImageFileModel image_file = 12; // جدید - ImageFileModel thumbnail_file = 13; // جدید -} - -// تعریف مدل جدید -message ImageFileModel { - bytes file = 1; - string mime = 2; - string file_name = 3; -} -``` - -**فایل**: `/home/masoud/Apps/project/FourSat/BackOffice.BFF/src/Protobufs/BackOffice.BFF.DiscountProduct.Protobuf/Protos/discountproduct.proto` - -### 3. DTOs - Backend - -#### CreateDiscountProductDto و UpdateDiscountProductDto: -```csharp -// پراپرتی‌های جدید اضافه شده: -public byte[]? ImageFile { get; set; } -public string? ImageMime { get; set; } -public string? ImageFileName { get; set; } -public byte[]? ThumbnailFile { get; set; } -public string? ThumbnailMime { get; set; } -public string? ThumbnailFileName { get; set; } -``` - -**فایل‌ها**: -- `/home/masoud/Apps/project/FourSat/BackOffice/src/BackOffice/Services/DiscountProduct/IDiscountProductService.cs` - -### 4. Service Layer - DiscountProductService - -#### تغییرات CreateAsync و UpdateAsync: -```csharp -// افزودن لاجیک آپلود فایل -if (dto.ImageFile != null && !string.IsNullOrEmpty(dto.ImageMime)) { - request.ImageFile = new ImageFileModel { - File = ByteString.CopyFrom(dto.ImageFile), - Mime = dto.ImageMime, - FileName = dto.ImageFileName - }; -} -``` - -**فایل**: `/home/masoud/Apps/project/FourSat/BackOffice/src/BackOffice/Services/DiscountProduct/DiscountProductService.cs` - -### 5. Page Integration - DiscountProductsMainPage - -#### تغییرات در OpenCreateDialog و OpenEditDialog: -```csharp -var dto = new CreateDiscountProductDto { - // ... سایر فیلدها - InitialCount = 0, // تغییر: همیشه 0 - موجودی از طریق Inventory مدیریت می‌شود - ImageFile = formData.ImageFile, - ImageMime = formData.ImageMime, - ImageFileName = formData.ImageFileName, - ThumbnailFile = formData.ThumbnailFile, - ThumbnailMime = formData.ThumbnailMime, - ThumbnailFileName = formData.ThumbnailFileName -}; -``` - -**فایل**: `/home/masoud/Apps/project/FourSat/BackOffice/src/BackOffice/Pages/DiscountShop/DiscountProductsMainPage.razor` - -### 6. BFF - Validators - -#### اصلاح CreateDiscountProductCommandValidator: -```csharp -// قبل: الزامی بودن ShortInformation و FullInformation -RuleFor(x => x.ShortInformation) - .NotEmpty().WithMessage("اطلاعات کوتاه محصول الزامی است") - -// بعد: اختیاری شدن با چک طول -RuleFor(x => x.ShortInformation) - .MaximumLength(500) - .When(x => !string.IsNullOrEmpty(x.ShortInformation)); - -RuleFor(x => x.FullInformation) - .MaximumLength(10000) - .When(x => !string.IsNullOrEmpty(x.FullInformation)); -``` - -**فایل‌ها**: -- `/home/masoud/Apps/project/FourSat/BackOffice.BFF/src/BackOffice.BFF.Application/DiscountProductCQ/Commands/CreateDiscountProduct/CreateDiscountProductCommandValidator.cs` -- `/home/masoud/Apps/project/FourSat/BackOffice.BFF/src/BackOffice.BFF.Application/DiscountProductCQ/Commands/UpdateDiscountProduct/UpdateDiscountProductCommandValidator.cs` - -### 7. BFF - Command Handlers - -#### اصلاح CreateDiscountProductCommandHandler: -```csharp -// افزودن null coalescing برای جلوگیری از ArgumentNullException -var createRequest = new CreateDiscountProductRequest { - ShortInfomation = request.ShortInformation ?? string.Empty, - FullInformation = request.FullInformation ?? string.Empty, - // ... -}; - -// افزودن لاجیک آپلود فایل به File Storage -if (request.ImageFile != null && request.ImageFile.File.Length > 0) { - var imageFileInfo = await _context.FileInfos.CreateNewFileInfoAsync(...); - if (imageFileInfo != null) - createRequest.ImagePath = imageFileInfo.File; -} -``` - -**فایل‌ها**: -- `/home/masoud/Apps/project/FourSat/BackOffice.BFF/src/BackOffice.BFF.Application/DiscountProductCQ/Commands/CreateDiscountProduct/CreateDiscountProductCommandHandler.cs` -- `/home/masoud/Apps/project/FourSat/BackOffice.BFF/src/BackOffice.BFF.Application/DiscountProductCQ/Commands/UpdateDiscountProduct/UpdateDiscountProductCommandHandler.cs` - -### 8. CMS - Validators - -#### اصلاح CreateDiscountProductCommandValidator: -```csharp -// حذف الزامی بودن ImagePath و ThumbnailPath -// قبل: -RuleFor(v => v.ImagePath).NotEmpty() -RuleFor(v => v.ThumbnailPath).NotEmpty() - -// بعد: حذف شده - فایل‌ها از طریق BFF آپلود می‌شوند - -// ShortInformation و FullInformation اختیاری شدن -RuleFor(v => v.ShortInfomation) - .MaximumLength(500) - .When(v => !string.IsNullOrEmpty(v.ShortInfomation)); -``` - -**فایل‌ها**: -- `/home/masoud/Apps/project/FourSat/CMS/src/CMSMicroservice.Application/DiscountShopCQ/Commands/CreateDiscountProduct/CreateDiscountProductCommandValidator.cs` -- `/home/masoud/Apps/project/FourSat/CMS/src/CMSMicroservice.Application/DiscountShopCQ/Commands/UpdateDiscountProduct/UpdateDiscountProductCommandValidator.cs` - -### 9. Bug Fixes - -#### 9.1. Foreign Key Constraint Error -**مشکل**: استفاده از CategoryMultiSelectCombo که Category های عادی را لود می‌کرد، در حالی که DiscountProduct نیاز به DiscountCategory دارد. - -**راه‌حل**: -- برگشت به MudSelect ساده -- لود DiscountCategory از IDiscountCategoryService -- Flatten کردن tree برای نمایش در dropdown - -#### 9.2. GetDiscountProducts NullReferenceException -**مشکل**: `response.MetaData` یا `response.Models` می‌توانست null باشد. - -**راه‌حل**: -```csharp -Products = response.Models?.Select(p => new DiscountProductDto { - Created = p.Created?.ToDateTime() ?? DateTime.MinValue -}).ToList() ?? new List() -``` - -**فایل**: `/home/masoud/Apps/project/FourSat/BackOffice.BFF/src/BackOffice.BFF.Application/DiscountProductCQ/Queries/GetDiscountProducts/GetDiscountProductsQueryHandler.cs` - -#### 9.3. GetDiscountCategories Handler Bugs -**مشکل‌ها**: -1. `response.Categories` بدون null check -2. شرط‌های `string.IsNullOrWhiteSpace` معکوس بودند -3. `ParentCategoryId` چک نادرست -4. `node.Children` بدون null check - -**راه‌حل**: -```csharp -Categories = response.Categories?.Select(MapCategory).ToList() - ?? new List() - -// اصلاح شرط‌ها -Description = !string.IsNullOrWhiteSpace(node.Description) ? node.Description : string.Empty, -ParentCategoryId = node.ParentCategoryId != 0 ? node.ParentCategoryId : null, -ChildCategories = node.Children?.Select(MapCategory).ToList() - ?? new List() -``` - -**فایل**: `/home/masoud/Apps/project/FourSat/BackOffice.BFF/src/BackOffice.BFF.Application/DiscountCategoryCQ/Queries/GetDiscountCategories/GetDiscountCategoriesQueryHandler.cs` - -## Build و Deploy - -### Build Status -- ✅ BackOffice: 0 errors, 248 warnings (MudBlazor style warnings only) -- ✅ BackOffice.BFF: 0 errors -- ✅ CMS: 0 errors - -### دستور Build Proto -```bash -bash /home/masoud/Apps/project/FourSat/BackOffice/build-deps.sh -``` - -### فایل‌های نیاز به Deploy -1. **BackOffice.BFF** (stage) - - تغییرات: Validators, Command Handlers, Query Handlers - -2. **CMS** (stage) - - تغییرات: Validators - -3. **BackOffice** (local) - - در حال اجرا با `dotnet watch` - - تغییرات بلافاصله اعمال می‌شود - -## نتیجه نهایی - -### قابلیت‌های جدید: -✅ آپلود تصویر با drag & drop -✅ پیش‌نمایش تصویر قبل از ذخیره -✅ ویرایشگر HTML برای محتوای غنی -✅ انتخاب چندگانه دسته‌بندی با UI بهتر -✅ مدیریت صحیح DiscountCategory ها -✅ حذف الزامی بودن فیلدهای اختیاری -✅ رفع تمام خطاهای NullReference - -### تفاوت با قبل: -| قبل | بعد | -|-----|-----| -| TextField برای مسیر تصویر | آپلود فایل واقعی | -| TextField ساده | HTML Editor | -| CategoryMultiSelectCombo (اشتباه) | MudSelect با DiscountCategory | -| الزامی بودن توضیحات | اختیاری | -| خطای Foreign Key | حل شده | - -## نکات مهم - -1. **موجودی (InitialCount)**: همیشه 0 قرار می‌گیرد - موجودی باید از صفحه Inventory مدیریت شود -2. **دسته‌بندی**: حتماً DiscountCategory استفاده شود نه Category معمولی -3. **Validators**: فیلدهای اختیاری با `.When()` چک شوند -4. **Null Safety**: همیشه `??` و `?.` استفاده شود در LINQ queries - -## مراجع -- Proto Guide: `/home/masoud/Apps/project/FourSat/PROTO-PACKAGING-GUIDE.md` -- Build Script: `/home/masoud/Apps/project/FourSat/BackOffice/build-deps.sh` diff --git a/docs/MANUAL-ACTIVATION-FEATURE.md b/docs/MANUAL-ACTIVATION-FEATURE.md deleted file mode 100644 index a431acd..0000000 --- a/docs/MANUAL-ACTIVATION-FEATURE.md +++ /dev/null @@ -1,164 +0,0 @@ -# فیچر فعالسازی (پرداخت) دستی باشگاه مشتریان - -## خلاصه -این فیچر امکان فعالسازی دستی عضویت باشگاه مشتریان را برای ادمین فراهم می‌کند. ادمین می‌تواند کاربر را انتخاب کرده، تصویر فیش پرداخت را آپلود کند و عضویت را فعال کند. - -## تاریخ: 2 ژانویه 2026 - ---- - -## تغییرات انجام شده - -### 1. CMS (Backend) - -#### Entity - `ManualPayment.cs` -- اضافه شدن فیلد `ImageDocumentId` برای ذخیره شناسه سند در FMS - -```csharp -public long? ImageDocumentId { get; set; } -``` - -#### Proto - `manualpayment.proto` -- اضافه شدن `image_document_id` به `CreateManualPaymentRequest` (فیلد 7) -- اضافه شدن `image_document_id` به `ManualPaymentModel` (فیلد 21) - -#### Command - `CreateManualPaymentCommand.cs` -- اضافه شدن پراپرتی `ImageDocumentId` - -#### Handler - `CreateManualPaymentCommandHandler.cs` -- ذخیره `ImageDocumentId` از request در entity - ---- - -### 2. BFF (Backend For Frontend) - -#### Proto - `manualpayment.proto` -- اضافه شدن `image_document_id` به `ManualPaymentModel` (فیلد 21) -- اضافه شدن `FileUploadModel` برای آپلود فایل -- اضافه شدن `image_file` به `CreateManualPaymentRequest` - -#### Command - `CreateManualPaymentCommand.cs` -- اضافه شدن `FileUploadDto` برای دریافت فایل از فرانت - -#### Handler - `CreateManualPaymentCommandHandler.cs` -- اتصال به FMS برای آپلود فایل -- استخراج `ImagePath` و `ImageDocumentId` از پاسخ FMS -- ارسال هر دو به CMS - -```csharp -var fileInfo = await _context.FileInfos.CreateNewFileInfoAsync(new() -{ - Directory = "Images/ManualPayments", - IsBase64 = false, - MIME = request.ImageFile.Mime, - FileName = request.ImageFile.FileName, - File = ByteString.CopyFrom(request.ImageFile.File) -}, cancellationToken: cancellationToken); - -if (fileInfo != null) -{ - if (!string.IsNullOrWhiteSpace(fileInfo.File)) - grpcRequest.ImagePath = fileInfo.File; - if (fileInfo.Id > 0) - grpcRequest.ImageDocumentId = fileInfo.Id; -} -``` - -#### Query Handler - `GetManualPaymentsQueryHandler.cs` -- اضافه شدن mapping برای `ImagePath` و `ImageDocumentId` - -#### DTO - `GetManualPaymentsResponseDto.cs` -- اضافه شدن فیلدهای: -```csharp -public string? ImagePath { get; set; } -public long? ImageDocumentId { get; set; } -``` - -#### Mapping - `ManualPaymentProfile.cs` -- اضافه شدن mapping برای `FileUploadModel -> FileUploadDto` - ---- - -### 3. Frontend (Blazor) - -#### `ManualPaymentDialog.razor` -- استفاده از `UserAutoComplete` برای انتخاب کاربر -- استفاده از `MudFileUpload` برای آپلود تصویر فیش -- استفاده از `MudSelect` برای انتخاب نوع پرداخت -- پیش‌نمایش تصویر قبل از ارسال -- تغییر عنوان‌ها از "پرداخت دستی" به "فعالسازی دستی" - -#### `ManualPaymentDialog.razor.cs` -- هندل کردن انتخاب فایل با `IBrowserFile` -- تبدیل فایل به Base64 برای پیش‌نمایش -- ایجاد `FileUploadModel` برای ارسال به BFF -- مقادیر پیش‌فرض: - - `Type = 1` (واریز نقدی) - - `Description = "عضویت دستی باشگاه مشتریان"` - -#### `ManualPayments.razor` -- تغییر عنوان صفحه به "فعالسازی (پرداخت) دستی" -- تغییر دکمه به "ثبت فعالسازی دستی جدید" - -#### `NavMenu.razor` -- حذف آیتم منوی "پرداخت دستی عضویت" -- تغییر نام "پرداخت‌های دستی" به "فعالسازی (پرداخت) دستی" - -#### حذف شده -- `ManualMembershipPayment.razor` و `ManualMembershipPayment.razor.cs` - ---- - -## مقادیر ثابت - -```csharp -// مبلغ پایه پکیج: 56 میلیون ریال -SystemConstants.BasePackageAmount = 56_000_000; - -// شارژ کیف پول: -// - مجموع شارژ: 56M ریال -``` - ---- - -## فلو کامل - -1. ادمین کاربر را با `UserAutoComplete` انتخاب می‌کند -2. نوع پرداخت را انتخاب می‌کند (پیش‌فرض: واریز نقدی) -3. توضیحات را وارد می‌کند (پیش‌فرض: عضویت دستی باشگاه مشتریان) -4. تصویر فیش را آپلود می‌کند (اختیاری) -5. دکمه ثبت را می‌زند -6. Frontend فایل را به BFF ارسال می‌کند -7. BFF فایل را به FMS آپلود می‌کند -8. FMS مسیر فایل (`File`) و شناسه سند (`Id`) را برمی‌گرداند -9. BFF هر دو را به CMS ارسال می‌کند -10. CMS تراکنش، پرداخت دستی و لاگ کیف پول را ثبت می‌کند -11. کیف پول کاربر شارژ می‌شود - ---- - -## فایل‌های تغییر یافته - -### CMS -- `CMSMicroservice.Domain/Entities/Payment/ManualPayment.cs` -- `CMSMicroservice.Application/ManualPaymentCQ/Commands/CreateManualPayment/CreateManualPaymentCommand.cs` -- `CMSMicroservice.Application/ManualPaymentCQ/Commands/CreateManualPayment/CreateManualPaymentCommandHandler.cs` -- `Protos/manualpayment.proto` - -### BFF -- `BackOffice.BFF.Application/ManualPaymentCQ/Commands/CreateManualPayment/CreateManualPaymentCommand.cs` -- `BackOffice.BFF.Application/ManualPaymentCQ/Commands/CreateManualPayment/CreateManualPaymentCommandHandler.cs` -- `BackOffice.BFF.Application/ManualPaymentCQ/Queries/GetManualPayments/GetManualPaymentsQueryHandler.cs` -- `BackOffice.BFF.Application/ManualPaymentCQ/Queries/GetManualPayments/GetManualPaymentsResponseDto.cs` -- `BackOffice.BFF.Application/ManualPaymentCQ/ManualPaymentProfile.cs` -- `Protobufs/BackOffice.BFF.ManualPayment.Protobuf/Protos/manualpayment.proto` - -### Frontend -- `BackOffice/Pages/Payment/Components/ManualPaymentDialog.razor` -- `BackOffice/Pages/Payment/Components/ManualPaymentDialog.razor.cs` -- `BackOffice/Pages/Payment/ManualPayments.razor` -- `BackOffice/Shared/NavMenu.razor` - -### حذف شده -- `BackOffice.Main/Pages/Payment/ManualMembershipPayment.razor` -- `BackOffice.Main/Pages/Payment/ManualMembershipPayment.razor.cs` diff --git a/docs/MOVED-TO-TOTALDOC.md b/docs/MOVED-TO-TOTALDOC.md new file mode 100644 index 0000000..8e394a8 --- /dev/null +++ b/docs/MOVED-TO-TOTALDOC.md @@ -0,0 +1 @@ +Docs moved to /totalDoc — see totalDoc/INDEX.md diff --git a/docs/MOVED.md b/docs/MOVED.md deleted file mode 100644 index 42a7421..0000000 --- a/docs/MOVED.md +++ /dev/null @@ -1,28 +0,0 @@ -# ⚠️ توجه: مستندات اصلی منتقل شده - -مستندات اصلی پروژه در فولدر زیر قرار دارند: - -``` -/home/masoud/Apps/project/FourSat/totalDoc/ -``` - -## 🗂️ ساختار اصلی مستندات: - -- **00-INDEX.md** - فهرست جامع مستندات -- **QUICK-REFERENCE.md** - مرجع سریع -- **FINAL-STATUS.md** - وضعیت نهایی پروژه -- **CHANGELOG-2025-12-XX.md** - لاگ تغییرات روزانه -- **01-BUSINESS/** - منطق تجاری -- **02-ARCHITECTURE/** - معماری سیستم -- **03-BACKEND/** - مستندات Backend (CMS, BFF) -- **04-FRONTEND/** - مستندات Frontend (BackOffice, FrontOffice) -- **05-TASKS/** - کارهای جاری -- **06-DEPLOYMENT/** - راهنمای استقرار - -## 📝 این پوشه: - -فایل‌های این پوشه (`BackOffice/docs/`) برای مرجع محلی نگه داشته شده‌اند ولی **مستندات اصلی و به‌روز** در `totalDoc` قرار دارند. - ---- - -**تاریخ**: ۳۰ آذر ۱۴۰۴ (20 December 2025) diff --git a/docs/README.md b/docs/README.md deleted file mode 100644 index 6fdad22..0000000 --- a/docs/README.md +++ /dev/null @@ -1,34 +0,0 @@ -# BackOffice Documentation - README - -> آخرین بروزرسانی: **December 20, 2025** - -## فایل‌های این پوشه - -| فایل | شرح | -|------|-----| -| `STATUS.md` | وضعیت کلی پروژه و Build Status | -| `CHANGELOG.md` | تاریخچه تغییرات به ترتیب تاریخ | -| `TECHNICAL-NOTES.md` | نکات فنی، Mapster، MudBlazor، Proto | -| `development-plan.md` | برنامه توسعه (قدیمی - برای مرجع) | - ---- - -## وضعیت فعلی - -``` -✅ Build Status: SUCCESS (0 Errors) -✅ Proto Projects: 24 فعال -✅ صفحات فعال: 40+ -✅ Excluded Files: 0 -``` - -## دستورات سریع - -```bash -# Build همه -cd /home/masoud/Apps/project/FourSat/BackOffice/src -dotnet build BackOffice.sln - -# فقط UI -dotnet build BackOffice/BackOffice.csproj -``` diff --git a/docs/REMAINING-TASKS.md b/docs/REMAINING-TASKS.md deleted file mode 100644 index 1cc630b..0000000 --- a/docs/REMAINING-TASKS.md +++ /dev/null @@ -1,412 +0,0 @@ -# کارهای باقیمانده - BackOffice - -> آخرین بروزرسانی: January 1, 2026 - -## وضعیت کلی - -**Build Status**: ✅ SUCCESS (0 Errors) -**Enabled Modules**: 12+ ماژول کامل -**System Status**: **PRODUCTION READY** 🚀 - ---- - -## ✅ کارهای انجام شده - Session January 1, 2026 - -### فعال‌سازی ماژول‌های فروشگاه تخفیفی (DiscountShop Frontend) - -**وضعیت**: ✅ COMPLETED - همه چیز فعال و build موفق - -**فایل اصلی تغییر یافته**: -- `BackOffice/Common/Configure/ConfigureService.cs` - -**تغییرات**: - -#### 1. Using Statements فعال شدند: -```csharp -// Discount Shop Proto Clients -using BackOffice.BFF.DiscountProduct.Protobuf.Protos.DiscountProduct; -using BackOffice.BFF.DiscountCategory.Protobuf.Protos.DiscountCategory; -using BackOffice.BFF.DiscountOrder.Protobuf.Protos.DiscountOrder; -using BackOffice.BFF.Tag.Protobuf.Protos.Tag; -using BackOffice.BFF.ProductTag.Protobuf.Protos.ProductTag; -using Foursat.BackOffice.BFF.PublicMessage.Protobuf; - -// Application Services -using BackOffice.Services.DiscountProduct; -using BackOffice.Services.DiscountCategory; -using BackOffice.Services.DiscountOrder; -using BackOffice.Services.PublicMessage; -using BackOffice.Services.Tag; -``` - -#### 2. gRPC Clients فعال شدند: -```csharp -// Discount Shop Services -services.AddTransient(sp => new DiscountProductContract.DiscountProductContractClient(...)); -services.AddTransient(sp => new DiscountCategoryContract.DiscountCategoryContractClient(...)); -services.AddTransient(sp => new DiscountOrderContract.DiscountOrderContractClient(...)); - -// Public Message Service -services.AddTransient(sp => new PublicMessageContract.PublicMessageContractClient(...)); - -// Tag Management Services -services.AddTransient(sp => new TagContract.TagContractClient(...)); -services.AddTransient(sp => new ProductTagContract.ProductTagContractClient(...)); -``` - -#### 3. Application Services فعال شدند: -```csharp -services.AddScoped(); -services.AddScoped(); -services.AddScoped(); -services.AddScoped(); -services.AddScoped(); -``` - -### صفحات فعال شده: - -| صفحه | Route | توضیحات | -|------|-------|---------| -| مدیریت محصولات تخفیفی | `/discount-products` | CRUD + گالری تصاویر | -| مدیریت دسته‌بندی‌ها | `/discount-categories` | CRUD + سلسله‌مراتب | -| مدیریت سفارشات | `/discount-orders` | مشاهده + تغییر وضعیت | -| گزارش فروش | `/sales-reports` | آمار و نمودار | -| مدیریت تگ‌ها | `/tags` | CRUD تگ‌ها | -| پیام‌های عمومی | `/public-messages` | CRUD + انتشار | - ---- - -## ✅ کارهای انجام شده - Session December 20, 2025 - -### 1. صفحه `/network/balances` - ✅ FIXED -**مشکل**: ValidationException هنگام لود صفحه -**راه‌حل**: اضافه کردن Mapster mapping برای `GetUserWeeklyBalancesRequest` → `GetUserWeeklyBalancesQuery` - -**فایل تغییر یافته**: -- `BackOffice.BFF/WebApi/Common/Mappings/CommissionProfile.cs` - -```csharp -config.NewConfig() - .Map(dest => dest.PaginationState, src => src.PaginationState); -``` - -### 2. صفحه `/club/members` - ✅ FIXED -**مشکل**: داده‌ها لود نمی‌شدند (Mapster mapping نداشت) -**راه‌حل**: ایجاد ClubMembershipProfile در CMS و BFF - -**فایل‌های جدید**: -- `CMS/WebApi/Common/Mappings/ClubMembershipProfile.cs` (NEW) -- `BackOffice.BFF/WebApi/Common/Mappings/ClubMembershipProfile.cs` (REWRITTEN) - -**Mappings اضافه شده**: -- `GetAllClubMembershipsRequest` ↔ `GetAllClubMembershipsQuery` -- `GetAllClubMembershipsResponseDto` ↔ `GetAllClubMembershipsResponse` - -### 3. صفحه `/club/statistics` - ✅ FIXED -**مشکل**: خطای `Status(StatusCode="Unimplemented")` -**راه‌حل**: پیاده‌سازی متد gRPC در BFF و اضافه کردن mappings - -**فایل‌های تغییر یافته**: -- `BackOffice.BFF/WebApi/Services/ClubMembershipService.cs` - اضافه شدن `GetClubStatistics` override -- `CMS/WebApi/Common/Mappings/ClubMembershipProfile.cs` - اضافه شدن mappings -- `BackOffice.BFF/WebApi/Common/Mappings/ClubMembershipProfile.cs` - اضافه شدن mappings - -**Mappings اضافه شده**: -- `GetClubStatisticsRequest` ↔ `GetClubStatisticsQuery` -- `GetClubStatisticsResponseDto` ↔ `GetClubStatisticsResponse` -- PackageDistribution و MonthlyTrend mappings - -### 4. صفحه Products - ✅ ALL FEATURES ENABLED -**مشکل**: همه قابلیت‌ها disabled بودند و "در حال توسعه" نشان می‌دادند -**راه‌حل**: Uncomment کردن کدهای دیالوگ‌ها - -**فایل تغییر یافته**: -- `BackOffice/Pages/Products/ProductsMainPage.razor.cs` - -**قابلیت‌های فعال شده**: -- ✅ `CreateNew()` - ایجاد محصول جدید -- ✅ `Update()` - ویرایش محصول -- ✅ `OpenGallery()` - گالری تصاویر -- ✅ `OpenTagAssignment()` - اختصاص تگ - -### 5. فیلد "تعداد موجودی" در Products - ✅ ADDED -**مشکل**: فیلد RemainingCount در فرم‌ها و لیست نبود -**راه‌حل**: اضافه کردن فیلد به همه لایه‌ها - -**فایل‌های تغییر یافته**: -- `BackOffice/Pages/Products/Components/CreateDialog.razor` - اضافه شدن فیلد موجودی -- `BackOffice/Pages/Products/Components/UpdateDialog.razor` - اضافه شدن فیلد موجودی -- `BackOffice/Pages/Products/ProductsMainPage.razor` - اضافه شدن ستون موجودی با رنگ‌بندی -- `BackOffice.BFF.Application/ProductsCQ/Commands/CreateNewProducts/CreateNewProductsCommand.cs` - اضافه شدن `RemainingCount` -- `BackOffice.BFF.Application/ProductsCQ/Commands/UpdateProducts/UpdateProductsCommand.cs` - اضافه شدن `RemainingCount` - -**نمایش موجودی در لیست**: -- 🔴 **ناموجود** - اگر موجودی `0` یا کمتر (Chip قرمز) -- 🟡 **عدد** - اگر موجودی کمتر از `10` (Chip زرد - هشدار) -- 🟢 **عدد** - اگر موجودی `10` یا بیشتر (Chip سبز) - ---- - -## ✅ کارهای انجام شده قبلی - -### 1. BulkEdit Module - COMPLETED ✅ -- ✅ حذف dependency به CMSMicroservice -- ✅ استفاده از BackOffice.BFF.Products.Protobuf -- ✅ تصحیح PaginationState namespace issue -- ✅ فایل فعال شد و build موفق - -### 2. Product Image Management - Proto COMPLETED ✅ -- ✅ تعریف ImageFileModel message -- ✅ اضافه کردن GetProductGallery RPC -- ✅ اضافه کردن AddProductImage RPC -- ✅ اضافه کردن RemoveProductImage RPC -- ✅ اضافه کردن ImageFile و ThumbnailFile به Create/Update requests -- ✅ هر 3 دیالوگ فعال شدند و build موفق - -**فایل‌های Enabled**: -- `Pages/Products/Components/GalleryDialog.razor` ✅ -- `Pages/Products/Components/CreateDialog.razor` ✅ -- `Pages/Products/Components/UpdateDialog.razor` ✅ - ---- - -## 🔴 کارهای باقیمانده (Backend Only) - -### 1. Product Image Management - Backend Implementation - -**اولویت**: بالا -**وضعیت**: ✅ COMPLETED - همه چیز آماده! - -**آخرین تغییرات**: -- ✅ ProductsService.cs: همه methods فعال شدند (AddProductImage, GetProductGallery, RemoveProductImage) -- ✅ Application Layer: CQRS handlers از قبل پیاده‌سازی شده‌اند -- ✅ CMS Integration: ProductGalleries microservice متصل است -- ✅ Image Optimization: 1200x1200 main + 300x300 thumbnail ready - -#### Proto Messages (✅ Ready): -```protobuf -// Image file model -message ImageFileModel { - bytes file = 1; - string mime = 2; - string file_name = 3; -} - -// Get Product Gallery -rpc GetProductGallery(GetProductGalleryRequest) returns (GetProductGalleryResponse); - -message GetProductGalleryRequest { - int64 product_id = 1; -} - -message ProductGalleryItem { - int64 product_gallery_id = 1; - int64 product_image_id = 2; - string title = 3; - string image_path = 4; - string image_thumbnail_path = 5; -} - -message GetProductGalleryResponse { - repeated ProductGalleryItem items = 1; -} - -// Add Product Image -rpc AddProductImage(AddProductImageRequest) returns (AddProductImageResponse); - -message AddProductImageRequest { - int64 product_id = 1; - string title = 2; - ImageFileModel image_file = 3; -} - -message AddProductImageResponse { - int64 product_gallery_id = 1; - int64 product_image_id = 2; - string title = 3; - string image_path = 4; - string image_thumbnail_path = 5; -} - -// Remove Product Image -rpc RemoveProductImage(RemoveProductImageRequest) returns (google.protobuf.Empty); - -message RemoveProductImageRequest { - int64 product_gallery_id = 1; -} -``` - -#### Backend Implementation Steps: - -1. **افزودن Messages به Proto** ✅ (فقط تعریف) -2. **پیاده‌سازی RPCs در Backend**: - - AddProductImage: دریافت فایل، ذخیره در storage، ثبت در DB - - RemoveProductImage: حذف فایل از storage و DB - - CreateProductWithImage: ایجاد محصول + آپلود تصاویر - - UpdateProductWithImage: ویرایش محصول + آپلود تصاویر (اختیاری) - -3. **File Storage**: - - پیشنهاد: MinIO, Azure Blob, یا local file system - - ذخیره تصویر اصلی و thumbnail - - برگرداندن URL های قابل دسترسی - -4. **تست و Enable فایل‌ها در UI** - -**زمان تخمینی**: 2-3 روز کاری - ---- - -### 2. BulkEdit Backend Implementation (اختیاری) - -**اولویت**: پایین -**وضعیت**: ✅ UI کامل، Backend موجود و کار می‌کند - -**نکته**: BulkEdit از RPCهای موجود استفاده می‌کند: -- `BulkUpdateProductPricesAsync` ✅ -- `BulkUpdateProductStockAsync` ✅ -- `ToggleProductStatusAsync` ✅ - -همه چیز آماده و کار می‌کند! فقط نیاز به تست دارد. - ---- - -### 3. Transactions API Implementation - -**اولویت**: پایین -**وضعیت**: UI آماده، API نیاز به پیاده‌سازی - -#### فایل: -- `Pages/Payment/Transactions.razor` - ✅ Enabled اما TODO - -#### وضعیت فعلی: -```csharp -private async Task> LoadData(GridState state) -{ - // TODO: Connect to BackOffice.BFF Transactions when API is ready - await Task.CompletedTask; - - return new GridData - { - Items = Array.Empty(), - TotalItems = 0 - }; -} -``` - -#### نیاز: -- ایجاد Transaction proto در BackOffice.BFF -- پیاده‌سازی GetTransactions RPC -- اتصال UI به API - -**زمان تخمینی**: 1 روز کاری - ---- - -## 📊 آمار پیشرفت - -### Modules Status: - -| Module | Status | Files | Notes | -|--------|--------|-------|-------| -| DiscountShop | ✅ Complete | 10+ | Products, Categories, Orders, Reports | -| PublicMessages | ✅ Complete | 4 | CRUD + Templates | -| ManualPayments | ✅ Complete | 2 | Create, Approve, Reject | -| Tag Management | ✅ Complete | 3 | CRUD Tags | -| Dashboard Widget | ✅ Complete | 1 | DiscountShop Stats | -| Transactions | ⚠️ Partial | 1 | UI ready, API TODO | -| DragDrop Pages | ✅ Complete | 2 | Category ↔ Products | -| **BulkEdit** | ✅ Complete | 1 | Fully working! | -| **Product Images** | ✅ Complete | 3 | Backend FULLY implemented! | - -### Overall Progress: - -- **Enabled**: 38+ صفحه و کامپوننت ✅ -- **Blocked**: 0 فایل ✅ -- **Proto Projects**: 14 فعال -- **Build Errors**: 0 ✅ -- **UI Completion**: 100% 🎉 -- **Backend Implementation**: 100% ✅✅✅ -- **System Status**: FULLY OPERATIONAL 🚀 - ---- - -## 🎯 Next Steps - -### ✅ ALL TASKS COMPLETED! - -**BackOffice System Status**: **PRODUCTION READY** 🚀 - -**آماده برای استفاده**: - ---- - -## 📝 نکات مهم - -### ⚠️ CRITICAL: Proto Package Management - -**هر بار که Proto تغییر می‌کند (در هر سرویسی):** - -```bash -# 1. افزایش Version در csproj -X.Y.ZX.Y.Z+1 - -# 2. Pack کردن -cd path/to/proto/project -dotnet pack -c Release # Auto-push به GitLab - -# 3. Update در لایه بالاتر - -``` - -**این قانون برای همه سرویس‌ها صادق است:** -- CMS → BFF ها -- BackOffice.BFF → BackOffice UI -- FrontOffice.BFF → FrontOffice UI - -**⚠️ عدم رعایت = ساعت‌ها Debug بیهوده!** - ---- - -### برای Backend Developer: - -1. **Image Upload**: - - استفاده از streaming برای فایل‌های بزرگ - - اعتبارسنجی نوع و سایز فایل - - تولید thumbnail خودکار - - مدیریت storage (MinIO recommended) - -2. **Bulk Update**: - - استفاده از Transaction برای atomicity - - مدیریت concurrent updates - - Logging تغییرات برای audit - -3. **Security**: - - اعتبارسنجی سمت سرور - - محدودیت سایز فایل - - sanitize file names - -### برای Frontend Developer: - -1. **Image Upload**: - - Progress indicator - - Preview قبل از upload - - مدیریت خطاها - - Retry mechanism - -2. **BulkEdit**: - - Confirmation قبل از تغییرات - - نمایش نتایج - - Undo capability (آینده) - ---- - -## 🔗 Related Docs - -- [BUILD-FIX-STATUS.md](./BUILD-FIX-STATUS.md) - وضعیت کلی build -- [EXCLUDED-FILES.md](./EXCLUDED-FILES.md) - لیست فایل‌های exclude -- [PROTO-DEPENDENCIES.md](./PROTO-DEPENDENCIES.md) - وابستگی‌های proto - ---- - -**Last Updated**: December 6, 2025 -**By**: GitHub Copilot (Claude Sonnet 4.5) diff --git a/docs/SESSION-2025-12-20.md b/docs/SESSION-2025-12-20.md deleted file mode 100644 index fbfe2fb..0000000 --- a/docs/SESSION-2025-12-20.md +++ /dev/null @@ -1,311 +0,0 @@ -# Session Log - December 20, 2025 - -## خلاصه Session - -این session شامل رفع چندین باگ در صفحات BackOffice و فعال‌سازی قابلیت‌های Products بود. - ---- - -## 1. فیکس صفحه `/network/balances` - -### مشکل -``` -ValidationException هنگام لود صفحه بالانس‌های هفتگی -``` - -### علت -Mapster mapping برای تبدیل `GetUserWeeklyBalancesRequest` به `GetUserWeeklyBalancesQuery` وجود نداشت. - -### راه‌حل -اضافه کردن mapping در `CommissionProfile.cs`: - -```csharp -// File: BackOffice.BFF/src/BackOffice.BFF.WebApi/Common/Mappings/CommissionProfile.cs - -config.NewConfig() - .Map(dest => dest.PaginationState, src => src.PaginationState); -``` - ---- - -## 2. فیکس صفحه `/club/members` - -### مشکل -``` -صفحه لود می‌شد ولی هیچ داده‌ای نمایش نمی‌داد -``` - -### علت -Mapster mappings در CMS و BFF برای `GetAllClubMemberships` وجود نداشتند. - -### راه‌حل -ایجاد `ClubMembershipProfile.cs` در هر دو لایه: - -**CMS/src/CMSMicroservice.WebApi/Common/Mappings/ClubMembershipProfile.cs** (NEW): -```csharp -public class ClubMembershipProfile : IRegister -{ - void IRegister.Register(TypeAdapterConfig config) - { - // GetAllClubMemberships mappings - config.NewConfig() - .Map(dest => dest.PaginationState, src => src.PaginationState) - .Map(dest => dest.Filter, src => src.Filter); - - config.NewConfig() - .MapWith(src => new GetAllClubMembershipsResponse - { - MetaData = src.MetaData != null ? new CMSMicroservice.Protobuf.Common.MetaData - { - PageIndex = src.MetaData.PageIndex, - TotalPages = src.MetaData.TotalPages, - TotalCount = src.MetaData.TotalCount - } : null, - Models = { src.Models?.Select(...) ?? Enumerable.Empty<...>() } - }); - } -} -``` - -**BackOffice.BFF/src/BackOffice.BFF.WebApi/Common/Mappings/ClubMembershipProfile.cs** (REWRITTEN): -- Mapping از BFF Proto به Query -- Mapping از CMS Response به BFF Proto Response -- استفاده از alias imports برای disambiguation - ---- - -## 3. فیکس صفحه `/club/statistics` - -### مشکل -``` -Status(StatusCode="Unimplemented", Detail="Method cms.ClubMembershipContract/GetClubStatistics is unimplemented") -``` - -### علت -متد `GetClubStatistics` در BFF Service override نشده بود. - -### راه‌حل - -**1. اضافه کردن override در ClubMembershipService.cs:** -```csharp -public override async Task GetClubStatistics( - GetClubStatisticsRequest request, ServerCallContext context) -{ - return await _dispatchRequestToCQRS.Handle(request, context); -} -``` - -**2. اضافه کردن mappings در CMS ClubMembershipProfile:** -```csharp -config.NewConfig(); - -config.NewConfig() - .MapWith(src => new GetClubStatisticsResponse - { - TotalMembers = src.TotalMembers, - ActiveMembers = src.ActiveMembers, - // ... سایر فیلدها - PackageDistribution = { src.PackageDistribution?.Select(...) }, - MonthlyTrend = { src.MonthlyTrend?.Select(...) } - }); -``` - -**3. اضافه کردن mappings در BFF ClubMembershipProfile:** -- Mapping از BFF Proto به Query -- Mapping از CMS Response DTO به BFF Proto Response - ---- - -## 4. فعال‌سازی قابلیت‌های Products - -### مشکل -``` -همه دکمه‌های صفحه محصولات "در حال توسعه" نشان می‌دادند -``` - -### علت -کدهای دیالوگ‌ها comment شده بودند با TODO markers. - -### راه‌حل -Uncomment کردن کدها در `ProductsMainPage.razor.cs`: - -**فایل: BackOffice/src/BackOffice/Pages/Products/ProductsMainPage.razor.cs** - -```csharp -// ✅ CreateNew() - فعال شد -public async Task CreateNew() -{ - var dialog = await DialogService.ShowAsync("افزودن محصول", - new DialogParameters { { x => x.Model, new CreateNewProductsRequest() } }, - new DialogOptions { CloseButton = true, FullWidth = true, MaxWidth = MaxWidth.Small }); - // ... -} - -// ✅ Update() - فعال شد -public async Task Update(DataModel model) -{ - var parameters = new DialogParameters { { x => x.Model, model.Adapt() } }; - var dialog = await DialogService.ShowAsync("ویرایش محصول", parameters, ...); - // ... -} - -// ✅ OpenGallery() - فعال شد -public async Task OpenGallery(DataModel model) -{ - var parameters = new DialogParameters - { - { x => x.ProductId, model.Id }, - { x => x.ProductTitle, model.Title } - }; - await DialogService.ShowAsync("گالری تصاویر", parameters, ...); -} - -// ✅ OpenTagAssignment() - فعال شد -public async Task OpenTagAssignment(DataModel model) -{ - var parameters = new DialogParameters - { - { x => x.ProductId, model.Id }, - { x => x.ProductTitle, model.Title } - }; - await DialogService.ShowAsync("مدیریت تگ‌های محصول", parameters, ...); -} -``` - -**Using statement uncomment شد:** -```csharp -using BackOffice.Pages.Tag.Components; // برای AssignTagsDialog -``` - ---- - -## 5. اضافه کردن فیلد "تعداد موجودی" به Products - -### نیاز -نمایش و ویرایش تعداد موجودی محصول در فرم‌ها و لیست - -### تغییرات - -**1. فرم‌های دیالوگ (CreateDialog.razor & UpdateDialog.razor):** -```razor - - - - - - - - -``` - -**2. ستون جدید در لیست (ProductsMainPage.razor):** -```razor - - - @if (context.Item.RemainingCount <= 0) - { - ناموجود - } - else if (context.Item.RemainingCount < 10) - { - @context.Item.RemainingCount - } - else - { - @context.Item.RemainingCount - } - - -``` - -**3. اضافه کردن فیلد به BFF Commands (فیکس مهم!):** - -مشکل: فیلد `RemainingCount` در BFF Application Commands نبود و باعث می‌شد مقدار ارسال/دریافت نشه. - -**CreateNewProductsCommand.cs:** -```csharp -public int Discount { get; init; } -public int Rate { get; init; } -public int RemainingCount { get; init; } // ← اضافه شد -public ImageFileModel ImageFile { get; init; } -``` - -**UpdateProductsCommand.cs:** -```csharp -public int Discount { get; init; } -public int Rate { get; init; } -public int RemainingCount { get; init; } // ← اضافه شد -public string ImagePath { get; init; } -``` - ---- - -## لیست کامل فایل‌های تغییر یافته - -### BackOffice.BFF -| فایل | نوع تغییر | توضیح | -|------|----------|-------| -| `WebApi/Common/Mappings/CommissionProfile.cs` | MODIFIED | اضافه شدن mapping برای GetUserWeeklyBalances | -| `WebApi/Common/Mappings/ClubMembershipProfile.cs` | REWRITTEN | Mappings کامل برای ClubMembership | -| `WebApi/Services/ClubMembershipService.cs` | MODIFIED | اضافه شدن GetClubStatistics override | -| `Application/ProductsCQ/Commands/CreateNewProducts/CreateNewProductsCommand.cs` | MODIFIED | اضافه شدن RemainingCount | -| `Application/ProductsCQ/Commands/UpdateProducts/UpdateProductsCommand.cs` | MODIFIED | اضافه شدن RemainingCount | - -### CMS -| فایل | نوع تغییر | توضیح | -|------|----------|-------| -| `WebApi/Common/Mappings/ClubMembershipProfile.cs` | NEW | Mappings برای ClubMembership | - -### BackOffice UI -| فایل | نوع تغییر | توضیح | -|------|----------|-------| -| `Pages/Products/ProductsMainPage.razor.cs` | MODIFIED | فعال‌سازی CreateNew, Update, OpenGallery, OpenTagAssignment | -| `Pages/Products/ProductsMainPage.razor` | MODIFIED | اضافه شدن ستون موجودی | -| `Pages/Products/Components/CreateDialog.razor` | MODIFIED | اضافه شدن فیلد موجودی | -| `Pages/Products/Components/UpdateDialog.razor` | MODIFIED | اضافه شدن فیلد موجودی | - ---- - -## نکات فنی مهم - -### 1. Mapster با Proto Types -برای proto types که immutable هستند، باید از `MapWith` استفاده کرد: - -```csharp -config.NewConfig() - .MapWith(src => new ProtoResponse - { - Field1 = src.Field1, - RepeatedField = { src.List?.Select(...) ?? Enumerable.Empty<...>() } - }); -``` - -### 2. Alias Imports برای Proto Disambiguation -وقتی دو proto با اسم یکسان داریم: - -```csharp -using BffProtos = BackOffice.BFF.ClubMembership.Protobuf.Protos.ClubMembership; -using CmsProtos = CMSMicroservice.Protobuf.Protos.ClubMembership; -``` - -### 3. Null-Safe MetaData Mapping -```csharp -MetaData = src.MetaData != null ? new MetaData -{ - PageIndex = src.MetaData.PageIndex, - TotalPages = src.MetaData.TotalPages, - TotalCount = src.MetaData.TotalCount -} : null -``` - ---- - -## Build Status پایان Session - -``` -BackOffice.BFF: ✅ Build succeeded (0 errors) -CMS: ✅ Build succeeded (0 errors) -BackOffice UI: ✅ Build succeeded (0 errors) -``` diff --git a/docs/SESSION-2026-01-03-PROTO-DLL-MIGRATION.md b/docs/SESSION-2026-01-03-PROTO-DLL-MIGRATION.md deleted file mode 100644 index 8bc8972..0000000 --- a/docs/SESSION-2026-01-03-PROTO-DLL-MIGRATION.md +++ /dev/null @@ -1,289 +0,0 @@ -# Session 2026-01-03: Proto DLL Migration & Domain Changes - -> **تاریخ**: January 3, 2026 -> **موضوع**: مایگریشن به DLL-based Proto References + تغییر دامنه‌ها - ---- - -## 📋 خلاصه تغییرات - -### 1. ✅ مایگریشن Proto References به DLL-based Approach - -**مشکل**: در CI/CD نمی‌توانستیم از `ProjectReference` به پروژه‌های proto در `BackOffice.BFF` استفاده کنیم چون ریپوها جدا هستند. - -**راه‌حل**: ایجاد سیستم hybrid با DLL های pre-built: - -#### فایل‌های ایجاد شده: - -1. **`BackOffice/build-deps.sh`**: - ```bash - #!/bin/bash - # Build all BFF proto dependencies and copy DLLs to libs folder - - # Builds all 24 proto projects from BackOffice.BFF/src/Protobufs/ - # Copies DLLs to BackOffice/libs/ folder - # Supports both net8.0 and net9.0 target frameworks - ``` - -2. **`BackOffice/libs/`**: فولدر شامل 24 فایل DLL: - - `BackOffice.BFF.Category.Protobuf.dll` - - `BackOffice.BFF.ClubMembership.Protobuf.dll` - - `BackOffice.BFF.Commission.Protobuf.dll` - - `BackOffice.BFF.Common.Protobuf.dll` - - `BackOffice.BFF.Configuration.Protobuf.dll` - - `BackOffice.BFF.DiscountCategory.Protobuf.dll` - - `BackOffice.BFF.DiscountOrder.Protobuf.dll` - - `BackOffice.BFF.DiscountProduct.Protobuf.dll` - - `BackOffice.BFF.DiscountShoppingCart.Protobuf.dll` - - `BackOffice.BFF.Health.Protobuf.dll` - - `BackOffice.BFF.Inventory.Protobuf.dll` - - `BackOffice.BFF.ManualPayment.Protobuf.dll` - - `BackOffice.BFF.NetworkMembership.Protobuf.dll` - - `BackOffice.BFF.Otp.Protobuf.dll` - - `BackOffice.BFF.Package.Protobuf.dll` - - `BackOffice.BFF.Products.Protobuf.dll` - - `BackOffice.BFF.ProductTag.Protobuf.dll` - - `BackOffice.BFF.PublicMessage.Protobuf.dll` ⚠️ (net8.0) - - `BackOffice.BFF.Role.Protobuf.dll` - - `BackOffice.BFF.Tag.Protobuf.dll` - - `BackOffice.BFF.User.Protobuf.dll` - - `BackOffice.BFF.UserAddress.Protobuf.dll` - - `BackOffice.BFF.UserOrder.Protobuf.dll` - - `BackOffice.BFF.UserRole.Protobuf.dll` - -#### تغییرات در `BackOffice/src/BackOffice/BackOffice.csproj`: - -**PackageReferences اضافه شده** (برای transitive dependencies): -```xml - - - - - - -``` - -**Conditional ItemGroups**: -```xml - - - - ../../libs/BackOffice.BFF.Common.Protobuf.dll - - - - - - - - - -``` - -#### تغییرات در `BackOffice/Dockerfile`: -```dockerfile -# Copy pre-built proto DLLs -COPY ["libs/", "libs/"] -``` - -#### مشکلات حل شده: - -1. **Google.Protobuf Version Conflict**: - - مشکل: `PublicMessage.Protobuf` از ورژن `3.28.3` استفاده می‌کرد ولی بقیه از `3.23.3` - - راه‌حل: آپگرید به `3.28.3` در `BackOffice.csproj` - -2. **Grpc.Core.Api Version Conflict**: - - مشکل: Downgrade از `2.71.0` به `2.54.0` - - راه‌حل: تنظیم explicit version `2.71.0` در `BackOffice.csproj` - -3. **PublicMessage.Protobuf Missing**: - - مشکل: این پروژه `net8.0` است نه `net9.0` - - راه‌حل: اسکریپت `build-deps.sh` حالا هر دو framework را چک می‌کند - -### نتیجه: -✅ **Build: SUCCESS** (0 Errors, 246 Warnings - فقط MudBlazor) -✅ **Publish: SUCCESS** - همه 24 proto assembly به WASM کامپایل شدند -✅ **CI/CD Ready**: می‌توان با `./build-deps.sh` قبل از build، DLL ها را آماده کرد - ---- - -## 2. ✅ تغییر دامنه‌ها (Domain Migration) - -### تغییر از `*.foursat.afrino.co` به `*.se.kbs1.ir` - -**دستور اجرا شده**: -```bash -cd /home/masoud/Apps/project/FourSat -find . -type f \( -name "*.json" -o -name "*.yml" -o -name "*.yaml" \) \ - -exec sed -i 's/foursat\.afrino\.co/se.kbs1.ir/g' {} \; -``` - -#### فایل‌های تغییر یافته: - -**Workflow Files** (`.gitea/workflows/*.yml`): -- `BackOffice/.gitea/workflows/prod-deploy.yml` -- `BackOffice/.gitea/workflows/kub-deploy.yml` -- `BackOffice.BFF/.gitea/workflows/prod-deploy.yml` -- `BackOffice.BFF/.gitea/workflows/kub-deploy.yml` -- `FrontOffice/.gitea/workflows/prod-deploy.yml` -- `FrontOffice/.gitea/workflows/kub-deploy.yml` -- `FrontOffice.BFF/.gitea/workflows/prod-deploy.yml` -- `FrontOffice.BFF/.gitea/workflows/kub-deploy.yml` -- `CMS/.gitea/workflows/prod-deploy.yml` -- `CMS/.gitea/workflows/kub-deploy.yml` - -**تغییرات در Workflows**: -```yaml -# قبل: -EXTERNAL_REGISTRY: git.foursat.afrino.co -"insecure-registries": ["git.foursat.afrino.co", "gitea-svc:3000"] - -# بعد: -EXTERNAL_REGISTRY: git.se.kbs1.ir -"insecure-registries": ["git.se.kbs1.ir", "gitea-svc:3000"] -``` - -**Configuration Files** (appsettings): -- `BackOffice/src/BackOffice/wwwroot/appsettings.json` -- `BackOffice/src/BackOffice/wwwroot/appsettings.Staging.json` -- `FrontOffice/src/FrontOffice.Main/appsettings.json` -- `FrontOffice/src/FrontOffice.Main/appsettings.Staging.json` -- `FrontOffice.BFF/src/FrontOffice.BFF.WebApi/appsettings.json` - -**تغییرات در appsettings**: -```json -// BackOffice -"GwUrl": "https://backoffice-bff.se.kbs1.ir" - -// FrontOffice -"GwUrl": "https://frontoffice-bff.se.kbs1.ir" - -// FrontOffice.BFF -"CMSMSAddress": "https://cms.se.kbs1.ir" -``` - -### نتیجه: -✅ **21 فایل** با موفقیت تغییر کرد -✅ **0 آدرس قدیمی** باقی مانده - ---- - -## 3. ✅ تغییر Git Remote URLs - -**دستورات اجرا شده**: -```bash -# FrontOffice -cd FrontOffice -git remote set-url kub-stage https://git.se.kbs1.ir/admin/FrontOffice.git - -# BackOffice -cd BackOffice -git remote set-url kub-stage https://git.se.kbs1.ir/admin/BackOffice.git - -# BackOffice.BFF -cd BackOffice.BFF -git remote set-url kub-stage https://git.se.kbs1.ir/admin/BackOffice.BFF.git - -# FrontOffice.BFF -cd FrontOffice.BFF -git remote set-url kub-stage https://git.se.kbs1.ir/admin/FrontOffice.BFF.git - -# CMS -cd CMS -git remote set-url gitea https://git.se.kbs1.ir/admin/CMS.git - -# totalDoc -cd totalDoc -git remote set-url foursatDocs https://git.se.kbs1.ir/FourSat/docs.git -``` - -### نتیجه: -✅ **6 ریپو** بروز شد -✅ همه remote ها به `git.se.kbs1.ir` تغییر کرد - ---- - -## 📊 آمار کلی - -| مورد | تعداد | -|------|-------| -| Proto DLL های ایجاد شده | 24 | -| فایل‌های JSON/YAML تغییر یافته | 21 | -| Git Repositories بروز شده | 6 | -| Build Errors | 0 ✅ | -| Build Warnings | 246 (MudBlazor) | - ---- - -## 🚀 دستورات CI/CD - -### قبل از Build/Deploy: -```bash -# 1. Build proto dependencies -cd /home/masoud/Apps/project/FourSat/BackOffice -./build-deps.sh - -# 2. Build project -cd src -dotnet build BackOffice.sln -c Release - -# 3. Publish -dotnet publish BackOffice/BackOffice.csproj -c Release -o ./publish -``` - -### بررسی Output: -```bash -# تعداد proto assemblies در output -ls ./publish/wwwroot/_framework/*.wasm | grep "BackOffice.BFF" | wc -l -# Result: 24 ✅ -``` - ---- - -## 🔧 Troubleshooting - -### اگر Build شکست: - -1. **بررسی libs/ folder**: - ```bash - ls BackOffice/libs/*.dll | wc -l - # باید 24 باشد - ``` - -2. **Rebuild proto dependencies**: - ```bash - cd BackOffice - rm -rf libs/ - ./build-deps.sh - ``` - -3. **بررسی Package Versions**: - - `Google.Protobuf`: باید `3.28.3` باشد - - `Grpc.Core.Api`: باید `2.71.0` باشد - -### اگر Git Push شکست: - -```bash -# تست اتصال به remote جدید -git ls-remote https://git.se.kbs1.ir/admin/BackOffice.git -``` - ---- - -## 📝 نکات مهم - -1. **PublicMessage.Protobuf** تنها پروژه‌ای است که `net8.0` دارد -2. اسکریپت `build-deps.sh` خودکار هر دو framework را چک می‌کند -3. در Development Mode می‌توان از ProjectReference استفاده کرد (اگر libs/ وجود نداشته باشد) -4. همه آدرس‌های `*.foursat.afrino.co` به `*.se.kbs1.ir` تغییر کرد -5. همه Git remote ها بروز شدند - ---- - -## ✅ Status: COMPLETED - -**تاریخ تکمیل**: January 3, 2026 -**Build Status**: ✅ SUCCESS -**Publish Status**: ✅ SUCCESS -**Domain Migration**: ✅ COMPLETED -**Git Remotes**: ✅ UPDATED diff --git a/docs/STATUS.md b/docs/STATUS.md deleted file mode 100644 index be87fed..0000000 --- a/docs/STATUS.md +++ /dev/null @@ -1,135 +0,0 @@ -# BackOffice Project Status - -> آخرین بروزرسانی: **December 20, 2025** - ---- - -## 🎯 وضعیت کلی - -| Component | Build Status | Errors | -|-----------|--------------|--------| -| BackOffice UI | ✅ SUCCESS | 0 | -| BackOffice.BFF | ✅ SUCCESS | 0 | -| CMS Microservice | ✅ SUCCESS | 0 | - -**System Status**: 🟢 **PRODUCTION READY** - ---- - -## 📦 Proto Projects (24 پروژه فعال) - -### Core Protos: -- ✅ Common.Protobuf -- ✅ Health.Protobuf -- ✅ Configuration.Protobuf - -### User Management: -- ✅ User.Protobuf -- ✅ UserRole.Protobuf -- ✅ Role.Protobuf -- ✅ UserAddress.Protobuf -- ✅ UserWallet.Protobuf -- ✅ Otp.Protobuf - -### Products & Shop: -- ✅ Products.Protobuf -- ✅ Category.Protobuf -- ✅ Tag.Protobuf -- ✅ ProductTag.Protobuf -- ✅ Package.Protobuf - -### Discount Shop: -- ✅ DiscountProduct.Protobuf -- ✅ DiscountCategory.Protobuf -- ✅ DiscountOrder.Protobuf -- ✅ DiscountShoppingCart.Protobuf - -### Network & Commission: -- ✅ NetworkMembership.Protobuf -- ✅ ClubMembership.Protobuf -- ✅ Commission.Protobuf - -### Orders & Payments: -- ✅ UserOrder.Protobuf -- ✅ ManualPayment.Protobuf - -### Messaging: -- ✅ PublicMessage.Protobuf - ---- - -## 🗂️ ماژول‌های فعال - -### 1. Products Module ✅ -- صفحه اصلی محصولات با فیلتر و صفحه‌بندی -- ایجاد محصول جدید با آپلود تصویر -- ویرایش محصول -- گالری تصاویر محصول -- مدیریت تگ‌های محصول -- ویرایش گروهی (قیمت، موجودی، وضعیت) -- **ستون موجودی** با رنگ‌بندی هوشمند (🔴🟡🟢) -- DragDrop دسته‌بندی محصولات - -### 2. Discount Shop Module ✅ -- مدیریت محصولات تخفیفی -- مدیریت دسته‌بندی‌ها -- مدیریت سفارشات -- گزارش فروش - -### 3. Commission Module ✅ -- داشبورد استخر هفتگی -- لیست پرداخت‌ها -- لیست برداشت‌ها -- بالانس‌های هفتگی کاربران - -### 4. Network Module ✅ -- لیست اعضای شبکه -- نمای درختی شبکه -- آمار شبکه - -### 5. Club Module ✅ -- لیست اعضای باشگاه -- آمار باشگاه -- مدیریت ویژگی‌های باشگاه - -### 6. Tag Module ✅ -- مدیریت تگ‌ها (CRUD) -- اختصاص تگ به محصولات - -### 7. Public Messages Module ✅ -- مدیریت پیام‌های عمومی -- قالب‌های پیام - -### 8. Manual Payments Module ✅ -- ثبت پرداخت دستی -- تایید/رد پرداخت - -### 9. System Management ✅ -- تنظیمات سیستم -- لاگ تغییرات -- Health Check - -### 10. Dashboard ✅ -- ویجت آمار فروشگاه تخفیفی (7 روز اخیر) - ---- - -## 📊 آمار - -| Metric | Value | -|--------|-------| -| Build Errors | 0 | -| Proto Projects | 24 | -| Active Pages | 40+ | -| Active Components | 60+ | -| Excluded Files | 0 | -| Test Coverage | N/A | - ---- - -## 🔧 Environment - -- **Framework**: Blazor WebAssembly .NET 9.0 -- **UI Library**: MudBlazor 8.14.0 -- **gRPC**: Grpc.Net.Client 2.70.0 -- **Mapping**: Mapster 7.4.0+ diff --git a/docs/TECHNICAL-NOTES.md b/docs/TECHNICAL-NOTES.md deleted file mode 100644 index 83ac5f7..0000000 --- a/docs/TECHNICAL-NOTES.md +++ /dev/null @@ -1,230 +0,0 @@ -# BackOffice Technical Notes - -> نکات فنی برای توسعه‌دهندگان - ---- - -## 1. Mapster Mapping Patterns - -### 1.1 Proto Types (Immutable) -برای proto types که immutable هستند، باید از `MapWith` استفاده کرد: - -```csharp -config.NewConfig() - .MapWith(src => new ProtoResponse - { - Field1 = src.Field1, - Field2 = src.Field2 ?? string.Empty, - RepeatedField = { src.List?.Select(x => new Item { ... }) ?? Enumerable.Empty() } - }); -``` - -### 1.2 Null-Safe MetaData -```csharp -MetaData = src.MetaData != null ? new MetaData -{ - PageIndex = src.MetaData.PageIndex, - TotalPages = src.MetaData.TotalPages, - TotalCount = src.MetaData.TotalCount -} : null -``` - -### 1.3 Alias Imports برای Disambiguation -وقتی دو proto با نام یکسان داریم: - -```csharp -using BffProtos = BackOffice.BFF.ClubMembership.Protobuf.Protos.ClubMembership; -using CmsProtos = CMSMicroservice.Protobuf.Protos.ClubMembership; - -// استفاده: -config.NewConfig(); -``` - -### 1.4 PaginationState Mapping -```csharp -config.NewConfig() - .Map(dest => dest.PaginationState, src => src.PaginationState); -``` - ---- - -## 2. MudBlazor 8 Breaking Changes - -### 2.1 Dialog Instance -```csharp -// ❌ قبلی -[CascadingParameter] MudDialogInstance MudDialog { get; set; } - -// ✅ جدید -[CascadingParameter] IMudDialogInstance MudDialog { get; set; } -``` - -### 2.2 Generic Components -```razor - - -Text - - - -Text -``` - -### 2.3 Drag Events -```razor - -@ondragover="e => e.PreventDefault()" - - -@ondragover:preventDefault -``` - -### 2.4 File Upload -```csharp -// FilesChanged حالا IBrowserFile می‌گیرد - -``` - ---- - -## 3. gRPC Patterns - -### 3.1 Service Override in BFF -```csharp -public override async Task GetData(GetRequest request, ServerCallContext context) -{ - return await _dispatchRequestToCQRS.Handle(request, context); -} -``` - -### 3.2 CQRS Handler -```csharp -public class GetQueryHandler : IRequestHandler -{ - private readonly IApplicationContractContext _context; - - public async Task Handle(GetQuery request, CancellationToken ct) - { - var cmsRequest = request.Adapt(); - var response = await _context.Service.GetAsync(cmsRequest, cancellationToken: ct); - return response.Adapt(); - } -} -``` - ---- - -## 4. Proto Update Checklist - -هر تغییری در Proto نیاز به این مراحل دارد: - -### Step 1: Update Version -```xml - -0.0.1420.0.143 -``` - -### Step 2: Pack -```bash -cd path/to/proto/project -dotnet pack -c Release -# Push به GitLab Registry خودکار انجام می‌شود -``` - -### Step 3: Update References -```xml - -``` - -### Step 4: Build & Test -```bash -dotnet build -dotnet test -``` - ---- - -## 5. Common Fixes - -### 5.1 Snackbar Duplicate Injection -اگر در `_Imports.razor` inject شده، در component نیاز نیست: -```csharp -// ❌ حذف کن -[Inject] ISnackbar Snackbar { get; set; } -``` - -### 5.2 BasePageComponent Reload -```csharp -private MudDataGrid? _gridData; - -private async Task OnFilterSubmit() -{ - if (_gridData != null) - await _gridData.ReloadServerData(); -} -``` - -### 5.3 Nullable Wrapper Types -```csharp -// Proto nullable types: -// google.protobuf.Int64Value → long? -// google.protobuf.BoolValue → bool? - -// Set value: -request.UserId = userId; // نه new Int64Value { Value = userId } -``` - ---- - -## 6. Build Commands - -```bash -# Full Solution Build -cd /home/masoud/Apps/project/FourSat/BackOffice/src -dotnet build BackOffice.sln - -# Single Project -dotnet build BackOffice/BackOffice.csproj - -# With Restore -dotnet build --restore - -# Clean Build -dotnet clean && dotnet build - -# Check Errors Only -dotnet build 2>&1 | grep -E "error CS" -``` - ---- - -## 7. Project References - -### ProjectReference (Local Development): -```xml - -``` - -### PackageReference (Production): -```xml - -``` - ---- - -## 8. File Organization - -``` -BackOffice/ -├── docs/ -│ ├── README.md # Index -│ ├── STATUS.md # Current Status -│ ├── CHANGELOG.md # History -│ ├── TECHNICAL-NOTES.md # This file -│ └── SESSION-*.md # Session logs -├── src/ -│ └── BackOffice/ -│ ├── Pages/ # Blazor pages -│ ├── Services/ # gRPC clients -│ └── Common/ # Shared components -``` diff --git a/docs/development-plan.md b/docs/development-plan.md deleted file mode 100644 index 7dd7ee1..0000000 --- a/docs/development-plan.md +++ /dev/null @@ -1,1461 +0,0 @@ -# BackOffice Development Plan - Network & Commission System - -**Date**: 2025-12-01 -**Version**: 2.3 -**Status**: 🟢 **Production Ready - 100% Complete** -**Last Updated**: 2025-12-01 - ---- - -## 📊 **Implementation Status Legend** - -| Icon | Status | Description | -|------|--------|-------------| -| ✅ | **Complete** | CMS + BFF + Frontend پیاده‌سازی و تست شده | -| 🟡 | **Partial** | Frontend آماده، Backend نیاز به API | -| 🔴 | **Not Started** | هنوز پیاده‌سازی نشده | -| ⏳ | **In Progress** | در حال توسعه | - ---- - -## 🎯 **Overall Progress - 100% Complete** - -### **Backend Status**: -- ✅ **CMS Microservice**: Complete (Commission, Network, Club, Configuration services) -- ✅ **BFF Integration**: Complete (gRPC clients registered) -- ✅ **BFF CQRS Handlers**: **35 files implemented** (Commission: 15, Club: 6, Network: 9, Configuration: 3, Health: 2) -- ✅ **BFF Services**: **5 services auto-registered** (CommissionService, ClubMembershipService, NetworkMembershipService, ConfigurationService, HealthService) -- ✅ **BFF Protobuf Packages**: 5 packages (Commission, ClubMembership, NetworkMembership, Configuration, Health) -- ✅ **Architecture**: Proper 3-tier (Frontend → BFF → CMS) with NO direct CMS access - -### **Frontend Status**: -- ✅ **Blazor Pages**: **23 pages implemented** (Commission: 4, Network: 4, Club: 3, Dashboard: 1, Settings: 1, System: 4) -- ✅ **UI Components**: **8 dialogs/components created** -- ✅ **Direct gRPC Integration**: Using gRPC-Web with JWT interceptor -- ✅ **Build Status**: **0 compilation errors**, 0 runtime errors -- ✅ **Navigation**: Organized menu with Commission, Network, Club, System groups -- ✅ **System Management**: All 4 pages complete and connected to real APIs -- ✅ **User Settings**: Complete with LocalStorage persistence (General, Notifications, Security tabs) -- ✅ **API Integration**: **100% complete** - All pages production ready - ---- - -## 📋 **Feature Implementation Roadmap** - ---- - -## 1️⃣ **Commission Management** 💰 - -### **1.1 Commission Dashboard** -**Priority**: 🔥 High -**Status**: ✅ **Complete** - -#### Backend Availability: -- ✅ **CMS Service**: `CommissionContract.GetWeeklyCommissionPool` -- ✅ **BFF Client**: `IApplicationContractContext.Commissions` registered -- ✅ **BFF Handler**: `GetWeeklyPoolQuery` + `GetWeeklyPoolQueryHandler` + `GetWeeklyPoolResponseDto` -- ✅ **BFF Service**: `CommissionService.cs` with `GetWeeklyCommissionPoolAsync` - -#### Frontend Implementation: -- ✅ **Page**: `Pages/Commission/Dashboard.razor` (189 lines) -- ✅ **Code-behind**: `Dashboard.razor.cs` (66 lines) -- ✅ **Components**: - - 4 MudCard summary cards (TotalPoolAmount, TotalBalances, ValuePerBalance, IsCalculated) - - Week selector with ISO 8601 format (2025-W48) - - Pool details table with 8 data rows - - Quick action buttons (Payouts, Withdrawals, Manual calculation) - - Loading state with MudProgressCircular -- ✅ **gRPC Integration**: Direct call to `CommissionClient.GetWeeklyCommissionPoolAsync` - -#### Implementation Status: -``` -[✅] 1. Create GetWeeklyPoolQuery + Handler in BFF -[✅] 2. Add CommissionService with gRPC call -[✅] 3. Create Dashboard.razor page -[✅] 4. Add MudBlazor cards for pool display -[🔴] 5. Integrate Chart.js for trend visualization (using table instead) -[✅] 6. Direct gRPC integration (no HTTP layer needed) -``` - -#### Files Created: **6 files** - ---- - -### **1.2 Weekly Commission Reports** -**Priority**: 🟠 Medium -**Status**: ✅ **Complete** - -#### Backend Availability: -- ✅ **CMS Service**: `GetAllWeeklyPoolsQuery` implemented -- ✅ **BFF Handler**: `GetAllWeeklyPoolsQueryHandler` implemented -- ✅ **BFF Protobuf**: Added to `commission.proto` v0.0.2 - -#### Frontend Implementation: -- ✅ **Page**: `Pages/Commission/WeeklyReports.razor` (273 lines) -- ✅ **Features**: - - MudDataGrid with date range filter (FromWeek, ToWeek) - - Columns: WeekNumber, TotalPoolAmount, TotalBalances, ValuePerBalance, IsCalculated, CalculatedAt - - Status chips (محاسبه شده/در انتظار) - - 4 summary cards (مجموع استخرها، محاسبه شده، در انتظار، میانگین ارزش) - - Action buttons: View details, Navigate to payouts - - **Using Real API**: `CommissionClient.GetAllWeeklyPoolsAsync` -- ✅ **API Integration**: Fully integrated with BFF - -#### Implementation Status: -``` -[✅] 1. Add GetAllWeeklyPoolsQuery to CMS -[✅] 2. Create corresponding BFF handler -[✅] 3. Add BFF service method -[✅] 4. Build WeeklyReports.razor with MudTable -[✅] 5. Implement filtering logic -[✅] 6. Integrate with real BFF API -[🔴] 7. Add Excel export (EPPlus or ClosedXML) -``` - -#### Files Created: **7 files** (3 CMS + 3 BFF + 1 Frontend) - -#### Estimated Time: **3 days** - ---- - -### **1.3 User Payouts Management** -**Priority**: 🟠 Medium -**Status**: ✅ **Complete** - -#### Backend Availability: -- ✅ **CMS Service**: `CommissionContract.GetUserCommissionPayouts` -- ✅ **BFF Client**: Available -- ✅ **BFF Handler**: `GetUserPayoutsQuery` + `GetUserPayoutsQueryHandler` + `GetUserPayoutsResponseDto` -- ✅ **BFF Service**: `CommissionService.cs` with `GetUserCommissionPayoutsAsync` - -#### Frontend Implementation: -- ✅ **Page**: `Pages/Commission/UserPayouts.razor` (136 lines) -- ✅ **Code-behind**: `UserPayouts.razor.cs` (155 lines) -- ✅ **Dialog**: `Components/PayoutDetailsDialog.razor` (115 lines) -- ✅ **Features**: - - MudDataGrid with ServerReload pagination - - Filters: UserId (long), WeekNumber (string), Status (0=Pending, 1=Paid, 2=Failed) - - Columns: Id, User (with name), BalancesEarned, ValuePerBalance, TotalAmount, Status chip, Created - - Action buttons: View details, Process withdrawal (for pending only) - - PayoutDetailsDialog shows: User info, Payout details, Withdrawal info (Method: Cash/Diamond, IBAN), Timestamps - -#### Implementation Status: -``` -[✅] 1. Create GetUserPayoutsQuery + Handler in BFF -[✅] 2. Add BFF service method -[✅] 3. Build UserPayouts.razor page with ServerReload -[✅] 4. Add filtering UI (UserId, WeekNumber, Status) -[✅] 5. Create PayoutDetailsDialog component -[🔴] 6. Add Excel export functionality -``` - -#### Files Created: **5 files** (3 CQRS + 2 Frontend) - ---- - -### **1.4 Withdrawal Requests** -**Priority**: 🔥 High -**Status**: ✅ **Complete** - -#### Backend Availability: -- ✅ **CMS Service**: Complete - - ✅ `RequestWithdrawal` (Command exists) - - ✅ `GetWithdrawalRequests` (Query implemented) - - ✅ `ApproveWithdrawal` (Command implemented) - - ✅ `RejectWithdrawal` (Command implemented) -- ✅ **BFF Client**: Available -- ✅ **BFF Handler**: All 3 handlers implemented (GetWithdrawalRequests, Approve, Reject) -- ✅ **BFF Service Methods**: Fully implemented - -#### Frontend Implementation: -- ✅ **Page**: `Pages/Commission/WithdrawalRequests.razor` (136 lines) -- ✅ **Code-behind**: `WithdrawalRequests.razor.cs` (155 lines) -- ✅ **Features**: - - MudDataGrid with ServerReload pagination - - Status filter: 0=Pending, 1=Approved, 2=Rejected, 3=Processed - - Columns: Id, User (name+id), Amount, Method (Cash/Diamond chip), Status chip, RequestedAt - - Action buttons per status: - * Pending: View + Approve + Reject - * Approved: View + Process - * Other: View only - - Status color coding: Warning/Success/Error/Info - - Confirmation dialogs for all actions - - **Ready for API integration** - -#### Implementation Status: -``` -[✅] 1. Add GetWithdrawalRequestsQuery to CMS -[✅] 2. Create BFF handlers (Get, Approve, Reject) -[✅] 3. Add BFF service methods -[✅] 4. Build WithdrawalRequests.razor with action buttons -[✅] 5. Add approval/rejection confirmation dialogs -[✅] 6. Implement UI for all withdrawal states -[✅] 7. CMS + BFF Build successful (0 errors) -``` - -#### Files Created: **11 files** (6 CMS + 3 BFF + 2 Frontend) - ---- - -### **1.5 Manual Worker Execution** -**Priority**: 🟠 Medium -**Status**: ✅ **Complete - Using Real API** - -#### Backend Availability: -- ✅ **CMS Service**: Fully implemented - - ✅ `GetExecutionLogs` (Query with pagination and filtering) -- ✅ **BFF Client**: Available -- ✅ **BFF Handler**: GetExecutionLogs handler implemented -- ✅ **Worker Control APIs**: Complete - -#### Frontend Implementation: -- ✅ **Page**: `Pages/SystemManagement/WorkerControl.razor` (265 lines) -- ✅ **Features**: - - **Using Real API**: Connected to `CommissionClient.GetExecutionLogsAsync` - - Execution log table with ServerReload pagination - - Columns: ExecutedAt, WorkerName, Status (Success/Failed), Duration, Message, CreatedBy - - Status color coding: Success (Green), Failed (Red) - - Filter by WorkerType enum (0=WeeklyCalculation, 1=DailyReport, 2=Other) - - PageSize options: 10, 25, 50 - - Action buttons for future: Trigger, Pause, Resume (requires additional CMS APIs) -- ✅ **API Integration**: Fully integrated with BFF - -#### Implementation Status: -``` -[✅] 1. Create GetExecutionLogsQuery + Handler in BFF -[✅] 2. Add BFF service method -[✅] 3. Build WorkerControl.razor with ServerReload -[✅] 4. Add filtering UI (WorkerType enum) -[✅] 5. Implement pagination -[✅] 6. Show execution log with status indicators -[✅] 7. Connect to real API (GetExecutionLogsAsync) -[🔴] 8. Add Trigger/Pause/Resume buttons (requires additional CMS endpoints) -``` - -#### Files Created: **4 files** (3 BFF CQRS + 1 Frontend) - ---- - -## 2️⃣ **Network Management** 🌳 - -### **2.1 Network Tree Visualization** -**Priority**: 🟠 Medium -**Status**: ✅ **Complete** (Table-based implementation) - -#### Backend Availability: -- ✅ **CMS Service**: `NetworkMembershipContract.GetNetworkTree` -- ✅ **BFF Client**: Available -- ✅ **BFF Handler**: `GetNetworkTreeQuery` + `GetNetworkTreeQueryHandler` + `GetNetworkTreeResponseDto` -- ✅ **BFF Service**: `NetworkMembershipService.cs` with `GetNetworkTreeAsync` - -#### Frontend Implementation: -- ✅ **Page**: `Pages/Network/NetworkTreeViewer.razor` (157 lines) -- ✅ **Features**: - - Search by RootUserId (MudNumericField) - - Stats chips: Total members, Left count, Right count - - MudDataGrid displaying flat node list (GetNetworkTreeResponse.Nodes) - - Columns: UserId, UserName, NetworkLeg (چپ/راست with color), NetworkLevel, IsActive, JoinedAt - - CalculateStats() using LINQ to count by NetworkLeg - - Navigate to UserNetworkInfo on row click - - **Note**: Using table-based display instead of D3.js tree (based on actual Protobuf structure) - -#### Implementation Status: -``` -[✅] 1. Create GetNetworkTreeQuery + Handler in BFF -[✅] 2. Add BFF service method -[✅] 3. Build TreeViewer.razor with MudDataGrid -[🔴] 4. Integrate D3.js for hierarchical tree (optional enhancement) -[✅] 5. Implement flat list rendering based on Protobuf -[✅] 6. Add stats calculation -[✅] 7. Add navigation to user details -[✅] 8. Add user search functionality -``` - -#### Files Created: **4 files** (3 CQRS + 1 Frontend) - -#### Estimated Time: **5 days** (complex visualization) - ---- - -### **2.2 User Network Info** -**Priority**: 🟠 Medium -**Status**: ⚠️ **95% Complete - Has 2 Bugs** - -#### Backend Availability: -- ✅ **CMS Service**: `NetworkMembershipContract.GetUserNetwork` -- ✅ **BFF Client**: Available -- ✅ **BFF Handler**: `GetUserNetworkInfoQuery` + `GetUserNetworkInfoQueryHandler` + `GetUserNetworkInfoResponseDto` -- ✅ **BFF Service**: `NetworkMembershipService.cs` with `GetUserNetworkAsync` - -#### Frontend Implementation: -- ✅ **Page**: `Pages/Network/UserNetworkInfo.razor` (220+ lines) -- ✅ **Features**: - - Route parameter: `/network/user-info/{UserId:long}` - - Breadcrumbs: Network → User - - User info card: UserId, UserName, NetworkLeg (چپ/راست), NetworkLevel, JoinedAt - - Network structure card: Parent button, LeftChild button, RightChild button with navigation - - NavigationManager integration for parent/children navigation - - LoadUserInfo() calls GetUserNetworkAsync - - **Note**: Removed non-existent properties (IsActive, TotalLeftMembers, TotalRightMembers) -- ⚠️ **Known Issues**: - - Line 87: Int64Value display error with LeftChildId - - Line 105: Int64Value display error with RightChildId - - Root cause: Confusion between `google.protobuf.Int64Value` vs `long?` - -#### Implementation Status: -``` -[✅] 1. Create GetUserNetworkInfoQuery + Handler in BFF -[✅] 2. Add BFF service method -[✅] 3. Build UserNetworkInfo.razor with route parameter -[✅] 4. Add NavigationManager for parent/children navigation -[✅] 5. Display network position details -[⚠️] 6. Fix Int64Value property access (2 bugs remaining) -[🔴] 7. Add mini tree visualization (currently card-based) -``` - -#### Files Created: **4 files** (3 CQRS + 1 Frontend) - ---- - -### **2.3 Network Statistics** -**Priority**: 🟢 Low -**Status**: ✅ **Complete - Using Real API** - -#### Backend Availability: -- ✅ **CMS Service**: `GetNetworkStatistics` implemented -- ✅ **BFF Client**: Available -- ✅ **BFF Handler**: GetNetworkStatisticsQuery + Handler + ResponseDto -- ✅ **BFF Service Method**: NetworkMembershipService with GetNetworkStatisticsAsync - -#### Frontend Implementation: -- ✅ **Page**: `Pages/Network/Statistics.razor` (243 lines) -- ✅ **Features**: - - **Using Real API**: Connected to `NetworkClient.GetNetworkStatisticsAsync` - - 4 summary cards: Total members, Left branch, Right branch, Active members - - MudChart Donut: Left/Right distribution (using real TotalLeftBranch/TotalRightBranch) - - MudChart Line: Growth trend (mock data - requires historical API) - - MudChart Bar: Network depth distribution (mock data - requires level breakdown) - - Top 10 users table (mock data - requires leaderboard API) - - Navigate to UserNetworkInfo on view button - - Error handling with Snackbar notifications - -#### Implementation Status: -``` -[✅] 1. Create GetNetworkStatisticsQuery + Handler in BFF -[✅] 2. Add BFF service method -[✅] 3. Build Statistics.razor with MudCharts -[✅] 4. Connect to real API (GetNetworkStatisticsAsync) -[✅] 5. Add chart visualizations (Donut with real data) -[✅] 6. Implement summary cards with real statistics -[🟡] 7. Historical trend chart (requires additional API) -[🟡] 8. Top users leaderboard (requires additional API) -``` - -#### Files Created: **4 files** (3 BFF CQRS + 1 Frontend) - ---- - -### **2.4 Network Balances Report** -**Priority**: 🟠 Medium -**Status**: ✅ **Complete - Using Real API** - -#### Backend Availability: -- ✅ **CMS Service**: `CommissionContract.GetUserWeeklyBalances` -- ✅ **BFF Client**: Available -- ✅ **BFF Handler**: GetUserWeeklyBalancesQuery + Handler + ResponseDto -- ✅ **BFF Service Method**: CommissionService with GetUserWeeklyBalancesAsync - -#### Frontend Implementation: -- ✅ **Page**: `Pages/Network/BalancesReport.razor` (240 lines) -- ✅ **Features**: - - **Using Real API**: Connected to `CommissionClient.GetUserWeeklyBalancesAsync` - - Filters: UserId (long?), WeekNumber (string), OnlyActive (bool) - - MudDataGrid with ServerReload pagination - - Columns: UserId, UserName, WeekNumber, LeftBalance (green), RightBalance (yellow), MatchedBalance (blue), PoolContribution, IsExpired - - 3 summary cards: Total Left, Total Right, Total Matched (using long for large sums) - - Explicit type casting for TotalItems: `(int)(response.MetaData?.TotalCount ?? 0)` - - CalculateTotals with long aggregation: `items.Sum(b => (long)b.LeftBalance)` - - Excel export button (TODO: implementation pending) - - Error handling with fallback to empty list - -#### Implementation Status: -``` -[✅] 1. Create GetUserWeeklyBalancesQuery + Handler in BFF -[✅] 2. Add BFF service method -[✅] 3. Build BalancesReport.razor with ServerReload -[✅] 4. Connect to real API (GetUserWeeklyBalancesAsync) -[✅] 5. Add filtering UI (UserId, WeekNumber, OnlyActive) -[✅] 6. Implement pagination and totals calculation with long type -[✅] 7. Fixed type conversion errors (int to long) -[🔴] 8. Add Excel export (EPPlus or ClosedXML) -``` - -#### Files Created: **4 files** (3 BFF CQRS + 1 Frontend) -- 🔴 **Page**: `Pages/Network/BalancesReport.razor` -- 🔴 **Components**: - - MudTable with user balances - - Week selector - - Filter by balance range - - Export to Excel - -#### Implementation Steps: -``` -[ ] 1. Create GetWeeklyBalancesQuery + Handler in BFF -[ ] 2. Add API endpoint -[ ] 3. Build BalancesReport.razor -[ ] 4. Add filtering UI -[ ] 5. Implement Excel export -``` - -#### Estimated Time: **2 days** - ---- - -## 3️⃣ **Club Membership Management** 🎖️ - -### **3.1 Club Members List** -**Priority**: 🟠 Medium -**Status**: ✅ **Complete** - -#### Backend Availability: -- ✅ **CMS Service**: `ClubMembershipContract.GetAllClubMemberships` -- ✅ **BFF Client**: Available -- ✅ **BFF Handler**: `GetAllClubMembersQuery` + `GetAllClubMembersQueryHandler` + `GetAllClubMembersResponseDto` -- ✅ **BFF Service**: `ClubMembershipService.cs` with `GetAllClubMembershipsAsync` - -#### Frontend Implementation: -- ✅ **Page**: `Pages/Club/ClubMembers.razor` (112 lines) -- ✅ **Code-behind**: `ClubMembers.razor.cs` (110 lines) -- ✅ **Features**: - - MudDataGrid with ServerReload pagination - - Filter by IsActive (bool toggle switch) - - Columns: Id, User (name+id), PackageName chip, ActivationCode, ActivatedAt, ExpiresAt (colored based on expiry), IsActive chip - - Action buttons: View details (MemberDetailsDialog), Deactivate (if active) - - New member button opens ActivateClubDialog - - Fixed: request.IsActive = _filterIsActive.Value (direct assignment, not BoolValue) - -#### Implementation Status: -``` -[✅] 1. Create GetAllClubMembersQuery + Handler in BFF -[✅] 2. Add BFF service method -[✅] 3. Build ClubMembers.razor with ServerReload -[✅] 4. Add filtering UI (IsActive toggle) -[✅] 5. Implement pagination -[✅] 6. Add action buttons (View, Deactivate, New Member) -``` - -#### Files Created: **8 files** (3 CQRS + 5 Frontend components) - ---- - -### **3.2 Club Activation** -**Priority**: 🔥 High -**Status**: ✅ **Complete** - -#### Backend Availability: -- ✅ **CMS Service**: `ClubMembershipContract.ActivateClubMembership` -- ✅ **BFF Client**: Available -- ✅ **BFF Handler**: `ActivateClubCommand` + `ActivateClubCommandHandler` + `ActivateClubResponseDto` -- ✅ **BFF Service**: `ClubMembershipService.cs` with `ActivateClubMembershipAsync` - -#### Frontend Implementation: -- ✅ **Dialog**: `Pages/Club/Components/ActivateClubDialog.razor` (86 lines) -- ✅ **Features**: - - MudForm with validation - - Fields: UserId (long, required), PackageId (long, required), DurationMonths (int, min=1, max=12, required) - - Direct gRPC call to ClubContract.ActivateClubMembershipAsync - - Returns google.protobuf.Empty (fixed: removed IsSuccess/ActivationCode check) - - Success/error notifications with Snackbar - - IMudDialogInstance for closing - - Validation: All fields required, DurationMonths range check - -#### Implementation Status: -``` -[✅] 1. Create ActivateClubCommand + Handler in BFF -[✅] 2. Add BFF service method -[✅] 3. Build ActivateClubDialog with form -[✅] 4. Add input fields with validation -[✅] 5. Implement form validation (Required, Range) -[✅] 6. Add confirmation and success notifications -[✅] 7. Fix Empty response handling (no IsSuccess check) -``` - -#### Files Created: **4 files** (3 CQRS + 1 Dialog) - ---- - -### **3.3 Club Deactivation** -**Priority**: 🟠 Medium -**Status**: ✅ **Complete** - -#### Backend Availability: -- ✅ **CMS Service**: `ClubMembershipContract.DeactivateClubMembership` -- ✅ **BFF Client**: Available -- ✅ **BFF Handler**: (Uses direct gRPC call from frontend) -- ✅ **Direct Integration**: Frontend calls ClubContract directly - -#### Frontend Implementation: -- ✅ **Dialog**: `Pages/Club/Components/DeactivateClubDialog.razor` (79 lines) -- ✅ **Features**: - - Warning MudAlert with consequences - - MudList with 4 consequences (fixed: added T="string") - - Reason field (MudTextField, optional) - - Direct call to ClubContract.DeactivateClubMembershipAsync - - Returns google.protobuf.Empty (fixed: removed IsSuccess/Message check) - - Success/error notifications - - Refresh parent list after deactivation - -#### Implementation Status: -``` -[✅] 1. Direct gRPC integration (no BFF handler needed) -[✅] 2. Use existing CMS endpoint -[✅] 3. Build DeactivateMembershipDialog with warnings -[✅] 4. Integrated into ClubMembers.razor -[✅] 5. Implement optional reason field -[✅] 6. Fix Empty response handling -``` - -#### Files Created: **1 file** (Dialog only) - ---- - -### **3.4 Club Status Check** -**Priority**: 🟢 Low -**Status**: 🟡 **Partial - Dialog Created, Badge Component Pending** - -#### Backend Availability: -- ✅ **CMS Service**: `ClubMembershipContract.GetClubMembershipStatus` -- ✅ **BFF Client**: Available -- 🔴 **BFF Handler**: Not implemented (can use direct gRPC) -- 🔴 **Frontend Badge**: Not created - -#### Frontend Implementation: -- ✅ **Dialog**: `Pages/Club/Components/MemberDetailsDialog.razor` (105 lines) -- ✅ **Features**: - - User info: UserId, UserName - - Membership info: Id, PackageName, ActivationCode, ActivatedAt, ExpiresAt, IsActive chip, IsExpired - - Timestamps: Created only (removed LastModified - doesn't exist in model) - - IMudDialogInstance for closing -- 🔴 **Component**: `Components/Club/ClubStatusBadge.razor` - Not created yet -- 🔴 **Usage**: Not integrated into user profile pages - -#### Implementation Status: -``` -[✅] 1. Direct gRPC integration available -[✅] 2. CMS endpoint exists -[✅] 3. Build MemberDetailsDialog (shows status) -[🔴] 4. Create ClubStatusBadge component for reuse -[🔴] 5. Integrate badge into user profile pages -``` - -#### Files Created: **1 file** (Dialog only) - ---- - -### **3.5 Club Statistics** -**Priority**: 🟢 Low -**Status**: ✅ **Complete - Using Real API** - -#### Backend Availability: -- ✅ **CMS Service**: `GetClubStatistics` implemented -- ✅ **BFF Client**: Available -- ✅ **BFF Handler**: GetClubStatisticsQuery + Handler + ResponseDto -- ✅ **BFF Service Method**: ClubMembershipService with GetClubStatisticsAsync - -#### Frontend Implementation: -- ✅ **Page**: `Pages/Club/Statistics.razor` (246 lines) -- ✅ **Features**: - - **Using Real API**: Connected to `ClubClient.GetClubStatisticsAsync` - - 4 summary cards: Total members, Active, Inactive, Expired (using real counts) - - MudChart Donut: Active/Inactive distribution (using real TotalActive/TotalInactive) - - MudChart Line: Membership trend (mock data - requires historical API) - - MudChart Bar: Package distribution (mock data - requires package breakdown) - - Recent memberships table (mock data - requires recent members API) - - Navigate to ClubMembers on view button - - Error handling with Snackbar notifications - -#### Implementation Status: -``` -[✅] 1. Create GetClubStatisticsQuery + Handler in BFF -[✅] 2. Add BFF service method -[✅] 3. Build Statistics.razor with MudCharts -[✅] 4. Connect to real API (GetClubStatisticsAsync) -[✅] 5. Add summary cards with real statistics -[✅] 6. Add Donut chart with real data -[🟡] 7. Historical trend chart (requires additional API) -[🟡] 8. Recent memberships table (requires additional API) -``` - -#### Files Created: **4 files** (3 BFF CQRS + 1 Frontend) -**Priority**: 🟢 Low -**Status**: 🔴 Not Ready - -#### Backend Availability: -- 🔴 **CMS Service**: Not implemented (needs aggregation query) -- 🔴 **BFF Client**: Available once CMS implements -- 🔴 **BFF Handler**: Not implemented -- 🔴 **BFF Controller**: Not implemented - -#### Frontend Requirements: -- 🔴 **Page**: `Pages/Club/Statistics.razor` -- 🔴 **Components**: - - Active/Inactive counts - - Membership trend chart - - Total contributions - - Average membership duration - -#### Implementation Steps: -``` -[ ] 1. Add GetClubStatisticsQuery to CMS -[ ] 2. Create BFF handler -[ ] 3. Add API endpoint -[ ] 4. Build Statistics.razor -[ ] 5. Add charts and metrics -``` - -#### Estimated Time: **2 days** - ---- - -## 4️⃣ **System Monitoring & Control** ⚙️ - -### **4.1 Worker Control Panel** -**Priority**: 🔥 High -**Status**: 🟡 **Partial - Frontend Ready, Backend Pending** - -#### Backend Availability: -- 🔴 **CMS Service**: No direct worker control API -- 🔴 **BFF Handler**: Needs 5 handlers (TriggerCalculation, Pause, Resume, Restart, GetStatus, GetLog) -- 🔴 **Worker Control APIs**: Not implemented - -#### Frontend Implementation: -- ✅ **Page**: `Pages/SystemManagement/WorkerControl.razor` (265 lines) -- ✅ **Features**: - - Worker status card: Last run, Next run, Status chip, Successful runs, Failed runs - - Control panel: Manual week number input for calculation trigger - - Action buttons: Run manual calculation, Pause/Resume Worker, Restart Worker - - Execution log table: Last 20 runs with time, week, status, duration, message - - Confirmation dialogs for all operations - - MudOverlay with progress indicator during operations - - **Currently using Mock Data** (WorkerStatus enum, ExecutionLogModel) - - **Note**: Folder renamed from `/Pages/System` to `/Pages/SystemManagement` to avoid namespace conflict with `System.Net` - -#### Implementation Status: -``` -[🔴] 1. Add Worker control endpoints to CMS (TriggerCalculation, Pause, Resume, Restart) -[🔴] 2. Create BFF handlers (5 handlers needed) -[🔴] 3. Add BFF service methods -[✅] 4. Build WorkerControl.razor with status card -[✅] 5. Add control buttons with confirmation dialogs -[✅] 6. Implement execution log viewer with mock data -``` - -#### Files Created: **1 file** (Frontend only) - ---- - -### **4.2 Alerts & Notifications** -**Priority**: 🟠 Medium -**Status**: 🟡 **Complete UI - Requires AlertLog Table in CMS** - -#### Backend Availability: -- 🔴 **CMS Service**: No AlertLog table (requires schema design) -- 🔴 **BFF Handler**: Not needed until CMS implements AlertLog -- 🔴 **Alerts APIs**: Not implemented (requires AlertLog CRUD in CMS) - -#### Frontend Implementation: -- ✅ **Page**: `Pages/SystemManagement/AlertsMonitoring.razor` (410 lines) -- ✅ **Features**: - - Summary cards: Total alerts, Critical, Warning, Resolved today - - Advanced filters: Severity (Critical/Warning/Info), Status (Active/Acknowledged/Resolved), Source (Commission/Network/Club/System) - - Alerts table: Severity chip, Title, Source, Description, Created time, Status, Actions - - Action buttons: View details, Acknowledge, Resolve - - Confirmation dialogs for all alert operations - - Statistics calculation from filtered alerts - - **Currently using Mock Data** (25 mock alerts with various severities and statuses) - - **Production Ready UI** - Only needs Backend implementation - - Pagination support (10/25/50/100 per page) - -#### Implementation Status: -``` -[🔴] 1. Add AlertLog schema to CMS database (Id, Severity, Title, Description, Source, Status, CreatedAt, AcknowledgedAt, ResolvedAt) -[🔴] 2. Create CMS alert queries (GetAlerts, AcknowledgeAlert, ResolveAlert) -[🔴] 3. Create BFF handlers -[✅] 4. Build AlertsMonitoring.razor with complete UI -[✅] 5. Add summary cards and statistics -[✅] 6. Implement alerts table with all actions -[✅] 7. Add filtering and pagination -[✅] 8. Clean up TODO comments - added clear Backend requirement notes -``` - -#### Implementation Notes: -- ✅ **UI Complete**: 410 lines with full functionality (filters, actions, statistics) -- ✅ **Mock Data**: GenerateMockAlerts() creates 25 sample alerts for demonstration -- 🔴 **Backend Required**: Needs AlertLog table in CMS microservice -- 🔴 **Future APIs**: AlertClient.GetAllAlertsAsync(), AcknowledgeAlertAsync(), ResolveAlertAsync() -- ✅ **Production Ready UI**: Can be deployed immediately when Backend is implemented - -#### Files Created: **1 file** (Frontend only - Ready for Backend) - ---- - -### **4.3 System Health Dashboard** -**Priority**: 🟠 Medium -**Status**: ✅ **Complete - Using Real Health API** - -#### Backend Availability: -- ✅ **BFF Service**: Health check API implemented -- ✅ **BFF Handler**: GetSystemHealthQuery + Handler -- ✅ **BFF Proto**: health.proto created with GetSystemHealth RPC -- ✅ **Health Service**: HealthService.cs checks 4 services (CMS Commission, Configuration, Network, Club) - -#### Frontend Implementation: -- ✅ **Page**: `Pages/SystemManagement/HealthDashboard.razor` (450+ lines) -- ✅ **Features**: - - **Using Real API**: Connected to `HealthClient.GetSystemHealthAsync` - - Overall system status card (Healthy/Unhealthy based on all services) - - Services health cards showing: - * CMS Commission Service (with response time) - * CMS Configuration Service (with response time) - * Network Membership Service (with response time) - * Club Membership Service (with response time) - - Status indicators: Healthy (Green), Unhealthy (Red) - - Last updated timestamp - - **Partial Mock Data**: CPU, Memory, Disk, Network metrics (requires System Monitoring API) - - **Mock Events**: Recent system events (requires Event Log API) - - Control buttons: Check health (refreshes all services), View logs (future enhancement) - -#### Implementation Status: -``` -[✅] 1. Create health.proto in BFF (GetSystemHealth RPC) -[✅] 2. Create GetSystemHealthQuery + Handler in BFF -[✅] 3. Add HealthService to BFF with 4 service checks -[✅] 4. Connect HealthDashboard.razor to real API -[✅] 5. Display real service health status with response times -[✅] 6. Build status cards and overall health indicator -[🟡] 7. System resources monitoring (requires additional API) -### **4.4 System Configuration** -**Priority**: 🟠 Medium -**Status**: ✅ **Complete - Using Real Configuration API** - -#### Backend Availability: -- ✅ **CMS Service**: Configuration management fully implemented -- ✅ **BFF Handler**: 3 handlers (GetAllConfigurations, CreateOrUpdateConfiguration, DeactivateConfiguration) -- ✅ **BFF Proto**: configuration.proto with 5 RPCs -- ✅ **Configuration APIs**: Complete CRUD operations - -#### Frontend Implementation: -- ✅ **Page**: `Pages/SystemManagement/Configuration.razor` (620+ lines) -- ✅ **Features**: - - **Using Real API**: Connected to `ConfigurationClient.GetAllConfigurationsAsync` - - 4 tabs: Commission, Network, Club, System settings - - **LoadConfigurations()**: Loads 100 configs, maps to dictionary, parses with type helpers - - **Commission Tab** (8 settings): MinPayoutAmount, WeeklyPoolPercentage, MaxWithdrawalPerWeek, etc. - - **Network Tab** (7 settings): MaxNetworkDepth, BinaryTreeEnabled, AutoPlacementEnabled, etc. - - **Club Tab** (7 settings): MonthlyFee, GracePeriodDays, DefaultMembershipDurationMonths, etc. - - **System Tab** (9 settings): Name, SupportEmail, SessionTimeoutMinutes, MaintenanceMode, 2FA, etc. - - **SaveConfig() helper**: Calls CreateOrUpdateConfigurationAsync with key-value pairs - - **5 Get*Config helpers**: Type-safe parsing (string, int, decimal, double, bool) with defaults - - Save/Reset buttons for each tab - - Snackbar notifications for success/errors - -#### Implementation Status: -``` -[✅] 1. Create GetAllConfigurationsQuery + Handler in BFF -[✅] 2. Create CreateOrUpdateConfigurationCommand + Handler in BFF -[✅] 3. Create DeactivateConfigurationCommand + Handler in BFF -[✅] 4. Add ConfigurationService to BFF -[✅] 5. Connect Configuration.razor to real API -[✅] 6. Build 4 tabs with 31 configuration settings -[✅] 7. Implement LoadConfigurations with type-safe parsing -[✅] 8. Implement Save methods for all 4 tabs -[🔴] 9. Implement change history tracking (requires History API) -``` - -#### Files Created: **8 files** (1 Proto + 6 BFF CQRS + 1 Frontend) - ---- - -## 5️⃣ **User Settings & Preferences** ⚙️ - -### **5.1 User Settings Page** -**Priority**: 🟠 Medium -**Status**: ✅ **Complete - Using LocalStorage** - -#### Backend Availability: -- 🟡 **Identity API**: Not implemented (requires separate Authentication service) -- ✅ **LocalStorage**: Used for client-side persistence - -#### Frontend Implementation: -- ✅ **Page**: `Pages/Settings/UserSettings.razor` (420+ lines) -- ✅ **Features**: - - **4 Tabs**: General, Notifications, Security, About - - **General Settings** (4 settings): Language (fa/en), Dark Mode, Compact Mode, Page Size (10-100) - - **Notification Settings** (7 settings): Email, SMS, System notifications + 4 event types - - **Security Settings** (2 features): Change Password (validation only), Two-Factor Authentication toggle - - **About Tab**: Version info, build date, support contact - - **LoadSettings()**: Loads all settings from localStorage with type-safe parsing - - **SaveGeneralSettings()**: Saves UI preferences to localStorage - - **SaveNotificationSettings()**: Saves notification preferences to localStorage - - **SaveSecuritySettings()**: Saves 2FA preference to localStorage - - **ChangePassword()**: Full validation (requires Identity API for actual change) - - **LocalStorage Helpers**: GetLocalStorage() and SetLocalStorage() with type conversion - - Snackbar notifications for all save actions - - Form validation for password (min 8 chars, match confirmation) - -#### Implementation Status: -``` -[✅] 1. Create UserSettings.razor with 4 tabs -[✅] 2. Add IJSRuntime for localStorage access -[✅] 3. Implement LoadSettings with type-safe parsing -[✅] 4. Implement SaveGeneralSettings -[✅] 5. Implement SaveNotificationSettings -[✅] 6. Implement SaveSecuritySettings -[✅] 7. Add ChangePassword with validation -[✅] 8. Create GetLocalStorage helper -[✅] 9. Create SetLocalStorage helper -[🔴] 10. Connect to Identity API (future - requires Auth service) -``` - -#### Files Created: **1 file** (Frontend with LocalStorage) - ---- - -### **5.2 Migration Tools** -**Priority**: 🟢 Low -**Status**: 🔴 **Not Started** - -#### Backend Availability: -- ✅ **CMS Service**: `MigrateNetworkParentIdCommand` exists -- ✅ **BFF Client**: Can be exposed -- 🔴 **BFF Handler**: Not implemented - -#### Frontend Requirements: -- 🔴 **Page**: `Pages/SystemManagement/MigrationTools.razor` - Not created -- 🔴 **Components**: Not created - -#### Implementation Steps: -``` -[🔴] 1. Create RunMigrationCommand + Handler in BFF -[🔴] 2. Add API endpoint (with admin authorization) -[🔴] 3. Build MigrationTools.razor -[🔴] 4. Add confirmation dialog -[🔴] 5. Show progress and results -``` - -#### Files Created: **0 files** - ---- - -## 📊 **Implementation Priority Matrix - UPDATED** - -### **Phase 1: Critical Features** (Week 1-2) - **70% Complete** -**Must Have - Essential for operations** - -| Feature | Status | CMS | BFF | Frontend | Progress | -|---------|--------|-----|-----|----------|----------| -| Commission Dashboard | ✅ **Complete** | ✅ | ✅ | ✅ | **100%** | -| Withdrawal Requests | 🟡 **Partial** | 🟡 | 🔴 | ✅ | **50%** | -| Club Activation | ✅ **Complete** | ✅ | ✅ | ✅ | **100%** | -| Worker Control Panel | 🟡 **Partial** | 🔴 | 🔴 | ✅ | **35%** | - -**Phase 1 Progress**: **7 of 10 days complete (70%)** - ---- - -### **Phase 2: Important Features** (Week 3-4) - **73% Complete** -**Should Have - High value** - -| Feature | Status | CMS | BFF | Frontend | Progress | -|---------|--------|-----|-----|----------|----------| -| User Payouts Management | ✅ **Complete** | ✅ | ✅ | ✅ | **100%** | -| Network Tree Visualization | ✅ **Complete** | ✅ | ✅ | ✅ | **100%** | -| User Network Info | ⚠️ **95% Complete** | ✅ | ✅ | ⚠️ | **95%** (2 bugs) | -| Club Members List | ✅ **Complete** | ✅ | ✅ | ✅ | **100%** | -| Network Balances Report | ✅ **Complete** | ✅ | ✅ | ✅ | **100%** | - -**Phase 2 Progress**: **9.95 of 13.5 days complete (73%)** - ---- - -### **Phase 3: Nice to Have** (Week 5-6) - **50% Complete** -**Could Have - Enhancement features** - -| Feature | Status | CMS | BFF | Frontend | Progress | -|---------|--------|-----|-----|----------|----------| -| Weekly Commission Reports | ✅ **Complete** | ✅ | ✅ | ✅ | **100%** | -| Network Statistics | 🟡 **Partial** | 🔴 | 🔴 | ✅ | **33%** | -| Club Statistics | 🟡 **Partial** | 🔴 | 🔴 | ✅ | **33%** | -| Alerts Monitoring | 🟡 **Partial** | 🔴 | 🔴 | ✅ | **33%** | -| System Health Dashboard | 🟡 **Partial** | 🔴 | 🔴 | ✅ | **33%** | -| System Configuration | 🟡 **Partial** | 🔴 | 🔴 | ✅ | **33%** | - -**Phase 3 Progress**: **3 of 15 days complete (20%)** - ---- - -### **Phase 4: Future Enhancements** (Week 7+) - **33% Complete** -**Won't Have (this iteration) - Future scope** - -| Feature | Status | CMS | BFF | Frontend | Progress | -|---------|--------|-----|-----|----------|----------| -| Club Deactivation | ✅ **Complete** | ✅ | ✅ | ✅ | **100%** | -| Club Status Check | 🟡 **Partial** | ✅ | 🔴 | 🟡 | **50%** | -| Migration Tools UI | 🔴 **Not Started** | ✅ | 🔴 | 🔴 | **25%** | -### **Summary Statistics:** -- **Total Estimated Days**: 43.5 days -- **Days Completed**: **43 days (99%)** -- **Backend (BFF)**: **42 files created, 5 services operational, 5 Protobuf packages** -- **Frontend**: **23 pages, 8 dialogs/components created** -- **Build Status**: ✅ **0 compilation errors, 0 runtime errors** -- **API Integration**: ✅ **99% complete** - All pages connected to real APIs -- **Architecture**: ✅ Proper 3-tier with NO direct CMS access - -### **Progress by Module:** - -| Module | Progress | Status | -|--------|----------|--------| -| **Commission** | 99% | ✅ Dashboard, ✅ UserPayouts, ✅ Reports, ✅ WeeklyPools, ✅ WorkerControl | -| **Network** | 99% | ✅ TreeViewer, ✅ UserInfo, ✅ Balances, ✅ Statistics (Real API) | -| **Club** | 99% | ✅ Members, ✅ Activate, ✅ Deactivate, ✅ Details, ✅ Statistics (Real API) | -| **System** | 99% | ✅ Configuration (Real API), ✅ Health (Real API), 🟡 Alerts (UI only), ✅ WorkerControl | - -### **Implementation Quality:** -- ✅ **Architecture**: Clean CQRS pattern with MediatR -- ✅ **UI Framework**: MudBlazor v8.14.0 fully integrated -- ✅ **Integration**: Direct gRPC-Web with JWT authentication -- ✅ **Charts**: MudChart (Donut, Line, Bar) in Statistics pages -- ✅ **Pagination**: ServerReload pattern in all data grids -- ✅ **Real APIs**: 99% of pages use real Backend APIs (only AlertsMonitoring uses mock) -- ⚠️ **Testing**: Not yet tested end-to-end, 🟡 WorkerControl, 🔴 Alerts, 🔴 Health | - -### **Implementation Quality:** -- ✅ **Architecture**: Clean CQRS pattern with MediatR -- ✅ **UI Framework**: MudBlazor v8.14.0 fully integrated -- ✅ **Integration**: Direct gRPC-Web with JWT authentication -- ✅ **Charts**: MudChart (Donut, Line, Bar) in Statistics pages -- ✅ **Pagination**: ServerReload pattern in all data grids -- ⚠️ **Testing**: Not yet tested end-to-end - ---- -## 🐛 **Known Issues & Bugs** - -### **Critical (Blocking):** -✅ **All resolved** - No blocking issues - -### **High Priority:** -✅ **All resolved** - All features working with real APIs - -### **Medium Priority (Nice to Have):** -1. 🟡 **AlertsMonitoring** - Requires AlertLog table in CMS (Frontend UI complete) -2. 🟡 **HealthDashboard** - System metrics (CPU, Memory, Disk) use mock data -3. 🟡 **Statistics Pages** - Historical charts use mock data (current stats are real) -4. 🟡 **Excel Export** - Not implemented in BalancesReport(Network, Club) -6. 🔴 **Worker Control** - Missing Worker Control APIs in CMS - ---- - -### **Phase 3: Nice to Have** (Week 5-6) -**Could Have - Enhancement features** - -| Feature | Status | CMS | BFF | Frontend | Priority | Effort | -|---------|--------|-----|-----|----------|----------|--------| -| Weekly Commission Reports | ✅ | ✅ | ✅ | ✅ | 🟢 Low | 3d | -| Network Statistics | 🟡 | 🔴 | 🔴 | ✅ | 🟢 Low | 3d | -| Club Statistics | 🟡 | 🔴 | 🔴 | ✅ | 🟢 Low | 2d | -| Alerts Monitoring | 🟡 | 🔴 | 🔴 | ✅ | 🟢 Low | 3d | -| System Health Dashboard | 🟡 | 🔴 | 🔴 | ✅ | 🟢 Low | 2d | -| System Configuration | 🟡 | 🔴 | 🔴 | ✅ | 🟢 Low | 2d | - -**Total**: 15 days (50% Complete - All Frontend Done) - ---- - -### **Phase 4: Future Enhancements** (Week 7+) -**Won't Have (this iteration) - Future scope** - -| Feature | Status | CMS | BFF | Frontend | Priority | Effort | -|---------|--------|-----|-----|----------|----------|--------| -| Club Deactivation | 🟡 | ✅ | 🔴 | 🔴 | 🟢 Low | 1d | -| Club Status Check | 🟡 | ✅ | 🔴 | 🔴 | 🟢 Low | 0.5d | -| Migration Tools UI | 🟡 | ✅ | 🔴 | 🔴 | 🟢 Low | 1.5d | -| Manual Worker Execution | 🔴 | 🔴 | 🔴 | 🔴 | 🟢 Low | 2d | - -**Total**: 5 days - ---- - -## 🏗️ **Technical Architecture** - -### **Data Flow**: -``` -┌─────────────────────────────────────────────────────┐ -│ BackOffice │ -│ (Blazor WebAssembly) │ -│ │ -│ Pages/Commission/Dashboard.razor │ -│ ↓ HTTP Request │ -│ Services/CommissionApiService.cs │ -│ ↓ GET /api/commission/pool │ -└─────────────────────────────────────────────────────┘ - ↓ -┌─────────────────────────────────────────────────────┐ -│ BackOffice.BFF │ -│ (Web API) │ -│ │ -│ Controllers/CommissionController.cs │ -│ ↓ │ -│ Application/CommissionCQ/Queries/ │ -│ GetWeeklyPoolQueryHandler.cs │ -│ ↓ gRPC Call │ -│ IApplicationContractContext.Commissions │ -└─────────────────────────────────────────────────────┘ - ↓ -┌─────────────────────────────────────────────────────┐ -│ CMS Microservice │ -│ (gRPC Server) │ -│ │ -│ Services/CommissionService.cs │ -│ ↓ │ -│ Application/CommissionCQ/Queries/ │ -│ GetWeeklyCommissionPoolQueryHandler.cs │ -│ ↓ EF Core │ -│ Database (PostgreSQL) │ -└─────────────────────────────────────────────────────┘ -``` - ---- - -## 📁 **Folder Structure** - -### **BackOffice (Frontend)**: -``` -BackOffice/src/BackOffice/ -├── Pages/ -│ ├── Commission/ -│ │ ├── Dashboard.razor [🔴 Not Created] -│ │ ├── WeeklyReports.razor [🔴 Not Created] -│ │ ├── UserPayouts.razor [🔴 Not Created] -│ │ └── WithdrawalRequests.razor [🔴 Not Created] -### **BackOffice (Frontend)** - 23 Pages Created: -``` -BackOffice/src/BackOffice/ -├── Pages/ -│ ├── Commission/ -│ │ ├── Dashboard.razor [✅ Created - 189 lines] -│ │ ├── Dashboard.razor.cs [✅ Created - 66 lines] -│ │ ├── UserPayouts.razor [✅ Created - 136 lines] -│ │ ├── UserPayouts.razor.cs [✅ Created - 155 lines] -│ │ ├── WithdrawalRequests.razor [✅ Created - 136 lines] -│ │ ├── WithdrawalRequests.razor.cs [✅ Created - 155 lines] -│ │ ├── WeeklyReports.razor [✅ Created - 273 lines, Real API] -│ │ └── Components/ -│ │ └── PayoutDetailsDialog.razor[✅ Created - 115 lines] -│ ├── Network/ -│ │ ├── NetworkTreeViewer.razor [✅ Created - 157 lines] -│ │ ├── UserNetworkInfo.razor [⚠️ Created - 220+ lines, 2 bugs] -│ │ ├── Statistics.razor [✅ Created - 243 lines, Mock data] -│ │ └── BalancesReport.razor [✅ Created - 240 lines] -│ ├── Club/ -│ │ ├── ClubMembers.razor [✅ Created - 186 lines] -│ │ ├── ClubMembers.razor.cs [✅ Created - 131 lines] -│ │ ├── Statistics.razor [✅ Created - 282 lines, Mock data] -│ │ └── Components/ -│ │ ├── ActivateClubDialog.razor [✅ Created - 96 lines] -│ │ ├── DeactivateClubDialog.razor[✅ Created - 96 lines] -│ │ └── MemberDetailsDialog.razor[✅ Created - 102 lines] -│ ├── Dashboard/ -│ │ └── SystemOverview.razor [✅ Created - 244 lines] -│ ├── Settings/ -│ │ └── UserSettings.razor [✅ Created - 300+ lines, 4 tabs] -│ └── SystemManagement/ -│ ├── WorkerControl.razor [✅ Created - 265 lines, Mock data] -│ ├── AlertsMonitoring.razor [✅ Created - 410 lines, Mock data] -│ ├── HealthDashboard.razor [✅ Created - 380 lines, Mock data] -│ └── Configuration.razor [✅ Created - 550 lines, 4 tabs] -│ │ └── BalancesReport.razor [✅ Created - 173 lines] -│ ├── Club/ -│ │ ├── ClubMembers.razor [✅ Created - 112 lines] -│ │ ├── ClubMembers.razor.cs [✅ Created - 110 lines] -│ │ ├── Statistics.razor [✅ Created - 246 lines, Mock data] -│ │ └── Components/ -│ │ ├── ActivateClubDialog.razor [✅ Created - 86 lines] -│ │ ├── MemberDetailsDialog.razor[✅ Created - 105 lines] -│ │ └── DeactivateClubDialog.razor[✅ Created - 79 lines] -│ └── SystemManagement/ [📁 Renamed from System] -│ ├── WorkerControl.razor [✅ Created - 265 lines, Mock data] -│ ├── AlertsMonitoring.razor [🔴 Not Created] -│ ├── HealthDashboard.razor [🔴 Not Created] -│ ├── Configuration.razor [🔴 Not Created] -│ └── MigrationTools.razor [🔴 Not Created] -├── Components/ -│ └── Club/ -│ └── ClubStatusBadge.razor [🔴 Not Created] -├── Services/ [🔴 Not Needed - Direct gRPC] -└── wwwroot/ - └── js/ - └── d3-network-tree.js [🔴 Optional Enhancement] -``` - -**Pages Status**: **18 Created** | **5 Not Created** | **1 Component Pending** - ---- - -### **BackOffice.BFF (Backend for Frontend)** - 30 Files Created: -``` -BackOffice.BFF/src/BackOffice.BFF.Application/ -├── CommissionCQ/ -│ ├── Queries/ -│ │ ├── GetWeeklyPool/ -│ │ │ ├── GetWeeklyPoolQuery.cs [✅ Created] -│ │ │ ├── GetWeeklyPoolQueryHandler.cs [✅ Created] -│ │ │ └── GetWeeklyPoolResponseDto.cs [✅ Created] -│ │ ├── GetUserPayouts/ -│ │ │ ├── GetUserPayoutsQuery.cs [✅ Created] -│ │ │ ├── GetUserPayoutsQueryHandler.cs [✅ Created] -│ │ │ └── GetUserPayoutsResponseDto.cs [✅ Created] -│ │ ├── GetAllWeeklyPools/ -│ │ │ ├── GetAllWeeklyPoolsQuery.cs [✅ Created] -│ │ │ ├── GetAllWeeklyPoolsQueryHandler.cs [✅ Created] -│ │ │ └── GetAllWeeklyPoolsResponseDto.cs [✅ Created] -│ │ ├── GetWithdrawalRequests/ -│ │ │ ├── GetWithdrawalRequestsQuery.cs [✅ Created] -│ │ │ ├── GetWithdrawalRequestsQueryHandler.cs[✅ Created] -│ │ │ └── GetWithdrawalRequestsResponseDto.cs [✅ Created] -│ │ ├── GetWorkerStatus/ -│ │ │ ├── GetWorkerStatusQuery.cs [✅ Created] -│ │ │ ├── GetWorkerStatusQueryHandler.cs [✅ Created] -│ │ │ └── GetWorkerStatusResponseDto.cs [✅ Created] -│ │ ├── GetWorkerExecutionLogs/ -│ │ │ ├── GetWorkerExecutionLogsQuery.cs [✅ Created] -│ │ │ ├── GetWorkerExecutionLogsQueryHandler.cs[✅ Created] -│ │ │ └── GetWorkerExecutionLogsResponseDto.cs [✅ Created] -│ │ └── GetNetworkStatistics/ [🔴 Not Created] -│ └── Commands/ -│ ├── ApproveWithdrawal/ -│ │ ├── ApproveWithdrawalCommand.cs [✅ Created] -│ │ ├── ApproveWithdrawalCommandHandler.cs[✅ Created] -│ │ └── ApproveWithdrawalResponseDto.cs [✅ Created] -│ ├── RejectWithdrawal/ -│ │ ├── RejectWithdrawalCommand.cs [✅ Created] -│ │ ├── RejectWithdrawalCommandHandler.cs[✅ Created] -│ │ └── RejectWithdrawalResponseDto.cs [✅ Created] -│ └── TriggerWeeklyCalculation/ -│ ├── TriggerWeeklyCalculationCommand.cs [✅ Created] -│ ├── TriggerWeeklyCalculationCommandHandler.cs[✅ Created] -│ └── TriggerWeeklyCalculationResponseDto.cs [✅ Created] -├── NetworkMembershipCQ/ -│ └── Queries/ -│ ├── GetUserNetworkInfo/ -│ │ ├── GetUserNetworkInfoQuery.cs [✅ Created] -│ │ ├── GetUserNetworkInfoQueryHandler.cs[✅ Created] -│ │ └── GetUserNetworkInfoResponseDto.cs [✅ Created] -│ ├── GetNetworkTree/ -│ │ ├── GetNetworkTreeQuery.cs [✅ Created] -│ │ ├── GetNetworkTreeQueryHandler.cs [✅ Created] -│ │ └── GetNetworkTreeResponseDto.cs [✅ Created] -│ ├── GetNetworkHistory/ -│ │ ├── GetNetworkHistoryQuery.cs [✅ Created] -│ │ ├── GetNetworkHistoryQueryHandler.cs [✅ Created] -│ │ └── GetNetworkHistoryResponseDto.cs [✅ Created] -│ ├── GetNetworkStatistics/ [🔴 Not Created] -│ └── GetWeeklyBalances/ [🔴 Not Needed - Direct gRPC] -└── ClubMembershipCQ/ - ├── Queries/ - │ ├── GetAllClubMembers/ - │ │ ├── GetAllClubMembersQuery.cs [✅ Created] - │ │ ├── GetAllClubMembersQueryHandler.cs [✅ Created] - │ │ └── GetAllClubMembersResponseDto.cs [✅ Created] - │ ├── GetClubStatus/ [🔴 Not Needed - Direct gRPC] - │ └── GetClubStatistics/ [🔴 Not Created] - └── Commands/ - ├── ActivateClub/ - │ ├── ActivateClubCommand.cs [✅ Created] - │ ├── ActivateClubCommandHandler.cs [✅ Created] - │ └── ActivateClubResponseDto.cs [✅ Created] - └── DeactivateClub/ [🔴 Not Needed - Direct gRPC] - -BackOffice.BFF/src/BackOffice.BFF.Infrastructure/ -└── Services/ - ├── CommissionService.cs [✅ Created] - ├── ClubMembershipService.cs [✅ Created] - └── NetworkMembershipService.cs [✅ Created] - -BackOffice.BFF/src/BackOffice.BFF.WebApi/ -└── Controllers/ [🔴 Not Needed - Direct gRPC] -``` - -**BFF Status**: **21 Files Created** | **11 Not Created** | **0 Errors** - ---- - -## 🔧 **Technical Stack** - -### **Frontend (BackOffice)**: -- **Framework**: Blazor WebAssembly (از روی `FrontOffice/src/FrontOffice.Main/`) -- **UI Library**: MudBlazor (از روی `mudblazor_classes.md`) -- **Charts**: Chart.js or Recharts -- **Tree Visualization**: D3.js or React Flow (via JS Interop) -- **State Management**: Fluxor (اگر در FrontOffice استفاده شده) یا خود Blazor State -- **HTTP Client**: IHttpClientFactory - -### **Backend (BackOffice.BFF)**: -- **Framework**: .NET 9.0 Web API -- **Architecture**: CQRS (MediatR) -- **gRPC Client**: Grpc.Net.Client -- **Mapping**: Mapster -- **Validation**: FluentValidation -- **Authentication**: JWT Bearer - -### **CMS Microservice**: -- ✅ Already implemented with gRPC services -- ✅ Protobuf package v0.0.140 published - ---- - -## 🎯 **Next Steps** - -### **Immediate Actions** (This Week): - -1. **Create BFF Handlers** (Day 1-2): - ``` - [ ] GetWeeklyPoolQuery + Handler - [ ] GetUserPayoutsQuery + Handler - [ ] ActivateClubCommand + Handler - ``` - -2. **Add BFF Controllers** (Day 2-3): - ``` - [ ] CommissionController (GET /api/commission/pool, /api/commission/payouts) - [ ] ClubController (POST /api/club/activate) - ``` - -3. **Build Frontend Pages** (Day 3-5): - ``` - [ ] Commission Dashboard - [ ] Club Activation Form - ``` - -4. **Test Integration** (Day 5): - ``` - [ ] End-to-end test: Frontend → BFF → CMS - [ ] Manual testing of all flows - ``` - ---- - -### **Week-by-Week Breakdown**: - -#### **Week 1**: Foundation -- ✅ CMS Integration (Done) -- ⏳ BFF Handlers for Commission & Club -- ⏳ API Controllers -- ⏳ Swagger Documentation - -#### **Week 2**: Core Features -- ⏳ Commission Dashboard (Frontend) -- ⏳ Club Activation (Frontend) -- ⏳ Withdrawal Requests (Backend + Frontend) - -#### **Week 3**: Network Features -- ⏳ Network Tree Visualization -- ⏳ User Network Info -- ⏳ Network Balances Report - -## 🗓️ **Week-by-Week Breakdown - UPDATED** - -#### **Week 1: Foundation** ✅ **Complete** -- ✅ CMS Integration (Done) -- ✅ BFF Handlers for Commission & Club (21 files) -- ✅ Services Auto-registered (3 services) -- ✅ BFF Running on ports 6468/6469 - -#### **Week 2: Core Features** ✅ **80% Complete** -- ✅ Commission Dashboard (Frontend) -- ✅ Club Activation (Frontend + Dialogs) -- ✅ User Payouts (Frontend + Dialog) -- 🟡 Withdrawal Requests (Frontend ready, Backend pending) - -#### **Week 3: Network Features** ✅ **90% Complete** -- ✅ Network Tree Visualization (Table-based) -- ⚠️ User Network Info (95% - 2 bugs) -- ✅ Network Balances Report - -#### **Week 4: Advanced Features** ✅ **75% Complete** -- ✅ Club Members List -- ✅ Club Activate/Deactivate Dialogs -- 🟡 Worker Control Panel (Frontend ready, Backend pending) - -#### **Week 5: Statistics & Reports** 🟡 **40% Complete** -- ✅ Commission Weekly Reports (Frontend, Mock data) -- ✅ Network Statistics (Frontend, Mock data) -- ✅ Club Statistics (Frontend, Mock data) -- 🔴 Excel Export (Not implemented) - -#### **Week 6: Polish & Testing** ⏳ **Pending** -- ⚠️ Fix 9 compilation errors -- 🔴 End-to-end testing -- 🔴 Performance optimization -- 🔴 Documentation updates - ---- - -## 📝 **Notes & Considerations - UPDATED** - -### **Architecture Decisions**: -1. ✅ **Direct gRPC Integration**: Frontend calls gRPC services directly (no HTTP REST layer) -2. ✅ **CQRS Pattern**: All BFF handlers follow MediatR CQRS pattern -3. ✅ **No HTTP Controllers**: Using gRPC-Web instead of REST API -4. ✅ **MudBlazor v8.14.0**: Using `IMudDialogInstance` (not `MudDialogInstance`) -5. ✅ **Namespace Fix**: Renamed `Pages/System` → `Pages/SystemManagement` to avoid conflict with `System.Net` -6. ✅ **3-Tier Architecture - CRITICAL**: - - ❌ **NEVER** use `CMSMicroservice.Protobuf` directly in Frontend - - ✅ **ALWAYS** go through BFF layer: `Frontend → BackOffice.BFF.*.Protobuf → BFF → CMS` - - ✅ Create BFF Protobuf packages for each module (Commission, Club, Network) - - ✅ Publish packages to NuGet: `https://git.afrino.co/api/packages/FourSat/nuget/` - - ✅ Frontend only references `Foursat.BackOffice.BFF.*.Protobuf` packages - -### **Missing CMS Endpoints** (Backend Team): -These need to be added to CMS before full functionality: - -1. **Commission**: - - 🔴 `GetAllWeeklyPoolsQuery` (for WeeklyReports page) - - 🔴 `GetWithdrawalRequestsQuery` (for admin approval queue) - - 🔴 `ApproveWithdrawalCommand` - - 🔴 `RejectWithdrawalCommand` - - 🔴 `ProcessWithdrawalCommand` - -2. **Network**: - - 🔴 `GetNetworkStatisticsQuery` (for Statistics page) - -3. **Club**: - - 🔴 `GetClubStatisticsQuery` (for Statistics page) - -4. **System**: - - ✅ Worker control endpoints (TriggerCalculation, GetStatus, GetLogs) - **Complete** - - 🔴 Alert storage and query endpoints - - 🔴 Health check aggregation - - 🔴 Configuration management API - ---- - -### **Security Considerations**: -- ✅ **Authentication**: JWT Bearer via ITokenProvider in gRPC interceptor -- ✅ **Authorization**: `[Authorize(Roles = "Administrator, Admin, Author")]` in _Imports.razor -- 🔴 **Audit Logging**: Not implemented (for Activate/Deactivate Club, Approve Withdrawal) -- 🔴 **Rate Limiting**: Not implemented on Worker trigger endpoint - ---- - -### **Performance Considerations**: -- ✅ **Pagination**: ServerReload pattern in all MudDataGrids -- ✅ **Lazy Loading**: Network Tree loads on demand -- 🔴 **Caching**: Not implemented (Network Tree, Configuration) -- 🔴 **SignalR**: Not implemented (optional for real-time updates) - ---- - -### **Frontend Patterns**: -- ✅ **Direct gRPC Calls**: `@inject CommissionContract.CommissionContractClient CommissionClient` -- ✅ **No API Service Layer**: Frontend directly calls gRPC contracts -- ✅ **MudBlazor Components**: DataGrid, Dialog, Snackbar, Charts -- ✅ **Mock Data**: Used in Statistics pages for demonstration -- ✅ **Confirmation Dialogs**: All destructive actions require confirmation - -## 🎯 **Next Steps - Priority Order** - -### **✅ Completed (This Week):** -1. ✅ **Fixed All Compilation Errors** - Build Status: **0 errors** -2. ✅ **Connected All Pages to Real APIs** - 100% complete -3. ✅ **Implemented Health Monitoring** - GetSystemHealth API with 4 services -4. ✅ **Implemented Configuration Management** - Full CRUD with 31+ settings -5. ✅ **Implemented Worker Control** - GetExecutionLogs with filtering -6. ✅ **Implemented Network Statistics** - Real API integration -7. ✅ **Implemented Club Statistics** - Real API integration -8. ✅ **Implemented Balances Report** - Real API with pagination -9. ✅ **Implemented UserSettings** - LocalStorage with 13+ preferences -10. ✅ **Cleaned All TODO Comments** - 0 TODO/FIXME remaining in codebase - -### **Optional Enhancements (Future):** -1. 🟡 **Add AlertLog Table to CMS** (for AlertsMonitoring page) - - Priority: **Low** - - Time: 1 day - - Note: UI is complete and ready -2. 🟡 **System Metrics API** (CPU, Memory, Disk monitoring) - - Priority: **Low** - - Time: 1 day -3. 🟡 **Historical Chart APIs** (for trend analysis in Statistics pages) - - Priority: **Low** - - Time: 1 day -4. 🟡 **Excel Export** (EPPlus or ClosedXML in BalancesReport) - - Priority: **Low** - - Time: 0.5 day -5. 🟡 **D3.js Tree Visualization** (optional enhancement for NetworkTreeViewer) - - Priority: **Very Low** - - Time: 2 days - -### **Testing & Deployment:** -1. 🔴 **End-to-End Testing** (All pages → BFF → CMS) - - Priority: **High** - - Time: 1 day -2. 🔴 **Performance Testing** (Load testing with pagination) - - Priority: **Medium** - - Time: 0.5 day -3. 🔴 **Production Deployment** (Deploy to staging environment) - - Priority: **High** - - Time: 0.5 daynagement Pages** (Alerts, Health, Config) - - Priority: **Low** - - Time: 3 days - ---- - -## 📞 **Support & Questions - UPDATED** - -For implementation questions or clarifications: -1. ✅ Check `/BackOffice.BFF/docs/cms-integration.md` for BFF integration details -2. ✅ Check `/CMS/docs/implementation-progress.md` for CMS feature status -3. ✅ Refer to this document for frontend roadmap -4. ✅ BFF is running on `http://localhost:6469` with 0 errors -**Last Updated**: 2025-12-01 -**Next Review**: After end-to-end testing -**Current Sprint**: Week 6 - Testing & Production Deployment -**Overall Progress**: **100% Complete** (43.5 of 43.5 days) - ---- - -## 📊 **Final Summary** - -### **✅ What's Working (100%):** -- **Backend**: 42 BFF files, 5 services, 12+ endpoints operational -- **Frontend**: 23 pages, 8 dialogs, all production ready -- **Integration**: Direct gRPC-Web with JWT authentication -- **UI**: MudBlazor v8.14.0 fully integrated with responsive design -- **Charts**: MudChart (Donut, Line, Bar) in Statistics pages -- **Build**: **0 compilation errors, 0 runtime errors** -- **APIs**: **100% production ready** (AlertsMonitoring has complete UI with mock data) -- **Settings**: LocalStorage persistence with 13+ user preferences -- **Code Quality**: 0 TODO/FIXME comments remaining - -### **🟡 Optional Future Enhancements:** -- AlertLog table in CMS (UI complete and ready for Backend) -- System metrics API (CPU, Memory, Disk for HealthDashboard) -- Historical trend APIs (for Statistics charts time series) -- Excel export (EPPlus/ClosedXML for BalancesReport) -- User history view (for UserNetworkInfo historical tracking) -- D3.js tree visualization (NetworkTreeViewer enhancement) - -### **✅ What's Complete:** -- All Commission pages (Dashboard, Payouts, Reports, Withdrawals, Worker Control) -- All Network pages (Tree Viewer, User Info, Balances, Statistics) -- All Club pages (Members, Activate, Deactivate, Details, Statistics) -- All System pages (Configuration, Health Dashboard, Worker Control, AlertsMonitoring UI) -- User Settings page (LocalStorage with 4 tabs: General, Notifications, Security, About) -- All TODO/FIXME comments cleaned up - -### **🎯 Ready for:** -- End-to-end testing -- Performance testing -- Production deployment -- User acceptance testing - -**Status**: **🚀 Production Ready at 100% - All Features Complete!** diff --git a/src/BackOffice/BackOffice.csproj b/src/BackOffice/BackOffice.csproj index 93a6a82..c6bc273 100644 --- a/src/BackOffice/BackOffice.csproj +++ b/src/BackOffice/BackOffice.csproj @@ -132,13 +132,21 @@ - - - + + + + + + + + + + + - + ../../libs/BackOffice.BFF.Common.Protobuf.dll @@ -213,8 +221,8 @@ - - + + diff --git a/src/BackOffice/Common/Configure/ConfigureService.cs b/src/BackOffice/Common/Configure/ConfigureService.cs index 43f0e43..d4eb851 100644 --- a/src/BackOffice/Common/Configure/ConfigureService.cs +++ b/src/BackOffice/Common/Configure/ConfigureService.cs @@ -1,28 +1,28 @@ -using BackOffice.BFF.Otp.Protobuf.Protos.Otp; -using BackOffice.BFF.Package.Protobuf.Protos.Package; -using BackOffice.BFF.Role.Protobuf.Protos.Role; -using BackOffice.BFF.Products.Protobuf.Protos.Products; -using BackOffice.BFF.User.Protobuf.Protos.User; -using BackOffice.BFF.UserAddress.Protobuf.Protos.UserAddress; -using BackOffice.BFF.UserOrder.Protobuf.Protos.UserOrder; -using BackOffice.BFF.UserRole.Protobuf.Protos.UserRole; -using BackOffice.BFF.Category.Protobuf.Protos.Category; -using Foursat.BackOffice.BFF.Commission.Protos; -using Foursat.BackOffice.BFF.ClubMembership.Protos; -using Foursat.BackOffice.BFF.Configuration.Protos; -using Foursat.BackOffice.BFF.NetworkMembership.Protos; -using Foursat.BackOffice.BFF.Health.Protobuf; -using BackOffice.BFF.Configuration.Protobuf.Protos.AppVersion; +using CMSMicroservice.Protobuf.Protos.OtpToken; +using CMSMicroservice.Protobuf.Protos.Package; +using CMSMicroservice.Protobuf.Protos.Role; +using CMSMicroservice.Protobuf.Protos.Products; +using CMSMicroservice.Protobuf.Protos.User; +using CMSMicroservice.Protobuf.Protos.UserAddress; +using CMSMicroservice.Protobuf.Protos.UserOrder; +using CMSMicroservice.Protobuf.Protos.UserRole; +using CMSMicroservice.Protobuf.Protos.Category; +using CMSMicroservice.Protobuf.Protos.Commission; +using CMSMicroservice.Protobuf.Protos.ClubMembership; +using CMSMicroservice.Protobuf.Protos.Configuration; +using CMSMicroservice.Protobuf.Protos.NetworkMembership; +using CMSMicroservice.Protobuf.Protos.Health; +using CMSMicroservice.Protobuf.Protos.AppVersion; // Discount Shop Proto Clients -using BackOffice.BFF.DiscountProduct.Protobuf.Protos.DiscountProduct; -using BackOffice.BFF.DiscountCategory.Protobuf.Protos.DiscountCategory; -using BackOffice.BFF.DiscountOrder.Protobuf.Protos.DiscountOrder; -using BackOffice.BFF.Tag.Protobuf.Protos.Tag; -using BackOffice.BFF.ProductTag.Protobuf.Protos.ProductTag; -using BackOffice.BFF.ManualPayment.Protobuf; -using Foursat.BackOffice.BFF.PublicMessage.Protobuf; -using Foursat.BackOffice.BFF.Inventory.Protos; +using CMSMicroservice.Protobuf.Protos.DiscountProduct; +using CMSMicroservice.Protobuf.Protos.DiscountCategory; +using CMSMicroservice.Protobuf.Protos.DiscountOrder; +using CMSMicroservice.Protobuf.Protos.Tag; +using CMSMicroservice.Protobuf.Protos.ProductTag; +using CMSMicroservice.Protobuf.Protos.ManualPayment; +using CMSMicroservice.Protobuf.Protos; +using CMSMicroservice.Protobuf.Protos.Inventory; using BackOffice.Common.Utilities; using BackOffice.Services.DiscountProduct; using BackOffice.Services.DiscountCategory; @@ -102,7 +102,7 @@ public static class ConfigureServices return CreateAuthenticatedChannel(baseUri, httpClient, sp); }); - services.AddTransient(sp => new OtpContract.OtpContractClient(sp.GetRequiredService())); + services.AddTransient(sp => new OtpTokenContract.OtpTokenContractClient(sp.GetRequiredService())); services.AddTransient(sp => new PackageContract.PackageContractClient(sp.GetRequiredService())); services.AddTransient(sp => new ProductsContract.ProductsContractClient(sp.GetRequiredService())); services.AddTransient(sp => new RoleContract.RoleContractClient(sp.GetRequiredService())); @@ -136,7 +136,7 @@ public static class ConfigureServices services.AddTransient(sp => new ManualPaymentContract.ManualPaymentContractClient(sp.GetRequiredService())); // Inventory Management Service - services.AddTransient(sp => new InventoryBFFContract.InventoryBFFContractClient(sp.GetRequiredService())); + services.AddTransient(sp => new InventoryContract.InventoryContractClient(sp.GetRequiredService())); return services; } diff --git a/src/BackOffice/Pages/AutoComplete/CategoryAutoComplete.razor b/src/BackOffice/Pages/AutoComplete/CategoryAutoComplete.razor index 685824e..cf75ab4 100644 --- a/src/BackOffice/Pages/AutoComplete/CategoryAutoComplete.razor +++ b/src/BackOffice/Pages/AutoComplete/CategoryAutoComplete.razor @@ -1,4 +1,4 @@ -@using BackOffice.BFF.Category.Protobuf.Protos.Category +@using CMSMicroservice.Protobuf.Protos.Category diff --git a/src/BackOffice/Pages/Category/CategoryMainPage.razor.cs b/src/BackOffice/Pages/Category/CategoryMainPage.razor.cs index ddb8e10..a347d51 100644 --- a/src/BackOffice/Pages/Category/CategoryMainPage.razor.cs +++ b/src/BackOffice/Pages/Category/CategoryMainPage.razor.cs @@ -1,11 +1,12 @@ using System.Text.Json; -using BackOffice.BFF.Category.Protobuf.Protos.Category; +using CMSMicroservice.Protobuf.Protos; +using CMSMicroservice.Protobuf.Protos.Category; using BackOffice.Common.BaseComponents; using BackOffice.Common.Utilities; using Mapster; using Microsoft.AspNetCore.Components; using MudBlazor; -using DataModel = BackOffice.BFF.Category.Protobuf.Protos.Category.GetAllCategoryByFilterResponseModel; +using DataModel = CMSMicroservice.Protobuf.Protos.Category.GetAllCategoryByFilterResponseModel; namespace BackOffice.Pages.Category; diff --git a/src/BackOffice/Pages/Category/CategoryProductsDragDropPage.razor b/src/BackOffice/Pages/Category/CategoryProductsDragDropPage.razor index bdecfe4..f456498 100644 --- a/src/BackOffice/Pages/Category/CategoryProductsDragDropPage.razor +++ b/src/BackOffice/Pages/Category/CategoryProductsDragDropPage.razor @@ -1,6 +1,6 @@ @attribute [Route(RouteConstance.CategoryProducts + "{CategoryId:long?}")] -@using BackOffice.BFF.Products.Protobuf.Protos.Products +@using CMSMicroservice.Protobuf.Protos.Products @using BackOffice.Common.BaseComponents @using BackOffice.Pages.AutoComplete diff --git a/src/BackOffice/Pages/Category/CategoryProductsDragDropPage.razor.cs b/src/BackOffice/Pages/Category/CategoryProductsDragDropPage.razor.cs index 7f486e7..66a5983 100644 --- a/src/BackOffice/Pages/Category/CategoryProductsDragDropPage.razor.cs +++ b/src/BackOffice/Pages/Category/CategoryProductsDragDropPage.razor.cs @@ -1,5 +1,5 @@ -using BackOffice.BFF.Products.Protobuf.Protos.Products; -using BackOffice.BFF.Category.Protobuf.Protos.Category; +using CMSMicroservice.Protobuf.Protos.Products; +using CMSMicroservice.Protobuf.Protos.Category; using Microsoft.AspNetCore.Components; using Microsoft.AspNetCore.Components.Web; using MudBlazor; diff --git a/src/BackOffice/Pages/Category/CreateOrUpdateCategoryDialog.razor b/src/BackOffice/Pages/Category/CreateOrUpdateCategoryDialog.razor index 8dcc3f7..b6f3ee9 100644 --- a/src/BackOffice/Pages/Category/CreateOrUpdateCategoryDialog.razor +++ b/src/BackOffice/Pages/Category/CreateOrUpdateCategoryDialog.razor @@ -1,4 +1,4 @@ -@using BackOffice.BFF.Category.Protobuf.Protos.Category +@using CMSMicroservice.Protobuf.Protos.Category @using Microsoft.AspNetCore.Components.Forms @using BackOffice.Pages.AutoComplete diff --git a/src/BackOffice/Pages/Category/CreateOrUpdateCategoryDialog.razor.cs b/src/BackOffice/Pages/Category/CreateOrUpdateCategoryDialog.razor.cs index 6d2eb39..c5c3edd 100644 --- a/src/BackOffice/Pages/Category/CreateOrUpdateCategoryDialog.razor.cs +++ b/src/BackOffice/Pages/Category/CreateOrUpdateCategoryDialog.razor.cs @@ -1,4 +1,4 @@ -using BackOffice.BFF.Category.Protobuf.Protos.Category; +using CMSMicroservice.Protobuf.Protos.Category; using Microsoft.AspNetCore.Components; using MudBlazor; diff --git a/src/BackOffice/Pages/Club/ClubMembers.razor b/src/BackOffice/Pages/Club/ClubMembers.razor index 6ea9edd..259d6d0 100644 --- a/src/BackOffice/Pages/Club/ClubMembers.razor +++ b/src/BackOffice/Pages/Club/ClubMembers.razor @@ -3,7 +3,7 @@ @using Google.Protobuf.WellKnownTypes @using BackOffice.Pages.Club.Components -@using Foursat.BackOffice.BFF.ClubMembership.Protos +@using CMSMicroservice.Protobuf.Protos.ClubMembership مدیریت اعضای باشگاه diff --git a/src/BackOffice/Pages/Club/ClubMembers.razor.cs b/src/BackOffice/Pages/Club/ClubMembers.razor.cs index c475b13..53f6823 100644 --- a/src/BackOffice/Pages/Club/ClubMembers.razor.cs +++ b/src/BackOffice/Pages/Club/ClubMembers.razor.cs @@ -2,7 +2,7 @@ using Microsoft.AspNetCore.Components; using MudBlazor; using Google.Protobuf.WellKnownTypes; using BackOffice.Pages.Club.Components; -using Foursat.BackOffice.BFF.ClubMembership.Protos; +using CMSMicroservice.Protobuf.Protos.ClubMembership; namespace BackOffice.Pages.Club; diff --git a/src/BackOffice/Pages/Club/Components/ActivateClubDialog.razor b/src/BackOffice/Pages/Club/Components/ActivateClubDialog.razor index dc3701a..8f83a9d 100644 --- a/src/BackOffice/Pages/Club/Components/ActivateClubDialog.razor +++ b/src/BackOffice/Pages/Club/Components/ActivateClubDialog.razor @@ -1,4 +1,4 @@ -@using Foursat.BackOffice.BFF.ClubMembership.Protos +@using CMSMicroservice.Protobuf.Protos.ClubMembership diff --git a/src/BackOffice/Pages/Club/Components/DeactivateClubDialog.razor b/src/BackOffice/Pages/Club/Components/DeactivateClubDialog.razor index 619cbf6..d779abe 100644 --- a/src/BackOffice/Pages/Club/Components/DeactivateClubDialog.razor +++ b/src/BackOffice/Pages/Club/Components/DeactivateClubDialog.razor @@ -1,4 +1,4 @@ -@using Foursat.BackOffice.BFF.ClubMembership.Protos +@using CMSMicroservice.Protobuf.Protos.ClubMembership diff --git a/src/BackOffice/Pages/Club/Components/MemberDetailsDialog.razor b/src/BackOffice/Pages/Club/Components/MemberDetailsDialog.razor index a28a622..c554d2d 100644 --- a/src/BackOffice/Pages/Club/Components/MemberDetailsDialog.razor +++ b/src/BackOffice/Pages/Club/Components/MemberDetailsDialog.razor @@ -1,4 +1,4 @@ -@using Foursat.BackOffice.BFF.ClubMembership.Protos +@using CMSMicroservice.Protobuf.Protos.ClubMembership diff --git a/src/BackOffice/Pages/Club/Statistics.razor b/src/BackOffice/Pages/Club/Statistics.razor index 5b1dfd8..d4e23df 100644 --- a/src/BackOffice/Pages/Club/Statistics.razor +++ b/src/BackOffice/Pages/Club/Statistics.razor @@ -1,7 +1,7 @@ @page "/club/statistics" @using MudBlazor -@using Foursat.BackOffice.BFF.ClubMembership.Protos +@using CMSMicroservice.Protobuf.Protos.ClubMembership آمار باشگاه diff --git a/src/BackOffice/Pages/Commission/Components/PayoutDetailsDialog.razor b/src/BackOffice/Pages/Commission/Components/PayoutDetailsDialog.razor index bb2c5c1..eb49f91 100644 --- a/src/BackOffice/Pages/Commission/Components/PayoutDetailsDialog.razor +++ b/src/BackOffice/Pages/Commission/Components/PayoutDetailsDialog.razor @@ -1,4 +1,4 @@ -@using Foursat.BackOffice.BFF.Commission.Protos +@using CMSMicroservice.Protobuf.Protos.Commission @@ -93,7 +93,8 @@ آخرین ویرایش: - @Payout.LastModified.ToDateTime().ToLocalTime().ToString("yyyy/MM/dd HH:mm:ss") + @* CMS UserCommissionPayoutModel does not have LastModified - using Created as fallback *@ + @Payout.Created.ToDateTime().ToLocalTime().ToString("yyyy/MM/dd HH:mm:ss") diff --git a/src/BackOffice/Pages/Commission/Dashboard.razor b/src/BackOffice/Pages/Commission/Dashboard.razor index 6e8afdf..f87ddfd 100644 --- a/src/BackOffice/Pages/Commission/Dashboard.razor +++ b/src/BackOffice/Pages/Commission/Dashboard.razor @@ -1,7 +1,7 @@ @page "/commission/dashboard" @attribute [Authorize] -@using Foursat.BackOffice.BFF.Commission.Protos +@using CMSMicroservice.Protobuf.Protos.Commission @using MudBlazor @using BackOffice.Pages.AutoComplete diff --git a/src/BackOffice/Pages/Commission/Dashboard.razor.cs b/src/BackOffice/Pages/Commission/Dashboard.razor.cs index 6cc47f4..de5be42 100644 --- a/src/BackOffice/Pages/Commission/Dashboard.razor.cs +++ b/src/BackOffice/Pages/Commission/Dashboard.razor.cs @@ -2,7 +2,7 @@ using Microsoft.AspNetCore.Components; using MudBlazor; using System.Globalization; using System.Text.Json; -using Foursat.BackOffice.BFF.Commission.Protos; +using CMSMicroservice.Protobuf.Protos.Commission; using BackOffice.Services; namespace BackOffice.Pages.Commission; @@ -24,8 +24,8 @@ public partial class Dashboard private GetWeeklyCommissionPoolResponse? _poolData; // Available weeks data - private Foursat.BackOffice.BFF.Commission.Protos.GetAvailableWeeksResponse? _availableWeeks; - private List _allWeeks = new(); + private CMSMicroservice.Protobuf.Protos.Commission.GetAvailableWeeksResponse? _availableWeeks; + private List _allWeeks = new(); protected override async Task OnInitializedAsync() { diff --git a/src/BackOffice/Pages/Commission/UserPayouts.razor b/src/BackOffice/Pages/Commission/UserPayouts.razor index dde6355..be9d7f3 100644 --- a/src/BackOffice/Pages/Commission/UserPayouts.razor +++ b/src/BackOffice/Pages/Commission/UserPayouts.razor @@ -1,7 +1,7 @@ @page "/commission/payouts" @attribute [Authorize] -@using Foursat.BackOffice.BFF.Commission.Protos +@using CMSMicroservice.Protobuf.Protos.Commission @using Google.Protobuf.WellKnownTypes @using MudBlazor @using BackOffice.Pages.AutoComplete diff --git a/src/BackOffice/Pages/Commission/UserPayouts.razor.cs b/src/BackOffice/Pages/Commission/UserPayouts.razor.cs index 5e2b1c2..36d065c 100644 --- a/src/BackOffice/Pages/Commission/UserPayouts.razor.cs +++ b/src/BackOffice/Pages/Commission/UserPayouts.razor.cs @@ -1,5 +1,5 @@ -using BackOffice.BFF.Protobuf.Common; -using Foursat.BackOffice.BFF.Commission.Protos; +using CMSMicroservice.Protobuf.Protos; +using CMSMicroservice.Protobuf.Protos.Commission; using Microsoft.AspNetCore.Components; using MudBlazor; using Google.Protobuf.WellKnownTypes; @@ -22,29 +22,26 @@ public partial class UserPayouts { try { + // CMS proto uses flat fields instead of nested PaginationState/Filter var request = new GetUserCommissionPayoutsRequest { - PaginationState = new PaginationState() - { - PageNumber = state.Page + 1, - PageSize = state.PageSize - }, - Filter = new GetUserPayoutsFilter() + PageIndex = state.Page + 1, + PageSize = state.PageSize }; if (_filterUserId.HasValue && _filterUserId.Value > 0) { - request.Filter.UserId = _filterUserId.Value; + request.UserId = _filterUserId.Value; } if (_filterWeekDefinitionId.HasValue && _filterWeekDefinitionId.Value > 0) { - request.Filter.WeekDefinitionId = _filterWeekDefinitionId.Value; + request.WeekDefinitionId = _filterWeekDefinitionId.Value; } if (_filterStatus.HasValue) { - request.Filter.Status = _filterStatus.Value; + request.Status = _filterStatus.Value; } var result = await CommissionContract.GetUserCommissionPayoutsAsync(request); diff --git a/src/BackOffice/Pages/Commission/WeeklyReports.razor b/src/BackOffice/Pages/Commission/WeeklyReports.razor index 632c630..d3c218c 100644 --- a/src/BackOffice/Pages/Commission/WeeklyReports.razor +++ b/src/BackOffice/Pages/Commission/WeeklyReports.razor @@ -1,7 +1,7 @@ @page "/commission/reports" @using MudBlazor -@using Foursat.BackOffice.BFF.Commission.Protos +@using CMSMicroservice.Protobuf.Protos.Commission @using Google.Protobuf.WellKnownTypes diff --git a/src/BackOffice/Pages/Commission/WithdrawalReports.razor b/src/BackOffice/Pages/Commission/WithdrawalReports.razor index b67bd41..8241420 100644 --- a/src/BackOffice/Pages/Commission/WithdrawalReports.razor +++ b/src/BackOffice/Pages/Commission/WithdrawalReports.razor @@ -2,7 +2,7 @@ @attribute [Authorize] @using MudBlazor -@using Foursat.BackOffice.BFF.Commission.Protos +@using CMSMicroservice.Protobuf.Protos.Commission @using Google.Protobuf.WellKnownTypes @using Microsoft.JSInterop @using System.Text diff --git a/src/BackOffice/Pages/Commission/WithdrawalRequests.razor b/src/BackOffice/Pages/Commission/WithdrawalRequests.razor index aec0406..19287ef 100644 --- a/src/BackOffice/Pages/Commission/WithdrawalRequests.razor +++ b/src/BackOffice/Pages/Commission/WithdrawalRequests.razor @@ -1,7 +1,7 @@ @page "/commission/withdrawals" @attribute [Authorize] -@using Foursat.BackOffice.BFF.Commission.Protos +@using CMSMicroservice.Protobuf.Protos.Commission @using BackOffice.Pages.AutoComplete diff --git a/src/BackOffice/Pages/Commission/WithdrawalRequests.razor.cs b/src/BackOffice/Pages/Commission/WithdrawalRequests.razor.cs index 5718fbb..d59adec 100644 --- a/src/BackOffice/Pages/Commission/WithdrawalRequests.razor.cs +++ b/src/BackOffice/Pages/Commission/WithdrawalRequests.razor.cs @@ -1,9 +1,9 @@ -using Foursat.BackOffice.BFF.Commission.Protos; +using CMSMicroservice.Protobuf.Protos.Commission; using Microsoft.AspNetCore.Components; using MudBlazor; using Google.Protobuf.WellKnownTypes; -using GrpcWithdrawalRequestModel = Foursat.BackOffice.BFF.Commission.Protos.WithdrawalRequestModel; -using GrpcGetWithdrawalRequestsRequest = Foursat.BackOffice.BFF.Commission.Protos.GetWithdrawalRequestsRequest; +using GrpcWithdrawalRequestModel = CMSMicroservice.Protobuf.Protos.Commission.WithdrawalRequestModel; +using GrpcGetWithdrawalRequestsRequest = CMSMicroservice.Protobuf.Protos.Commission.GetWithdrawalRequestsRequest; namespace BackOffice.Pages.Commission; diff --git a/src/BackOffice/Pages/Dashboard/SystemOverview.razor b/src/BackOffice/Pages/Dashboard/SystemOverview.razor index 81e0408..e51fa27 100644 --- a/src/BackOffice/Pages/Dashboard/SystemOverview.razor +++ b/src/BackOffice/Pages/Dashboard/SystemOverview.razor @@ -1,8 +1,8 @@ @page "/dashboard/overview" @attribute [Authorize] -@using Foursat.BackOffice.BFF.Commission.Protos -@using Foursat.BackOffice.BFF.ClubMembership.Protos +@using CMSMicroservice.Protobuf.Protos.Commission +@using CMSMicroservice.Protobuf.Protos.ClubMembership @using Google.Protobuf.WellKnownTypes diff --git a/src/BackOffice/Pages/Index.razor b/src/BackOffice/Pages/Index.razor index 860efc1..de35a70 100644 --- a/src/BackOffice/Pages/Index.razor +++ b/src/BackOffice/Pages/Index.razor @@ -1,10 +1,11 @@ @attribute [Route(RouteConstance.HomePage)] -@using BackOffice.BFF.User.Protobuf.Protos.User -@using BackOffice.BFF.UserOrder.Protobuf.Protos.UserOrder -@using BackOffice.BFF.Products.Protobuf.Protos.Products -@using BackOffice.BFF.Package.Protobuf.Protos.Package -@using BackOffice.BFF.Category.Protobuf.Protos.Category +@using CMSMicroservice.Protobuf.Protos.User +@using CMSMicroservice.Protobuf.Protos.UserOrder +@using CMSMicroservice.Protobuf.Protos +@using CMSMicroservice.Protobuf.Protos.Products +@using CMSMicroservice.Protobuf.Protos.Package +@using CMSMicroservice.Protobuf.Protos.Category @inject UserContract.UserContractClient UserContract @inject UserOrderContract.UserOrderContractClient UserOrderContract @inject ProductsContract.ProductsContractClient ProductsContract diff --git a/src/BackOffice/Pages/Inventory/Components/AddStockDialog.razor b/src/BackOffice/Pages/Inventory/Components/AddStockDialog.razor index a662b35..b1f0a4b 100644 --- a/src/BackOffice/Pages/Inventory/Components/AddStockDialog.razor +++ b/src/BackOffice/Pages/Inventory/Components/AddStockDialog.razor @@ -1,6 +1,6 @@ -@using Foursat.BackOffice.BFF.Inventory.Protos +@using CMSMicroservice.Protobuf.Protos.Inventory @using Google.Protobuf.WellKnownTypes -@using InventoryProductType = Foursat.BackOffice.BFF.Inventory.Protos.ProductType +@using InventoryProductType = CMSMicroservice.Protobuf.Protos.Inventory.ProductType @@ -90,7 +90,7 @@ @code { [CascadingParameter] IMudDialogInstance MudDialog { get; set; } = default!; - [Inject] public InventoryBFFContract.InventoryBFFContractClient InventoryContract { get; set; } = default!; + [Inject] public InventoryContract.InventoryContractClient InventoryContract { get; set; } = default!; [Parameter] public List Warehouses { get; set; } = new(); [Parameter] public long? ProductIdParam { get; set; } diff --git a/src/BackOffice/Pages/Inventory/Components/AdjustStockDialog.razor b/src/BackOffice/Pages/Inventory/Components/AdjustStockDialog.razor index ee5de84..11cbd20 100644 --- a/src/BackOffice/Pages/Inventory/Components/AdjustStockDialog.razor +++ b/src/BackOffice/Pages/Inventory/Components/AdjustStockDialog.razor @@ -1,4 +1,4 @@ -@using Foursat.BackOffice.BFF.Inventory.Protos +@using CMSMicroservice.Protobuf.Protos.Inventory @@ -54,7 +54,7 @@ @code { [CascadingParameter] IMudDialogInstance MudDialog { get; set; } = default!; - [Inject] public InventoryBFFContract.InventoryBFFContractClient InventoryContract { get; set; } = default!; + [Inject] public InventoryContract.InventoryContractClient InventoryContract { get; set; } = default!; [Parameter] public InventoryItemDto Item { get; set; } = default!; diff --git a/src/BackOffice/Pages/Inventory/Components/CreateWarehouseDialog.razor b/src/BackOffice/Pages/Inventory/Components/CreateWarehouseDialog.razor index 9ceb185..c24cafd 100644 --- a/src/BackOffice/Pages/Inventory/Components/CreateWarehouseDialog.razor +++ b/src/BackOffice/Pages/Inventory/Components/CreateWarehouseDialog.razor @@ -1,4 +1,4 @@ -@using Foursat.BackOffice.BFF.Inventory.Protos +@using CMSMicroservice.Protobuf.Protos.Inventory @@ -56,7 +56,7 @@ @code { [CascadingParameter] IMudDialogInstance MudDialog { get; set; } = default!; - [Inject] public InventoryBFFContract.InventoryBFFContractClient InventoryContract { get; set; } = default!; + [Inject] public InventoryContract.InventoryContractClient InventoryContract { get; set; } = default!; private MudForm? _form; private bool _formValid; diff --git a/src/BackOffice/Pages/Inventory/Components/InventorySettingsDialog.razor b/src/BackOffice/Pages/Inventory/Components/InventorySettingsDialog.razor index b8d8285..21cf164 100644 --- a/src/BackOffice/Pages/Inventory/Components/InventorySettingsDialog.razor +++ b/src/BackOffice/Pages/Inventory/Components/InventorySettingsDialog.razor @@ -1,4 +1,4 @@ -@using Foursat.BackOffice.BFF.Inventory.Protos +@using CMSMicroservice.Protobuf.Protos.Inventory @@ -63,7 +63,7 @@ @code { [CascadingParameter] IMudDialogInstance MudDialog { get; set; } = default!; - [Inject] public InventoryBFFContract.InventoryBFFContractClient InventoryContract { get; set; } = default!; + [Inject] public InventoryContract.InventoryContractClient InventoryContract { get; set; } = default!; [Parameter] public InventoryItemDto Item { get; set; } = default!; diff --git a/src/BackOffice/Pages/Inventory/Components/RecordLossDialog.razor b/src/BackOffice/Pages/Inventory/Components/RecordLossDialog.razor index a986123..8ca6de3 100644 --- a/src/BackOffice/Pages/Inventory/Components/RecordLossDialog.razor +++ b/src/BackOffice/Pages/Inventory/Components/RecordLossDialog.razor @@ -1,4 +1,4 @@ -@using Foursat.BackOffice.BFF.Inventory.Protos +@using CMSMicroservice.Protobuf.Protos.Inventory @@ -72,7 +72,7 @@ @code { [CascadingParameter] IMudDialogInstance MudDialog { get; set; } = default!; - [Inject] public InventoryBFFContract.InventoryBFFContractClient InventoryContract { get; set; } = default!; + [Inject] public InventoryContract.InventoryContractClient InventoryContract { get; set; } = default!; [Parameter] public InventoryItemDto Item { get; set; } = default!; diff --git a/src/BackOffice/Pages/Inventory/InventoryMainPage.razor b/src/BackOffice/Pages/Inventory/InventoryMainPage.razor index b9f2b8f..1d85053 100644 --- a/src/BackOffice/Pages/Inventory/InventoryMainPage.razor +++ b/src/BackOffice/Pages/Inventory/InventoryMainPage.razor @@ -1,7 +1,7 @@ @attribute [Route(RouteConstance.Inventory)] @attribute [Authorize] -@using Foursat.BackOffice.BFF.Inventory.Protos +@using CMSMicroservice.Protobuf.Protos.Inventory @using BackOffice.Pages.Inventory.Components diff --git a/src/BackOffice/Pages/Inventory/InventoryMainPage.razor.cs b/src/BackOffice/Pages/Inventory/InventoryMainPage.razor.cs index e9b6414..8a40454 100644 --- a/src/BackOffice/Pages/Inventory/InventoryMainPage.razor.cs +++ b/src/BackOffice/Pages/Inventory/InventoryMainPage.razor.cs @@ -1,7 +1,7 @@ using Microsoft.AspNetCore.Components; using MudBlazor; using Google.Protobuf.WellKnownTypes; -using Foursat.BackOffice.BFF.Inventory.Protos; +using CMSMicroservice.Protobuf.Protos.Inventory; using BackOffice.Pages.Inventory.Components; using BackOffice.Common.Utilities; @@ -9,7 +9,7 @@ namespace BackOffice.Pages.Inventory; public partial class InventoryMainPage { - [Inject] public InventoryBFFContract.InventoryBFFContractClient InventoryContract { get; set; } = default!; + [Inject] public InventoryContract.InventoryContractClient InventoryContract { get; set; } = default!; private MudDataGrid? _gridData; private List _warehouses = new(); diff --git a/src/BackOffice/Pages/Inventory/LowStockPage.razor b/src/BackOffice/Pages/Inventory/LowStockPage.razor index 2540f2c..f9334de 100644 --- a/src/BackOffice/Pages/Inventory/LowStockPage.razor +++ b/src/BackOffice/Pages/Inventory/LowStockPage.razor @@ -1,7 +1,7 @@ @attribute [Route(RouteConstance.InventoryLowStock)] @attribute [Authorize] -@using Foursat.BackOffice.BFF.Inventory.Protos +@using CMSMicroservice.Protobuf.Protos.Inventory diff --git a/src/BackOffice/Pages/Inventory/LowStockPage.razor.cs b/src/BackOffice/Pages/Inventory/LowStockPage.razor.cs index 0dfa1d6..7c98d4a 100644 --- a/src/BackOffice/Pages/Inventory/LowStockPage.razor.cs +++ b/src/BackOffice/Pages/Inventory/LowStockPage.razor.cs @@ -1,6 +1,6 @@ using Microsoft.AspNetCore.Components; using MudBlazor; -using Foursat.BackOffice.BFF.Inventory.Protos; +using CMSMicroservice.Protobuf.Protos.Inventory; using BackOffice.Pages.Inventory.Components; using BackOffice.Common.Utilities; @@ -8,7 +8,7 @@ namespace BackOffice.Pages.Inventory; public partial class LowStockPage { - [Inject] public InventoryBFFContract.InventoryBFFContractClient InventoryContract { get; set; } = default!; + [Inject] public InventoryContract.InventoryContractClient InventoryContract { get; set; } = default!; private List _items = new(); private List _warehouses = new(); diff --git a/src/BackOffice/Pages/Inventory/MovementsPage.razor b/src/BackOffice/Pages/Inventory/MovementsPage.razor index 5cae4ae..b5b5212 100644 --- a/src/BackOffice/Pages/Inventory/MovementsPage.razor +++ b/src/BackOffice/Pages/Inventory/MovementsPage.razor @@ -1,7 +1,7 @@ @attribute [Route(RouteConstance.InventoryMovements)] @attribute [Authorize] -@using Foursat.BackOffice.BFF.Inventory.Protos +@using CMSMicroservice.Protobuf.Protos.Inventory @using Google.Protobuf.WellKnownTypes diff --git a/src/BackOffice/Pages/Inventory/MovementsPage.razor.cs b/src/BackOffice/Pages/Inventory/MovementsPage.razor.cs index dd2f6a6..dd6a3eb 100644 --- a/src/BackOffice/Pages/Inventory/MovementsPage.razor.cs +++ b/src/BackOffice/Pages/Inventory/MovementsPage.razor.cs @@ -1,14 +1,14 @@ using Microsoft.AspNetCore.Components; using MudBlazor; using Google.Protobuf.WellKnownTypes; -using Foursat.BackOffice.BFF.Inventory.Protos; +using CMSMicroservice.Protobuf.Protos.Inventory; using BackOffice.Common.Utilities; namespace BackOffice.Pages.Inventory; public partial class MovementsPage { - [Inject] public InventoryBFFContract.InventoryBFFContractClient InventoryContract { get; set; } = default!; + [Inject] public InventoryContract.InventoryContractClient InventoryContract { get; set; } = default!; [SupplyParameterFromQuery(Name = "itemId")] public long? ItemId { get; set; } diff --git a/src/BackOffice/Pages/Inventory/WarehousesPage.razor b/src/BackOffice/Pages/Inventory/WarehousesPage.razor index 0da858c..b2e0b1f 100644 --- a/src/BackOffice/Pages/Inventory/WarehousesPage.razor +++ b/src/BackOffice/Pages/Inventory/WarehousesPage.razor @@ -1,7 +1,7 @@ @attribute [Route(RouteConstance.InventoryWarehouses)] @attribute [Authorize] -@using Foursat.BackOffice.BFF.Inventory.Protos +@using CMSMicroservice.Protobuf.Protos.Inventory @using BackOffice.Pages.Inventory.Components diff --git a/src/BackOffice/Pages/Inventory/WarehousesPage.razor.cs b/src/BackOffice/Pages/Inventory/WarehousesPage.razor.cs index 42a43f4..d44e385 100644 --- a/src/BackOffice/Pages/Inventory/WarehousesPage.razor.cs +++ b/src/BackOffice/Pages/Inventory/WarehousesPage.razor.cs @@ -1,6 +1,6 @@ using Microsoft.AspNetCore.Components; using MudBlazor; -using Foursat.BackOffice.BFF.Inventory.Protos; +using CMSMicroservice.Protobuf.Protos.Inventory; using BackOffice.Pages.Inventory.Components; using BackOffice.Common.Utilities; @@ -8,7 +8,7 @@ namespace BackOffice.Pages.Inventory; public partial class WarehousesPage { - [Inject] public InventoryBFFContract.InventoryBFFContractClient InventoryContract { get; set; } = default!; + [Inject] public InventoryContract.InventoryContractClient InventoryContract { get; set; } = default!; private List _warehouses = new(); private bool _isLoading = true; diff --git a/src/BackOffice/Pages/Login/LoginPage.razor.cs b/src/BackOffice/Pages/Login/LoginPage.razor.cs index d796916..9adf0ce 100644 --- a/src/BackOffice/Pages/Login/LoginPage.razor.cs +++ b/src/BackOffice/Pages/Login/LoginPage.razor.cs @@ -1,5 +1,5 @@ -using BackOffice.BFF.Otp.Protobuf.Protos.Otp; -using BackOffice.BFF.Otp.Protobuf.Validator; +using CMSMicroservice.Protobuf.Protos.OtpToken; +using CMSMicroservice.Protobuf.Validator.OtpToken; using BackOffice.Common.Utilities; using Microsoft.AspNetCore.Components; using MudBlazor; @@ -8,11 +8,11 @@ namespace BackOffice.Pages.Login; public partial class LoginPage { private bool _isLoading; - private SendOtpRequest _request = new(); - private SendOtpRequestValidator _requestValidator = new(); + private CreateNewOtpTokenRequest _request = new() { Purpose = "login" }; + private CreateNewOtpTokenRequestValidator _requestValidator = new(); private MudForm _form; - [Inject] public OtpContract.OtpContractClient OtpContract { get; set; } + [Inject] public OtpTokenContract.OtpTokenContractClient OtpContract { get; set; } private async Task OnSubmitClick() { await _form.Validate(); @@ -25,7 +25,7 @@ public partial class LoginPage _request.Mobile = _request.Mobile.PersianToEnglish(); try { - await OtpContract.SendOtpAsync(_request); + await OtpContract.CreateNewOtpTokenAsync(_request); Navigation.NavigateTo(RouteConstance.VerifyCodePage + _request.Mobile); } catch (Exception ex) diff --git a/src/BackOffice/Pages/Login/VerifyCodePage.razor.cs b/src/BackOffice/Pages/Login/VerifyCodePage.razor.cs index 975d015..544713a 100644 --- a/src/BackOffice/Pages/Login/VerifyCodePage.razor.cs +++ b/src/BackOffice/Pages/Login/VerifyCodePage.razor.cs @@ -1,9 +1,13 @@ -using BackOffice.BFF.Otp.Protobuf.Protos.Otp; -using BackOffice.BFF.Otp.Protobuf.Validator; +using CMSMicroservice.Protobuf.Protos.OtpToken; +using CMSMicroservice.Protobuf.Protos.User; +using CMSMicroservice.Protobuf.Validator.User; using BackOffice.Common.Utilities; using Blazored.LocalStorage; using Microsoft.AspNetCore.Components; using MudBlazor; +using VerifyOtpTokenRequest = CMSMicroservice.Protobuf.Protos.User.VerifyOtpTokenRequest; +using CreateNewOtpTokenRequest = CMSMicroservice.Protobuf.Protos.OtpToken.CreateNewOtpTokenRequest; +using VerifyOtpTokenRequestValidator = CMSMicroservice.Protobuf.Validator.User.VerifyOtpTokenRequestValidator; namespace BackOffice.Pages.Login; public partial class VerifyCodePage @@ -12,14 +16,17 @@ public partial class VerifyCodePage public string Mobile { get; set; } private bool _isLoading; - private VerifyOtpCodeRequest _request = new(); - private VerifyOtpCodeRequestValidator _requestValidator = new(); + private VerifyOtpTokenRequest _request = new() { Purpose = "login" }; + private VerifyOtpTokenRequestValidator _requestValidator = new(); private MudForm _form; private Timer _timer; private int _currentCount = 120; [Inject] - public OtpContract.OtpContractClient OtpContract { get; set; } + public UserContract.UserContractClient UserClient { get; set; } + + [Inject] + public OtpTokenContract.OtpTokenContractClient OtpTokenClient { get; set; } protected override void OnInitialized() { @@ -39,9 +46,16 @@ public partial class VerifyCodePage try { - var token = await OtpContract.VerifyOtpCodeAsync(_request); - await LocalStorageService.SetItemAsync(GlobalConstants.JwtTokenKey, token.Token); - Navigation.NavigateTo(RouteConstance.HomePage, forceLoad: true); + var result = await UserClient.VerifyOtpTokenAsync(_request); + if (result.Success && result.Token != null) + { + await LocalStorageService.SetItemAsync(GlobalConstants.JwtTokenKey, result.Token); + Navigation.NavigateTo(RouteConstance.HomePage, forceLoad: true); + } + else + { + Snackbar.Add(message: result.Message, severity: Severity.Error); + } } catch (Exception ex) { @@ -61,9 +75,10 @@ public partial class VerifyCodePage try { - await OtpContract.SendOtpAsync(request: new() + await OtpTokenClient.CreateNewOtpTokenAsync(new CreateNewOtpTokenRequest { - Mobile = Mobile + Mobile = Mobile, + Purpose = "login" }); StartTimer(); } diff --git a/src/BackOffice/Pages/Network/BalancesReport.razor b/src/BackOffice/Pages/Network/BalancesReport.razor index 6c63719..a042659 100644 --- a/src/BackOffice/Pages/Network/BalancesReport.razor +++ b/src/BackOffice/Pages/Network/BalancesReport.razor @@ -2,7 +2,7 @@ @using BackOffice.Pages.AutoComplete @using MudBlazor -@using Foursat.BackOffice.BFF.Commission.Protos +@using CMSMicroservice.Protobuf.Protos.Commission گزارش موجودی‌های هفتگی diff --git a/src/BackOffice/Pages/Network/NetworkTreeViewer.razor b/src/BackOffice/Pages/Network/NetworkTreeViewer.razor index 260f2a6..02078a4 100644 --- a/src/BackOffice/Pages/Network/NetworkTreeViewer.razor +++ b/src/BackOffice/Pages/Network/NetworkTreeViewer.razor @@ -3,7 +3,7 @@ @implements IAsyncDisposable @inject IJSRuntime JS -@using Foursat.BackOffice.BFF.NetworkMembership.Protos +@using CMSMicroservice.Protobuf.Protos.NetworkMembership @using BackOffice.Pages.AutoComplete @@ -252,7 +252,7 @@ UserId = _searchUserId.Value, MaxDepth = _selectedDepth, IsClubActive = _clubActiveFilter, - ActivationWeekDefinitionId = _activationWeekFilter + ActivationWeekDefinitionId = _activationWeekFilter?.ToString() }; _treeData = await NetworkContract.GetNetworkTreeAsync(request); @@ -288,7 +288,7 @@ UserId = userId, MaxDepth = _selectedDepth, IsClubActive = _clubActiveFilter, - ActivationWeekDefinitionId = _activationWeekFilter + ActivationWeekDefinitionId = _activationWeekFilter?.ToString() }; _treeData = await NetworkContract.GetNetworkTreeAsync(request); diff --git a/src/BackOffice/Pages/Network/Statistics.razor b/src/BackOffice/Pages/Network/Statistics.razor index a29c462..91a6c2a 100644 --- a/src/BackOffice/Pages/Network/Statistics.razor +++ b/src/BackOffice/Pages/Network/Statistics.razor @@ -1,6 +1,6 @@ @page "/network/statistics" -@using Foursat.BackOffice.BFF.NetworkMembership.Protos +@using CMSMicroservice.Protobuf.Protos.NetworkMembership @using MudBlazor diff --git a/src/BackOffice/Pages/Network/UserNetworkInfo.razor b/src/BackOffice/Pages/Network/UserNetworkInfo.razor index e8c4357..74abb7a 100644 --- a/src/BackOffice/Pages/Network/UserNetworkInfo.razor +++ b/src/BackOffice/Pages/Network/UserNetworkInfo.razor @@ -1,5 +1,5 @@ @page "/network/user-info/{UserId:long}" -@using Foursat.BackOffice.BFF.NetworkMembership.Protos +@using CMSMicroservice.Protobuf.Protos.NetworkMembership @attribute [Authorize] diff --git a/src/BackOffice/Pages/Package/Components/CreateDialog.razor b/src/BackOffice/Pages/Package/Components/CreateDialog.razor index 852a839..498bc94 100644 --- a/src/BackOffice/Pages/Package/Components/CreateDialog.razor +++ b/src/BackOffice/Pages/Package/Components/CreateDialog.razor @@ -1,4 +1,4 @@ -@using BackOffice.BFF.Package.Protobuf.Protos.Package +@using CMSMicroservice.Protobuf.Protos.Package @using BackOffice.Common.BaseComponents @using Microsoft.AspNetCore.Components.Forms @using Tizzani.MudBlazor.HtmlEditor diff --git a/src/BackOffice/Pages/Package/Components/CreateDialog.razor.cs b/src/BackOffice/Pages/Package/Components/CreateDialog.razor.cs index 6a5a847..bf0a2e9 100644 --- a/src/BackOffice/Pages/Package/Components/CreateDialog.razor.cs +++ b/src/BackOffice/Pages/Package/Components/CreateDialog.razor.cs @@ -1,4 +1,4 @@ -using BackOffice.BFF.Package.Protobuf.Protos.Package; +using CMSMicroservice.Protobuf.Protos.Package; using Google.Protobuf; using Grpc.Core; using Microsoft.AspNetCore.Components; diff --git a/src/BackOffice/Pages/Package/Components/UpdateDialog.razor b/src/BackOffice/Pages/Package/Components/UpdateDialog.razor index a7661d1..fee58f4 100644 --- a/src/BackOffice/Pages/Package/Components/UpdateDialog.razor +++ b/src/BackOffice/Pages/Package/Components/UpdateDialog.razor @@ -1,4 +1,4 @@ -@using BackOffice.BFF.Package.Protobuf.Protos.Package +@using CMSMicroservice.Protobuf.Protos.Package @using BackOffice.Common.BaseComponents @using Microsoft.AspNetCore.Components.Forms @using Tizzani.MudBlazor.HtmlEditor diff --git a/src/BackOffice/Pages/Package/Components/UpdateDialog.razor.cs b/src/BackOffice/Pages/Package/Components/UpdateDialog.razor.cs index 464d7d0..77d0ffa 100644 --- a/src/BackOffice/Pages/Package/Components/UpdateDialog.razor.cs +++ b/src/BackOffice/Pages/Package/Components/UpdateDialog.razor.cs @@ -1,4 +1,4 @@ -using BackOffice.BFF.Package.Protobuf.Protos.Package; +using CMSMicroservice.Protobuf.Protos.Package; using Google.Protobuf; using Microsoft.AspNetCore.Components; using Microsoft.AspNetCore.Components.Forms; diff --git a/src/BackOffice/Pages/Package/PackageMainPage.razor b/src/BackOffice/Pages/Package/PackageMainPage.razor index ea3741c..0aaf2fc 100644 --- a/src/BackOffice/Pages/Package/PackageMainPage.razor +++ b/src/BackOffice/Pages/Package/PackageMainPage.razor @@ -1,9 +1,9 @@ @attribute [Route(RouteConstance.Package)] -@using BackOffice.BFF.Package.Protobuf.Protos.Package +@using CMSMicroservice.Protobuf.Protos.Package @using BackOffice.Pages.Package.Components @using BackOffice.Common.BaseComponents -@using DataModel = BackOffice.BFF.Package.Protobuf.Protos.Package.GetAllPackageByFilterResponseModel +@using DataModel = CMSMicroservice.Protobuf.Protos.Package.GetAllPackageByFilterResponseModel diff --git a/src/BackOffice/Pages/Package/PackageMainPage.razor.cs b/src/BackOffice/Pages/Package/PackageMainPage.razor.cs index 05496db..026d4d1 100644 --- a/src/BackOffice/Pages/Package/PackageMainPage.razor.cs +++ b/src/BackOffice/Pages/Package/PackageMainPage.razor.cs @@ -1,10 +1,10 @@ -using BackOffice.BFF.Package.Protobuf.Protos.Package; +using CMSMicroservice.Protobuf.Protos.Package; using BackOffice.Common.BaseComponents; using BackOffice.Pages.Package.Components; using Mapster; using Microsoft.AspNetCore.Components; using MudBlazor; -using DataModel = BackOffice.BFF.Package.Protobuf.Protos.Package.GetAllPackageByFilterResponseModel; +using DataModel = CMSMicroservice.Protobuf.Protos.Package.GetAllPackageByFilterResponseModel; namespace BackOffice.Pages.Package; public partial class PackageMainPage diff --git a/src/BackOffice/Pages/Payment/Components/ManualPaymentDialog.razor b/src/BackOffice/Pages/Payment/Components/ManualPaymentDialog.razor index 6ab6a03..7613fa6 100644 --- a/src/BackOffice/Pages/Payment/Components/ManualPaymentDialog.razor +++ b/src/BackOffice/Pages/Payment/Components/ManualPaymentDialog.razor @@ -1,4 +1,4 @@ -@using BackOffice.BFF.ManualPayment.Protobuf +@using CMSMicroservice.Protobuf.Protos.ManualPayment @using BackOffice.Pages.Payment.Components @using BackOffice.Pages.AutoComplete @using Microsoft.AspNetCore.Components.Forms diff --git a/src/BackOffice/Pages/Payment/Components/ManualPaymentDialog.razor.cs b/src/BackOffice/Pages/Payment/Components/ManualPaymentDialog.razor.cs index b90b4c2..4803467 100644 --- a/src/BackOffice/Pages/Payment/Components/ManualPaymentDialog.razor.cs +++ b/src/BackOffice/Pages/Payment/Components/ManualPaymentDialog.razor.cs @@ -1,4 +1,4 @@ -using BackOffice.BFF.ManualPayment.Protobuf; +using CMSMicroservice.Protobuf.Protos.ManualPayment; using Google.Protobuf; using Microsoft.AspNetCore.Components; using Microsoft.AspNetCore.Components.Forms; @@ -102,7 +102,7 @@ public partial class ManualPaymentDialog { UserId = _selectedUserId.Value, Amount = _createModel.Amount, - Type = _selectedType, + Type = (ManualPaymentType)_selectedType, Description = _description }; diff --git a/src/BackOffice/Pages/Payment/ManualPayments.razor b/src/BackOffice/Pages/Payment/ManualPayments.razor index d5ad02f..1f72691 100644 --- a/src/BackOffice/Pages/Payment/ManualPayments.razor +++ b/src/BackOffice/Pages/Payment/ManualPayments.razor @@ -1,5 +1,5 @@ @page "/payment/manual-payments" -@using BackOffice.BFF.ManualPayment.Protobuf +@using CMSMicroservice.Protobuf.Protos.ManualPayment @using BackOffice.Pages.Payment.Components @using BackOffice.Common.BaseComponents @using BackOffice.Pages.AutoComplete @@ -69,15 +69,15 @@ - @GetTypeText(context.Item.Type) + @GetTypeText((int)context.Item.Type) - @GetStatusText(context.Item.Status) + Color="@GetStatusColor((int)context.Item.Status)"> + @GetStatusText((int)context.Item.Status) @@ -103,7 +103,7 @@ @code { - [Inject] public BackOffice.BFF.ManualPayment.Protobuf.ManualPaymentContract.ManualPaymentContractClient ManualPaymentClient { get; set; } = default!; + [Inject] public CMSMicroservice.Protobuf.Protos.ManualPayment.ManualPaymentContract.ManualPaymentContractClient ManualPaymentClient { get; set; } = default!; // DialogService is injected via _Imports.razor private BasePageComponent? _basePage; @@ -118,7 +118,7 @@ var pageNumber = state.Page + 1; var pageSize = state.PageSize; - var request = new GetManualPaymentsRequest + var request = new GetAllManualPaymentsRequest { PageNumber = pageNumber, PageSize = pageSize @@ -139,12 +139,7 @@ request.Type = _typeFilter.Value; } - if (!string.IsNullOrWhiteSpace(_referenceFilter)) - { - request.ReferenceNumber = _referenceFilter; - } - - var response = await ManualPaymentClient.GetManualPaymentsAsync(request); + var response = await ManualPaymentClient.GetAllManualPaymentsAsync(request); return new GridData { diff --git a/src/BackOffice/Pages/Products/BulkEdit.razor b/src/BackOffice/Pages/Products/BulkEdit.razor index 2a820af..d39b867 100644 --- a/src/BackOffice/Pages/Products/BulkEdit.razor +++ b/src/BackOffice/Pages/Products/BulkEdit.razor @@ -1,8 +1,8 @@ @attribute [Route(RouteConstance.ProductsBulkEdit)] -@using BackOffice.BFF.Products.Protobuf.Protos.Products +@using CMSMicroservice.Protobuf.Protos.Products @using BackOffice.Common.BaseComponents -@using DataModel = BackOffice.BFF.Products.Protobuf.Protos.Products.GetAllProductsByFilterResponseModel +@using DataModel = CMSMicroservice.Protobuf.Protos.Products.GetAllProductsByFilterResponseModel diff --git a/src/BackOffice/Pages/Products/ProductsMainPage.razor.cs b/src/BackOffice/Pages/Products/ProductsMainPage.razor.cs index 0d11997..6790636 100644 --- a/src/BackOffice/Pages/Products/ProductsMainPage.razor.cs +++ b/src/BackOffice/Pages/Products/ProductsMainPage.razor.cs @@ -1,5 +1,5 @@ -using BackOffice.BFF.Products.Protobuf.Protos.Products; -using BackOffice.BFF.Protobuf.Common; +using CMSMicroservice.Protobuf.Protos.Products; +using CMSMicroservice.Protobuf.Protos; using BackOffice.Common.BaseComponents; using BackOffice.Common.Utilities; using BackOffice.Pages.Tag.Components; @@ -9,7 +9,7 @@ using Microsoft.AspNetCore.Components; using Microsoft.JSInterop; using MudBlazor; using System.Text; -using DataModel = BackOffice.BFF.Products.Protobuf.Protos.Products.GetAllProductsByFilterResponseModel; +using DataModel = CMSMicroservice.Protobuf.Protos.Products.GetAllProductsByFilterResponseModel; namespace BackOffice.Pages.Products; diff --git a/src/BackOffice/Pages/Role/Components/CreateDialog.razor b/src/BackOffice/Pages/Role/Components/CreateDialog.razor index 98ba619..b4c6bff 100644 --- a/src/BackOffice/Pages/Role/Components/CreateDialog.razor +++ b/src/BackOffice/Pages/Role/Components/CreateDialog.razor @@ -1,4 +1,4 @@ -@using BackOffice.BFF.Package.Protobuf.Protos.Package +@using CMSMicroservice.Protobuf.Protos.Package @using BackOffice.Common.BaseComponents @using Microsoft.AspNetCore.Components.Forms @using Tizzani.MudBlazor.HtmlEditor diff --git a/src/BackOffice/Pages/Role/Components/CreateDialog.razor.cs b/src/BackOffice/Pages/Role/Components/CreateDialog.razor.cs index 2c0c776..ee285ab 100644 --- a/src/BackOffice/Pages/Role/Components/CreateDialog.razor.cs +++ b/src/BackOffice/Pages/Role/Components/CreateDialog.razor.cs @@ -1,4 +1,4 @@ -using BackOffice.BFF.Role.Protobuf.Protos.Role; +using CMSMicroservice.Protobuf.Protos.Role; using Google.Protobuf; using Grpc.Core; using Microsoft.AspNetCore.Components; diff --git a/src/BackOffice/Pages/Role/Components/UpdateDialog.razor b/src/BackOffice/Pages/Role/Components/UpdateDialog.razor index 2e71175..1fc865e 100644 --- a/src/BackOffice/Pages/Role/Components/UpdateDialog.razor +++ b/src/BackOffice/Pages/Role/Components/UpdateDialog.razor @@ -1,4 +1,4 @@ -@using BackOffice.BFF.Package.Protobuf.Protos.Package +@using CMSMicroservice.Protobuf.Protos.Package @using BackOffice.Common.BaseComponents @using Microsoft.AspNetCore.Components.Forms @using Tizzani.MudBlazor.HtmlEditor diff --git a/src/BackOffice/Pages/Role/Components/UpdateDialog.razor.cs b/src/BackOffice/Pages/Role/Components/UpdateDialog.razor.cs index 82236e0..e1d75b9 100644 --- a/src/BackOffice/Pages/Role/Components/UpdateDialog.razor.cs +++ b/src/BackOffice/Pages/Role/Components/UpdateDialog.razor.cs @@ -1,4 +1,4 @@ -using BackOffice.BFF.Role.Protobuf.Protos.Role; +using CMSMicroservice.Protobuf.Protos.Role; using Google.Protobuf; using Microsoft.AspNetCore.Components; using Microsoft.AspNetCore.Components.Forms; diff --git a/src/BackOffice/Pages/Role/RoleMainPage.razor b/src/BackOffice/Pages/Role/RoleMainPage.razor index 8e2a2d6..265f056 100644 --- a/src/BackOffice/Pages/Role/RoleMainPage.razor +++ b/src/BackOffice/Pages/Role/RoleMainPage.razor @@ -1,9 +1,9 @@ @attribute [Route(RouteConstance.Role)] -@using BackOffice.BFF.Role.Protobuf.Protos.Role +@using CMSMicroservice.Protobuf.Protos.Role @using BackOffice.Pages.Role.Components @using BackOffice.Common.BaseComponents -@using DataModel = BackOffice.BFF.Role.Protobuf.Protos.Role.GetAllRoleByFilterResponseModel +@using DataModel = CMSMicroservice.Protobuf.Protos.Role.GetAllRoleByFilterResponseModel diff --git a/src/BackOffice/Pages/Role/RoleMainPage.razor.cs b/src/BackOffice/Pages/Role/RoleMainPage.razor.cs index efde8cb..5175697 100644 --- a/src/BackOffice/Pages/Role/RoleMainPage.razor.cs +++ b/src/BackOffice/Pages/Role/RoleMainPage.razor.cs @@ -1,10 +1,10 @@ -using BackOffice.BFF.Role.Protobuf.Protos.Role; +using CMSMicroservice.Protobuf.Protos.Role; using BackOffice.Common.BaseComponents; using BackOffice.Pages.Role.Components; using Mapster; using Microsoft.AspNetCore.Components; using MudBlazor; -using DataModel = BackOffice.BFF.Role.Protobuf.Protos.Role.GetAllRoleByFilterResponseModel; +using DataModel = CMSMicroservice.Protobuf.Protos.Role.GetAllRoleByFilterResponseModel; namespace BackOffice.Pages.Role; public partial class RoleMainPage diff --git a/src/BackOffice/Pages/SystemManagement/Configuration.razor b/src/BackOffice/Pages/SystemManagement/Configuration.razor index e1d14be..a109591 100644 --- a/src/BackOffice/Pages/SystemManagement/Configuration.razor +++ b/src/BackOffice/Pages/SystemManagement/Configuration.razor @@ -1,7 +1,8 @@ @page "/system/configuration" @attribute [Authorize(Roles = "Administrator")] -@using Foursat.BackOffice.BFF.Configuration.Protos +@using CMSMicroservice.Protobuf.Protos.Configuration +@using CMSMicroservice.Protobuf.Protos @using MudBlazor @@ -431,8 +432,11 @@ { var request = new GetAllConfigurationsRequest { - PageIndex = 1, - PageSize = 100 + PaginationState = new PaginationState + { + PageNumber = 1, + PageSize = 100 + } }; var response = await ConfigurationClient.GetAllConfigurationsAsync(request); diff --git a/src/BackOffice/Pages/SystemManagement/HealthDashboard.razor b/src/BackOffice/Pages/SystemManagement/HealthDashboard.razor index c82f771..bfe0188 100644 --- a/src/BackOffice/Pages/SystemManagement/HealthDashboard.razor +++ b/src/BackOffice/Pages/SystemManagement/HealthDashboard.razor @@ -1,7 +1,8 @@ @page "/system/health" @attribute [Authorize] -@using Foursat.BackOffice.BFF.Health.Protobuf +@using CMSMicroservice.Protobuf.Protos.Health +@using Google.Protobuf.WellKnownTypes @using MudBlazor @inject HealthContract.HealthContractClient HealthClient @@ -234,8 +235,8 @@ { try { - var request = new GetSystemHealthRequest(); - var response = await HealthClient.GetSystemHealthAsync(request); + // CMS proto uses google.protobuf.Empty instead of GetSystemHealthRequest + var response = await HealthClient.GetSystemHealthAsync(new Empty()); _overallStatus = response.OverallHealthy ? "Healthy" : "Unhealthy"; _lastUpdated = DateTime.Now; @@ -245,11 +246,11 @@ { Name = s.ServiceName, Type = GetServiceType(s.ServiceName), - Status = s.Status, + Status = s.Status.ToString(), Uptime = "99.9%", // Mock - not in API ResponseTime = (int)s.ResponseTimeMs, Version = "1.0.0", // Mock - not in API - LastError = s.Status != "Healthy" ? s.Description : null + LastError = s.Status != HealthStatus.Healthy ? s.Description : null }).ToList(); // Keep mock events for now diff --git a/src/BackOffice/Pages/SystemManagement/WorkerControl.razor b/src/BackOffice/Pages/SystemManagement/WorkerControl.razor index 59b85c7..00b4a53 100644 --- a/src/BackOffice/Pages/SystemManagement/WorkerControl.razor +++ b/src/BackOffice/Pages/SystemManagement/WorkerControl.razor @@ -177,7 +177,7 @@ @code { - [Inject] public Foursat.BackOffice.BFF.Commission.Protos.CommissionContract.CommissionContractClient CommissionClient { get; set; } + [Inject] public CMSMicroservice.Protobuf.Protos.Commission.CommissionContract.CommissionContractClient CommissionClient { get; set; } [Inject] public BackOffice.Services.IPersianDateTimeService PersianDateTime { get; set; } private WorkerStatus _workerStatus = WorkerStatus.Running; @@ -194,7 +194,7 @@ { try { - var statusResponse = await CommissionClient.GetWorkerStatusAsync(new Foursat.BackOffice.BFF.Commission.Protos.GetWorkerStatusRequest()); + var statusResponse = await CommissionClient.GetWorkerStatusAsync(new CMSMicroservice.Protobuf.Protos.Commission.GetWorkerStatusRequest()); _workerStatus = statusResponse.IsRunning ? WorkerStatus.Running : WorkerStatus.Paused; _lastRunTime = statusResponse.LastRunAt?.ToDateTime() ?? DateTime.MinValue; _nextRunTime = statusResponse.NextScheduledRun?.ToDateTime() ?? DateTime.MinValue; @@ -228,7 +228,7 @@ _isProcessing = true; try { - var request = new Foursat.BackOffice.BFF.Commission.Protos.TriggerWeeklyCalculationRequest + var request = new CMSMicroservice.Protobuf.Protos.Commission.TriggerWeeklyCalculationRequest { WeekDefinitionId = _manualWeekDefinitionId.Value }; @@ -275,7 +275,7 @@ { try { - var request = new Foursat.BackOffice.BFF.Commission.Protos.GetWorkerExecutionLogsRequest + var request = new CMSMicroservice.Protobuf.Protos.Commission.GetWorkerExecutionLogsRequest { PageIndex = 1, PageSize = 20 diff --git a/src/BackOffice/Pages/User/Components/UserRoleDialog.razor b/src/BackOffice/Pages/User/Components/UserRoleDialog.razor index 12a873b..e0b994f 100644 --- a/src/BackOffice/Pages/User/Components/UserRoleDialog.razor +++ b/src/BackOffice/Pages/User/Components/UserRoleDialog.razor @@ -1,4 +1,4 @@ -@using BackOffice.BFF.Role.Protobuf.Protos.Role +@using CMSMicroservice.Protobuf.Protos.Role @if (_isFirstLoad) diff --git a/src/BackOffice/Pages/User/Components/UserRoleDialog.razor.cs b/src/BackOffice/Pages/User/Components/UserRoleDialog.razor.cs index 7fc56cf..1f178ea 100644 --- a/src/BackOffice/Pages/User/Components/UserRoleDialog.razor.cs +++ b/src/BackOffice/Pages/User/Components/UserRoleDialog.razor.cs @@ -1,8 +1,8 @@ -using BackOffice.BFF.Role.Protobuf.Protos.Role; +using CMSMicroservice.Protobuf.Protos.Role; using Microsoft.AspNetCore.Components; using MudBlazor; -using BackOffice.BFF.User.Protobuf.Protos.User; -using BackOffice.BFF.UserRole.Protobuf.Protos.UserRole; +using CMSMicroservice.Protobuf.Protos.User; +using CMSMicroservice.Protobuf.Protos.UserRole; namespace BackOffice.Pages.User.Components; public partial class UserRoleDialog diff --git a/src/BackOffice/Pages/User/UserMainPage.razor b/src/BackOffice/Pages/User/UserMainPage.razor index a45be61..8f60b07 100644 --- a/src/BackOffice/Pages/User/UserMainPage.razor +++ b/src/BackOffice/Pages/User/UserMainPage.razor @@ -1,9 +1,9 @@ @attribute [Route(RouteConstance.UserPage)] -@using BackOffice.BFF.User.Protobuf.Protos.User +@using CMSMicroservice.Protobuf.Protos.User @using BackOffice.Pages.User.Components @using BackOffice.Common.BaseComponents -@using DataModel = BackOffice.BFF.User.Protobuf.Protos.User.GetAllUserByFilterResponseModel +@using DataModel = CMSMicroservice.Protobuf.Protos.User.GetAllUserByFilterResponseModel diff --git a/src/BackOffice/Pages/User/UserMainPage.razor.cs b/src/BackOffice/Pages/User/UserMainPage.razor.cs index 53ec385..e536a14 100644 --- a/src/BackOffice/Pages/User/UserMainPage.razor.cs +++ b/src/BackOffice/Pages/User/UserMainPage.razor.cs @@ -1,9 +1,9 @@ -using BackOffice.BFF.User.Protobuf.Protos.User; +using CMSMicroservice.Protobuf.Protos.User; using BackOffice.Common.BaseComponents; using BackOffice.Pages.User.Components; using Microsoft.AspNetCore.Components; using MudBlazor; -using DataModel = BackOffice.BFF.User.Protobuf.Protos.User.GetAllUserByFilterResponseModel; +using DataModel = CMSMicroservice.Protobuf.Protos.User.GetAllUserByFilterResponseModel; namespace BackOffice.Pages.User; public partial class UserMainPage diff --git a/src/BackOffice/Pages/UserAddress/Components/CreateDialog.razor b/src/BackOffice/Pages/UserAddress/Components/CreateDialog.razor index 92b57d0..2fc4e2e 100644 --- a/src/BackOffice/Pages/UserAddress/Components/CreateDialog.razor +++ b/src/BackOffice/Pages/UserAddress/Components/CreateDialog.razor @@ -1,4 +1,4 @@ -@using BackOffice.BFF.UserAddress.Protobuf.Protos.UserAddress +@using CMSMicroservice.Protobuf.Protos.UserAddress @using BackOffice.Common.BaseComponents @using Microsoft.AspNetCore.Components.Forms @using Tizzani.MudBlazor.HtmlEditor diff --git a/src/BackOffice/Pages/UserAddress/Components/CreateDialog.razor.cs b/src/BackOffice/Pages/UserAddress/Components/CreateDialog.razor.cs index ae95782..68194bd 100644 --- a/src/BackOffice/Pages/UserAddress/Components/CreateDialog.razor.cs +++ b/src/BackOffice/Pages/UserAddress/Components/CreateDialog.razor.cs @@ -1,4 +1,4 @@ -using BackOffice.BFF.UserAddress.Protobuf.Protos.UserAddress; +using CMSMicroservice.Protobuf.Protos.UserAddress; using Google.Protobuf; using Grpc.Core; using Microsoft.AspNetCore.Components; diff --git a/src/BackOffice/Pages/UserAddress/Components/UpdateDialog.razor b/src/BackOffice/Pages/UserAddress/Components/UpdateDialog.razor index 23a5251..53d1b3d 100644 --- a/src/BackOffice/Pages/UserAddress/Components/UpdateDialog.razor +++ b/src/BackOffice/Pages/UserAddress/Components/UpdateDialog.razor @@ -1,4 +1,4 @@ -@using BackOffice.BFF.UserAddress.Protobuf.Protos.UserAddress +@using CMSMicroservice.Protobuf.Protos.UserAddress @using BackOffice.Common.BaseComponents @using Microsoft.AspNetCore.Components.Forms @using Tizzani.MudBlazor.HtmlEditor diff --git a/src/BackOffice/Pages/UserAddress/Components/UpdateDialog.razor.cs b/src/BackOffice/Pages/UserAddress/Components/UpdateDialog.razor.cs index 0c884a4..d0ce278 100644 --- a/src/BackOffice/Pages/UserAddress/Components/UpdateDialog.razor.cs +++ b/src/BackOffice/Pages/UserAddress/Components/UpdateDialog.razor.cs @@ -1,4 +1,4 @@ -using BackOffice.BFF.UserAddress.Protobuf.Protos.UserAddress; +using CMSMicroservice.Protobuf.Protos.UserAddress; using Google.Protobuf; using Microsoft.AspNetCore.Components; using Microsoft.AspNetCore.Components.Forms; diff --git a/src/BackOffice/Pages/UserAddress/UserAddressMainPage.razor b/src/BackOffice/Pages/UserAddress/UserAddressMainPage.razor index 2a34c45..f1eb5fd 100644 --- a/src/BackOffice/Pages/UserAddress/UserAddressMainPage.razor +++ b/src/BackOffice/Pages/UserAddress/UserAddressMainPage.razor @@ -1,9 +1,9 @@ @attribute [Route(RouteConstance.UserAddress + "{UserId:long}")] -@using BackOffice.BFF.UserAddress.Protobuf.Protos.UserAddress +@using CMSMicroservice.Protobuf.Protos.UserAddress @using BackOffice.Pages.UserAddress.Components @using BackOffice.Common.BaseComponents -@using DataModel = BackOffice.BFF.UserAddress.Protobuf.Protos.UserAddress.GetAllUserAddressByFilterResponseModel +@using DataModel = CMSMicroservice.Protobuf.Protos.UserAddress.GetAllUserAddressByFilterResponseModel diff --git a/src/BackOffice/Pages/UserAddress/UserAddressMainPage.razor.cs b/src/BackOffice/Pages/UserAddress/UserAddressMainPage.razor.cs index d2e4d53..4d2f439 100644 --- a/src/BackOffice/Pages/UserAddress/UserAddressMainPage.razor.cs +++ b/src/BackOffice/Pages/UserAddress/UserAddressMainPage.razor.cs @@ -1,10 +1,10 @@ -using BackOffice.BFF.UserAddress.Protobuf.Protos.UserAddress; +using CMSMicroservice.Protobuf.Protos.UserAddress; using BackOffice.Common.BaseComponents; using BackOffice.Pages.UserAddress.Components; using Mapster; using Microsoft.AspNetCore.Components; using MudBlazor; -using DataModel = BackOffice.BFF.UserAddress.Protobuf.Protos.UserAddress.GetAllUserAddressByFilterResponseModel; +using DataModel = CMSMicroservice.Protobuf.Protos.UserAddress.GetAllUserAddressByFilterResponseModel; namespace BackOffice.Pages.UserAddress; public partial class UserAddressMainPage diff --git a/src/BackOffice/Pages/UserOrder/Components/ApplyDiscountDialog.razor b/src/BackOffice/Pages/UserOrder/Components/ApplyDiscountDialog.razor index 79e060a..5e5adad 100644 --- a/src/BackOffice/Pages/UserOrder/Components/ApplyDiscountDialog.razor +++ b/src/BackOffice/Pages/UserOrder/Components/ApplyDiscountDialog.razor @@ -1,4 +1,4 @@ -@using BackOffice.BFF.UserOrder.Protobuf.Protos.UserOrder +@using CMSMicroservice.Protobuf.Protos.UserOrder diff --git a/src/BackOffice/Pages/UserOrder/Components/ApplyDiscountDialog.razor.cs b/src/BackOffice/Pages/UserOrder/Components/ApplyDiscountDialog.razor.cs index 31e6c55..adbe803 100644 --- a/src/BackOffice/Pages/UserOrder/Components/ApplyDiscountDialog.razor.cs +++ b/src/BackOffice/Pages/UserOrder/Components/ApplyDiscountDialog.razor.cs @@ -1,4 +1,4 @@ -using BackOffice.BFF.UserOrder.Protobuf.Protos.UserOrder; +using CMSMicroservice.Protobuf.Protos.UserOrder; using Microsoft.AspNetCore.Components; using MudBlazor; diff --git a/src/BackOffice/Pages/UserOrder/Components/CancelOrderDialog.razor b/src/BackOffice/Pages/UserOrder/Components/CancelOrderDialog.razor index 3307cfc..d397352 100644 --- a/src/BackOffice/Pages/UserOrder/Components/CancelOrderDialog.razor +++ b/src/BackOffice/Pages/UserOrder/Components/CancelOrderDialog.razor @@ -1,4 +1,4 @@ -@using BackOffice.BFF.UserOrder.Protobuf.Protos.UserOrder +@using CMSMicroservice.Protobuf.Protos.UserOrder diff --git a/src/BackOffice/Pages/UserOrder/Components/CancelOrderDialog.razor.cs b/src/BackOffice/Pages/UserOrder/Components/CancelOrderDialog.razor.cs index f3e5061..a5df0b7 100644 --- a/src/BackOffice/Pages/UserOrder/Components/CancelOrderDialog.razor.cs +++ b/src/BackOffice/Pages/UserOrder/Components/CancelOrderDialog.razor.cs @@ -1,4 +1,4 @@ -using BackOffice.BFF.UserOrder.Protobuf.Protos.UserOrder; +using CMSMicroservice.Protobuf.Protos.UserOrder; using Microsoft.AspNetCore.Components; using MudBlazor; diff --git a/src/BackOffice/Pages/UserOrder/Components/ChangeOrderStatusDialog.razor b/src/BackOffice/Pages/UserOrder/Components/ChangeOrderStatusDialog.razor index e3c0eb6..1d170ef 100644 --- a/src/BackOffice/Pages/UserOrder/Components/ChangeOrderStatusDialog.razor +++ b/src/BackOffice/Pages/UserOrder/Components/ChangeOrderStatusDialog.razor @@ -1,4 +1,4 @@ -@using BackOffice.BFF.UserOrder.Protobuf.Protos.UserOrder +@using CMSMicroservice.Protobuf.Protos.UserOrder diff --git a/src/BackOffice/Pages/UserOrder/Components/ChangeOrderStatusDialog.razor.cs b/src/BackOffice/Pages/UserOrder/Components/ChangeOrderStatusDialog.razor.cs index 30df047..510919d 100644 --- a/src/BackOffice/Pages/UserOrder/Components/ChangeOrderStatusDialog.razor.cs +++ b/src/BackOffice/Pages/UserOrder/Components/ChangeOrderStatusDialog.razor.cs @@ -1,4 +1,4 @@ -using BackOffice.BFF.UserOrder.Protobuf.Protos.UserOrder; +using CMSMicroservice.Protobuf.Protos.UserOrder; using Microsoft.AspNetCore.Components; using MudBlazor; diff --git a/src/BackOffice/Pages/UserOrder/Components/UserOrderDataTable.razor.cs b/src/BackOffice/Pages/UserOrder/Components/UserOrderDataTable.razor.cs index 24f0639..daddcbf 100644 --- a/src/BackOffice/Pages/UserOrder/Components/UserOrderDataTable.razor.cs +++ b/src/BackOffice/Pages/UserOrder/Components/UserOrderDataTable.razor.cs @@ -1,11 +1,11 @@ -using BackOffice.BFF.UserOrder.Protobuf.Protos.UserOrder; +using CMSMicroservice.Protobuf.Protos.UserOrder; using Google.Protobuf.WellKnownTypes; using HtmlAgilityPack; using Mapster; using Microsoft.AspNetCore.Components; using MudBlazor; using static Google.Rpc.Context.AttributeContext.Types; -using DataModel = BackOffice.BFF.UserOrder.Protobuf.Protos.UserOrder.GetAllUserOrderByFilterResponseModel; +using DataModel = CMSMicroservice.Protobuf.Protos.UserOrder.GetAllUserOrderByFilterResponseModel; namespace BackOffice.Pages.UserOrder.Components; diff --git a/src/BackOffice/Pages/UserOrder/Components/UserOrderDetailsDialog.razor b/src/BackOffice/Pages/UserOrder/Components/UserOrderDetailsDialog.razor index e9cdd8c..5464e1e 100644 --- a/src/BackOffice/Pages/UserOrder/Components/UserOrderDetailsDialog.razor +++ b/src/BackOffice/Pages/UserOrder/Components/UserOrderDetailsDialog.razor @@ -1,4 +1,5 @@ -@using BackOffice.BFF.UserOrder.Protobuf.Protos.UserOrder +@using CMSMicroservice.Protobuf.Protos.UserOrder +@using CMSMicroservice.Protobuf.Protos @using BackOffice.Common.BaseComponents @@ -51,18 +52,18 @@ } - @if (_model.VatAmount > 0) + @if (_model.VatInfo != null && _model.VatInfo.VatAmount > 0) { جزئیات مالیات بر ارزش افزوده - مبلغ کالا (قبل از مالیات): @_model.VatBaseAmount.ToString("N0") تومان + مبلغ کالا (قبل از مالیات): @_model.VatInfo.BaseAmount.ToString("N0") تومان - مالیات (@_model.VatPercentage.ToString("0")٪): @_model.VatAmount.ToString("N0") تومان + مالیات (@(_model.VatInfo.VatRate * 100).ToString("0")٪): @_model.VatInfo.VatAmount.ToString("N0") تومان - مبلغ نهایی (شامل مالیات): @_model.VatTotalAmount.ToString("N0") تومان + مبلغ نهایی (شامل مالیات): @_model.VatInfo.TotalAmount.ToString("N0") تومان } diff --git a/src/BackOffice/Pages/UserOrder/Components/UserOrderDetailsDialog.razor.cs b/src/BackOffice/Pages/UserOrder/Components/UserOrderDetailsDialog.razor.cs index 1314716..a2bbf3e 100644 --- a/src/BackOffice/Pages/UserOrder/Components/UserOrderDetailsDialog.razor.cs +++ b/src/BackOffice/Pages/UserOrder/Components/UserOrderDetailsDialog.razor.cs @@ -1,4 +1,5 @@ -using BackOffice.BFF.UserOrder.Protobuf.Protos.UserOrder; +using CMSMicroservice.Protobuf.Protos; +using CMSMicroservice.Protobuf.Protos.UserOrder; using Microsoft.AspNetCore.Components; using MudBlazor; @@ -169,7 +170,7 @@ public partial class UserOrderDetailsDialog await UserOrderContract.UpdateUserOrderAsync(new UpdateUserOrderRequest { Id = _model.Id, - DeliveryStatus = _deliveryStatusValue, + DeliveryStatus = (DeliveryStatus)_deliveryStatusValue, TrackingCode = _trackingCode ?? string.Empty, DeliveryDescription = _deliveryDescription ?? string.Empty }); diff --git a/src/BackOffice/Pages/UserOrder/UserOrderMainPage.razor b/src/BackOffice/Pages/UserOrder/UserOrderMainPage.razor index 83f3624..372b3a6 100644 --- a/src/BackOffice/Pages/UserOrder/UserOrderMainPage.razor +++ b/src/BackOffice/Pages/UserOrder/UserOrderMainPage.razor @@ -1,11 +1,12 @@ @attribute [Route(RouteConstance.Orders)] @attribute [Route(RouteConstance.UserOrder + "{UserId:long}")] -@using BackOffice.BFF.UserOrder.Protobuf.Protos.UserOrder +@using CMSMicroservice.Protobuf.Protos.UserOrder +@using CMSMicroservice.Protobuf.Protos @using BackOffice.Pages.UserOrder.Components @using BackOffice.Common.BaseComponents @using BackOffice.Pages.AutoComplete -@using DataModel = BackOffice.BFF.UserOrder.Protobuf.Protos.UserOrder.GetAllUserOrderByFilterResponseModel +@using DataModel = CMSMicroservice.Protobuf.Protos.UserOrder.GetAllUserOrderByFilterResponseModel diff --git a/src/BackOffice/Pages/UserOrder/UserOrderMainPage.razor.cs b/src/BackOffice/Pages/UserOrder/UserOrderMainPage.razor.cs index 7a0d890..47ff180 100644 --- a/src/BackOffice/Pages/UserOrder/UserOrderMainPage.razor.cs +++ b/src/BackOffice/Pages/UserOrder/UserOrderMainPage.razor.cs @@ -1,9 +1,10 @@ using System.Text.Json; -using BackOffice.BFF.UserOrder.Protobuf.Protos.UserOrder; +using CMSMicroservice.Protobuf.Protos; +using CMSMicroservice.Protobuf.Protos.UserOrder; using BackOffice.Common.BaseComponents; using Microsoft.AspNetCore.Components; using MudBlazor; -using DataModel = BackOffice.BFF.UserOrder.Protobuf.Protos.UserOrder.GetAllUserOrderByFilterResponseModel; +using DataModel = CMSMicroservice.Protobuf.Protos.UserOrder.GetAllUserOrderByFilterResponseModel; using Google.Protobuf.WellKnownTypes; namespace BackOffice.Pages.UserOrder; @@ -71,29 +72,29 @@ public partial class UserOrderMainPage if (_paymentStatusFilter.HasValue) { - _request.Filter.PaymentStatus = _paymentStatusFilter; + _request.Filter.PaymentStatus = (PaymentStatus)_paymentStatusFilter.Value; } else { - _request.Filter.PaymentStatus = null; + _request.Filter.ClearPaymentStatusItem(); } if (_deliveryStatusFilter.HasValue) { - _request.Filter.DeliveryStatus = _deliveryStatusFilter.Value; + _request.Filter.DeliveryStatus = (DeliveryStatus)_deliveryStatusFilter.Value; } else { - _request.Filter.DeliveryStatus = null; + _request.Filter.ClearDeliveryStatusItem(); } if (_paymentMethodFilter.HasValue) { - _request.Filter.PaymentMethod = _paymentMethodFilter.Value; + _request.Filter.PaymentMethod = (PaymentMethod)_paymentMethodFilter.Value; } else { - _request.Filter.PaymentMethod = null; + _request.Filter.ClearPaymentMethodItem(); } if (_transactionIdFilter.HasValue && _transactionIdFilter.Value > 0) diff --git a/src/BackOffice/Pages/UserRole/Components/CreateDialog.razor b/src/BackOffice/Pages/UserRole/Components/CreateDialog.razor index 6995bdf..9c73a07 100644 --- a/src/BackOffice/Pages/UserRole/Components/CreateDialog.razor +++ b/src/BackOffice/Pages/UserRole/Components/CreateDialog.razor @@ -1,4 +1,4 @@ -@using BackOffice.BFF.UserRole.Protobuf.Protos.UserRole +@using CMSMicroservice.Protobuf.Protos.UserRole @using BackOffice.Common.BaseComponents @using Microsoft.AspNetCore.Components.Forms @using Tizzani.MudBlazor.HtmlEditor diff --git a/src/BackOffice/Pages/UserRole/Components/CreateDialog.razor.cs b/src/BackOffice/Pages/UserRole/Components/CreateDialog.razor.cs index 5b3e918..ea23546 100644 --- a/src/BackOffice/Pages/UserRole/Components/CreateDialog.razor.cs +++ b/src/BackOffice/Pages/UserRole/Components/CreateDialog.razor.cs @@ -1,4 +1,4 @@ -using BackOffice.BFF.UserRole.Protobuf.Protos.UserRole; +using CMSMicroservice.Protobuf.Protos.UserRole; using Google.Protobuf; using Grpc.Core; using Microsoft.AspNetCore.Components; diff --git a/src/BackOffice/Pages/UserRole/Components/RoleTitleColumn.razor.cs b/src/BackOffice/Pages/UserRole/Components/RoleTitleColumn.razor.cs index 5367f89..c9616c0 100644 --- a/src/BackOffice/Pages/UserRole/Components/RoleTitleColumn.razor.cs +++ b/src/BackOffice/Pages/UserRole/Components/RoleTitleColumn.razor.cs @@ -1,4 +1,4 @@ -using BackOffice.BFF.Role.Protobuf.Protos.Role; +using CMSMicroservice.Protobuf.Protos.Role; using Microsoft.AspNetCore.Components; namespace BackOffice.Pages.UserRole.Components; diff --git a/src/BackOffice/Pages/UserRole/Components/UpdateDialog.razor b/src/BackOffice/Pages/UserRole/Components/UpdateDialog.razor index 103001c..6556f9f 100644 --- a/src/BackOffice/Pages/UserRole/Components/UpdateDialog.razor +++ b/src/BackOffice/Pages/UserRole/Components/UpdateDialog.razor @@ -1,4 +1,4 @@ -@using BackOffice.BFF.UserRole.Protobuf.Protos.UserRole +@using CMSMicroservice.Protobuf.Protos.UserRole @using BackOffice.Common.BaseComponents @using Microsoft.AspNetCore.Components.Forms @using Tizzani.MudBlazor.HtmlEditor diff --git a/src/BackOffice/Pages/UserRole/Components/UpdateDialog.razor.cs b/src/BackOffice/Pages/UserRole/Components/UpdateDialog.razor.cs index 9b40628..addfb25 100644 --- a/src/BackOffice/Pages/UserRole/Components/UpdateDialog.razor.cs +++ b/src/BackOffice/Pages/UserRole/Components/UpdateDialog.razor.cs @@ -1,4 +1,4 @@ -using BackOffice.BFF.UserRole.Protobuf.Protos.UserRole; +using CMSMicroservice.Protobuf.Protos.UserRole; using Google.Protobuf; using Microsoft.AspNetCore.Components; using Microsoft.AspNetCore.Components.Forms; diff --git a/src/BackOffice/Pages/UserRole/UserRoleMainPage.razor b/src/BackOffice/Pages/UserRole/UserRoleMainPage.razor index f6ad58d..83d9258 100644 --- a/src/BackOffice/Pages/UserRole/UserRoleMainPage.razor +++ b/src/BackOffice/Pages/UserRole/UserRoleMainPage.razor @@ -1,9 +1,9 @@ @attribute [Route(RouteConstance.UserRole + "{UserId:long}")] -@using BackOffice.BFF.UserRole.Protobuf.Protos.UserRole +@using CMSMicroservice.Protobuf.Protos.UserRole @using BackOffice.Pages.UserRole.Components @using BackOffice.Common.BaseComponents -@using DataModel = BackOffice.BFF.UserRole.Protobuf.Protos.UserRole.GetAllUserRoleByFilterResponseModel +@using DataModel = CMSMicroservice.Protobuf.Protos.UserRole.GetAllUserRoleByFilterResponseModel diff --git a/src/BackOffice/Pages/UserRole/UserRoleMainPage.razor.cs b/src/BackOffice/Pages/UserRole/UserRoleMainPage.razor.cs index 1026c09..21ce812 100644 --- a/src/BackOffice/Pages/UserRole/UserRoleMainPage.razor.cs +++ b/src/BackOffice/Pages/UserRole/UserRoleMainPage.razor.cs @@ -1,10 +1,10 @@ -using BackOffice.BFF.UserRole.Protobuf.Protos.UserRole; +using CMSMicroservice.Protobuf.Protos.UserRole; using BackOffice.Common.BaseComponents; using BackOffice.Pages.UserRole.Components; using Mapster; using Microsoft.AspNetCore.Components; using MudBlazor; -using DataModel = BackOffice.BFF.UserRole.Protobuf.Protos.UserRole.GetAllUserRoleByFilterResponseModel; +using DataModel = CMSMicroservice.Protobuf.Protos.UserRole.GetAllUserRoleByFilterResponseModel; namespace BackOffice.Pages.UserRole; public partial class UserRoleMainPage diff --git a/src/BackOffice/Pages/_Imports.razor b/src/BackOffice/Pages/_Imports.razor index 992c394..7c59991 100644 --- a/src/BackOffice/Pages/_Imports.razor +++ b/src/BackOffice/Pages/_Imports.razor @@ -1,3 +1,3 @@ -@using BackOffice.BFF.Package.Protobuf.Protos.Package -@using BackOffice.BFF.UserOrder.Protobuf.Protos.UserOrder -@using BackOffice.BFF.UserRole.Protobuf.Protos.UserRole \ No newline at end of file +@using CMSMicroservice.Protobuf.Protos.Package +@using CMSMicroservice.Protobuf.Protos.UserOrder +@using CMSMicroservice.Protobuf.Protos.UserRole \ No newline at end of file diff --git a/src/BackOffice/Services/AppVersion/AppVersionService.cs b/src/BackOffice/Services/AppVersion/AppVersionService.cs index 4a6b26d..2edaf8b 100644 --- a/src/BackOffice/Services/AppVersion/AppVersionService.cs +++ b/src/BackOffice/Services/AppVersion/AppVersionService.cs @@ -1,4 +1,4 @@ -using BackOffice.BFF.Configuration.Protobuf.Protos.AppVersion; +using CMSMicroservice.Protobuf.Protos.AppVersion; using Google.Protobuf.WellKnownTypes; namespace BackOffice.Services.AppVersion; @@ -45,22 +45,20 @@ public class AppVersionService : IAppVersionService var response = await _client.GetAppVersionAsync(request); - if (!response.Found || response.Item == null) + if (!response.Found) return null; - var item = response.Item; return new AppVersionDto { - Id = item.Id, - AppName = item.AppName, - CurrentVersion = item.CurrentVersion, - MinRequiredVersion = item.MinRequiredVersion, - RequiresFullCacheClear = item.RequiresFullCacheClear, - UpdateMessage = item.UpdateMessage, - ReleaseNotes = item.ReleaseNotes, - IsActive = item.IsActive, - Created = item.Created?.ToDateTime(), - LastModified = item.LastModified?.ToDateTime() + AppName = response.AppName, + CurrentVersion = response.CurrentVersion, + MinRequiredVersion = response.MinRequiredVersion, + RequiresFullCacheClear = response.RequiresFullCacheClear, + UpdateMessage = response.UpdateMessage, + ReleaseNotes = response.ReleaseNotes, + IsActive = true, + Created = response.LastUpdated?.ToDateTime(), + LastModified = response.LastUpdated?.ToDateTime() }; } diff --git a/src/BackOffice/Services/DiscountCategory/DiscountCategoryService.cs b/src/BackOffice/Services/DiscountCategory/DiscountCategoryService.cs index 7602b11..7bfd024 100644 --- a/src/BackOffice/Services/DiscountCategory/DiscountCategoryService.cs +++ b/src/BackOffice/Services/DiscountCategory/DiscountCategoryService.cs @@ -1,4 +1,4 @@ -using BackOffice.BFF.DiscountCategory.Protobuf.Protos.DiscountCategory; +using CMSMicroservice.Protobuf.Protos.DiscountCategory; namespace BackOffice.Services.DiscountCategory; @@ -82,7 +82,7 @@ public class DiscountCategoryService : IDiscountCategoryService await _client.DeleteDiscountCategoryAsync(request); } - private List MapCategories(IEnumerable protoCategories) + private List MapCategories(IEnumerable protoCategories) { return protoCategories.Select(c => new DiscountCategoryDto { diff --git a/src/BackOffice/Services/DiscountOrder/DiscountOrderService.cs b/src/BackOffice/Services/DiscountOrder/DiscountOrderService.cs index 8d89fef..5358623 100644 --- a/src/BackOffice/Services/DiscountOrder/DiscountOrderService.cs +++ b/src/BackOffice/Services/DiscountOrder/DiscountOrderService.cs @@ -1,5 +1,5 @@ -using BackOffice.BFF.DiscountOrder.Protobuf.Protos.DiscountOrder; -using ProtoDeliveryStatus = BackOffice.BFF.DiscountOrder.Protobuf.Protos.DiscountOrder.DeliveryStatus; +using CMSMicroservice.Protobuf.Protos.DiscountOrder; +using ProtoDeliveryStatus = CMSMicroservice.Protobuf.Protos.DiscountOrder.DeliveryStatus; namespace BackOffice.Services.DiscountOrder; diff --git a/src/BackOffice/Services/DiscountProduct/DiscountProductService.cs b/src/BackOffice/Services/DiscountProduct/DiscountProductService.cs index ac84a3c..7cb8125 100644 --- a/src/BackOffice/Services/DiscountProduct/DiscountProductService.cs +++ b/src/BackOffice/Services/DiscountProduct/DiscountProductService.cs @@ -1,4 +1,4 @@ -using BackOffice.BFF.DiscountProduct.Protobuf.Protos.DiscountProduct; +using CMSMicroservice.Protobuf.Protos.DiscountProduct; using Google.Protobuf; using Google.Protobuf.WellKnownTypes; diff --git a/src/BackOffice/Services/PublicMessage/PublicMessageService.cs b/src/BackOffice/Services/PublicMessage/PublicMessageService.cs index f4594d3..e590891 100644 --- a/src/BackOffice/Services/PublicMessage/PublicMessageService.cs +++ b/src/BackOffice/Services/PublicMessage/PublicMessageService.cs @@ -1,4 +1,4 @@ -using Foursat.BackOffice.BFF.PublicMessage.Protobuf; +using CMSMicroservice.Protobuf.Protos; using Google.Protobuf.WellKnownTypes; namespace BackOffice.Services.PublicMessage; @@ -22,34 +22,38 @@ public class PublicMessageService : IPublicMessageService PageSize = filter.PageSize }; + // CMS proto uses IsActive (BoolValue) instead of Status (int) if (filter.Status.HasValue) { - request.Status = (int)filter.Status.Value; + // Map: Draft=0 → inactive, Published=1 → active, Archived=2 → inactive + request.IsActive = filter.Status.Value == MessageStatus.Published; } + // CMS proto uses Type (Int32Value) instead of MessageType (int) if (filter.Type.HasValue) { - request.MessageType = (int)filter.Type.Value; + request.Type = (int)filter.Type.Value; } var response = await _client.GetAllMessagesAsync(request); var messages = response.Messages.Select(m => new PublicMessageDto { - Id = m.MessageId, + Id = m.Id, Title = m.Title, - Type = (MessageType)m.MessageType, - TypeName = m.MessageTypeName, + Type = (MessageType)m.Type, + TypeName = m.TypeName, Priority = m.Priority, PriorityName = m.PriorityName, - Status = (MessageStatus)m.Status, - StatusName = m.StatusName, + // CMS uses IsActive (bool) instead of Status enum + Status = m.IsActive ? MessageStatus.Published : MessageStatus.Draft, + StatusName = m.IsActive ? "فعال" : "غیرفعال", StartsAt = m.StartsAt?.ToDateTime(), ExpiresAt = m.ExpiresAt?.ToDateTime(), Created = m.Created?.ToDateTime() }).ToList(); - return (messages, response.TotalCount); + return (messages, (int)(response.MetaData?.TotalCount ?? 0)); } public async Task GetByIdAsync(long id) @@ -57,29 +61,30 @@ public class PublicMessageService : IPublicMessageService var request = new GetPublicMessageRequest { MessageId = id }; var response = await _client.GetPublicMessageAsync(request); - if (response.MessageId == 0) + if (response.Id == 0) return null; return new PublicMessageDetailsDto { - Id = response.MessageId, + Id = response.Id, Title = response.Title, Content = response.Content, - Type = (MessageType)response.MessageType, - TypeName = response.MessageTypeName, + Type = (MessageType)response.Type, + TypeName = string.Empty, // CMS GetPublicMessageResponse does not include TypeName Priority = response.Priority, - PriorityName = response.PriorityName, - Status = (MessageStatus)response.Status, - StatusName = response.StatusName, - StartsAt = response.StartsAt?.ToDateTime(), - ExpiresAt = response.ExpiresAt?.ToDateTime(), + PriorityName = string.Empty, // CMS GetPublicMessageResponse does not include PriorityName + // CMS uses IsActive/IsArchived bools instead of Status enum + Status = response.IsArchived ? MessageStatus.Archived : (response.IsActive ? MessageStatus.Published : MessageStatus.Draft), + StatusName = response.IsArchived ? "آرشیو شده" : (response.IsActive ? "فعال" : "غیرفعال"), + StartsAt = response.StartDate?.ToDateTime(), + ExpiresAt = response.EndDate?.ToDateTime(), PublishedAt = response.PublishedAt?.ToDateTime(), ArchivedAt = response.ArchivedAt?.ToDateTime(), - IsDismissible = response.IsDismissible, - TargetAudience = response.TargetAudience, - Tags = response.Tags.ToList(), - Created = response.Created?.ToDateTime(), - LastModified = response.LastModified?.ToDateTime() + IsDismissible = false, // CMS does not have IsDismissible + TargetAudience = null, // CMS does not have TargetAudience + Tags = new List(), // CMS does not have Tags + Created = response.CreatedAt?.ToDateTime(), + LastModified = response.LastModifiedAt?.ToDateTime() }; } @@ -89,58 +94,50 @@ public class PublicMessageService : IPublicMessageService { Title = dto.Title, Content = dto.Content, - MessageType = (int)dto.Type, - Priority = dto.Priority, - IsDismissible = dto.IsDismissible, - TargetAudience = dto.TargetAudience ?? string.Empty + Type = (int)dto.Type, // CMS uses Type instead of MessageType + Priority = dto.Priority + // CMS does not have IsDismissible or TargetAudience fields }; if (dto.StartsAt.HasValue) { - request.StartsAt = Timestamp.FromDateTime(dto.StartsAt.Value.ToUniversalTime()); + request.StartDate = Timestamp.FromDateTime(dto.StartsAt.Value.ToUniversalTime()); } if (dto.ExpiresAt.HasValue) { - request.ExpiresAt = Timestamp.FromDateTime(dto.ExpiresAt.Value.ToUniversalTime()); + request.EndDate = Timestamp.FromDateTime(dto.ExpiresAt.Value.ToUniversalTime()); } - if (dto.Tags != null) - { - request.Tags.AddRange(dto.Tags); - } + // CMS does not have Tags field in CreatePublicMessageRequest var response = await _client.CreatePublicMessageAsync(request); - return response.MessageId; + return response.Id; } public async Task UpdateAsync(long id, UpdatePublicMessageDto dto) { var request = new UpdatePublicMessageRequest { - MessageId = id, + Id = id, // CMS uses Id instead of MessageId Title = dto.Title, Content = dto.Content, - MessageType = (int)dto.Type, - Priority = dto.Priority, - IsDismissible = dto.IsDismissible, - TargetAudience = dto.TargetAudience ?? string.Empty + Type = (int)dto.Type, // CMS uses Type instead of MessageType + Priority = dto.Priority + // CMS does not have IsDismissible or TargetAudience fields }; if (dto.StartsAt.HasValue) { - request.StartsAt = Timestamp.FromDateTime(dto.StartsAt.Value.ToUniversalTime()); + request.StartDate = Timestamp.FromDateTime(dto.StartsAt.Value.ToUniversalTime()); } if (dto.ExpiresAt.HasValue) { - request.ExpiresAt = Timestamp.FromDateTime(dto.ExpiresAt.Value.ToUniversalTime()); + request.EndDate = Timestamp.FromDateTime(dto.ExpiresAt.Value.ToUniversalTime()); } - if (dto.Tags != null) - { - request.Tags.AddRange(dto.Tags); - } + // CMS does not have Tags field in UpdatePublicMessageRequest await _client.UpdatePublicMessageAsync(request); } diff --git a/src/BackOffice/Services/Tag/TagService.cs b/src/BackOffice/Services/Tag/TagService.cs index e603790..93c492e 100644 --- a/src/BackOffice/Services/Tag/TagService.cs +++ b/src/BackOffice/Services/Tag/TagService.cs @@ -2,13 +2,13 @@ namespace BackOffice.Services.Tag; public class TagService : ITagService { - private readonly BackOffice.BFF.Tag.Protobuf.Protos.Tag.TagContract.TagContractClient _tagClient; - private readonly BackOffice.BFF.ProductTag.Protobuf.Protos.ProductTag.ProductTagContract.ProductTagContractClient _productTagClient; - private readonly BackOffice.BFF.Products.Protobuf.Protos.Products.ProductsContract.ProductsContractClient _productsClient; + private readonly CMSMicroservice.Protobuf.Protos.Tag.TagContract.TagContractClient _tagClient; + private readonly CMSMicroservice.Protobuf.Protos.ProductTag.ProductTagContract.ProductTagContractClient _productTagClient; + private readonly CMSMicroservice.Protobuf.Protos.Products.ProductsContract.ProductsContractClient _productsClient; public TagService( - BackOffice.BFF.Tag.Protobuf.Protos.Tag.TagContract.TagContractClient tagClient, - BackOffice.BFF.ProductTag.Protobuf.Protos.ProductTag.ProductTagContract.ProductTagContractClient productTagClient, - BackOffice.BFF.Products.Protobuf.Protos.Products.ProductsContract.ProductsContractClient productsClient) + CMSMicroservice.Protobuf.Protos.Tag.TagContract.TagContractClient tagClient, + CMSMicroservice.Protobuf.Protos.ProductTag.ProductTagContract.ProductTagContractClient productTagClient, + CMSMicroservice.Protobuf.Protos.Products.ProductsContract.ProductsContractClient productsClient) { _tagClient = tagClient; _productTagClient = productTagClient; @@ -17,14 +17,14 @@ public class TagService : ITagService public async Task GetTagsAsync(TagFilterDto filter) { - var request = new BackOffice.BFF.Tag.Protobuf.Protos.Tag.GetAllTagByFilterRequest + var request = new CMSMicroservice.Protobuf.Protos.Tag.GetAllTagByFilterRequest { - PaginationState = new BackOffice.BFF.Tag.Protobuf.Protos.Tag.PaginationState + PaginationState = new CMSMicroservice.Protobuf.Protos.PaginationState { PageNumber = filter.PageNumber, PageSize = filter.PageSize }, - Filter = new BackOffice.BFF.Tag.Protobuf.Protos.Tag.GetAllTagByFilterFilter() + Filter = new CMSMicroservice.Protobuf.Protos.Tag.GetAllTagByFilterFilter() }; if (!string.IsNullOrWhiteSpace(filter.SearchTerm)) @@ -63,7 +63,7 @@ public class TagService : ITagService public async Task GetByIdAsync(long id) { - var response = await _tagClient.GetTagAsync(new BackOffice.BFF.Tag.Protobuf.Protos.Tag.GetTagRequest { Id = id }); + var response = await _tagClient.GetTagAsync(new CMSMicroservice.Protobuf.Protos.Tag.GetTagRequest { Id = id }); if (response == null || response.Id <= 0) { @@ -83,7 +83,7 @@ public class TagService : ITagService public async Task CreateAsync(TagEditDto dto) { - var request = new BackOffice.BFF.Tag.Protobuf.Protos.Tag.CreateNewTagRequest + var request = new CMSMicroservice.Protobuf.Protos.Tag.CreateNewTagRequest { Name = dto.Name, Title = dto.Title, @@ -98,7 +98,7 @@ public class TagService : ITagService public async Task UpdateAsync(long id, TagEditDto dto) { - var request = new BackOffice.BFF.Tag.Protobuf.Protos.Tag.UpdateTagRequest + var request = new CMSMicroservice.Protobuf.Protos.Tag.UpdateTagRequest { Id = id, Name = dto.Name, @@ -113,12 +113,12 @@ public class TagService : ITagService public async Task DeleteAsync(long id) { - await _tagClient.DeleteTagAsync(new BackOffice.BFF.Tag.Protobuf.Protos.Tag.DeleteTagRequest { Id = id }); + await _tagClient.DeleteTagAsync(new CMSMicroservice.Protobuf.Protos.Tag.DeleteTagRequest { Id = id }); } public async Task AssignToProductAsync(long productId, long tagId) { - var request = new BackOffice.BFF.ProductTag.Protobuf.Protos.ProductTag.CreateNewProductTagRequest + var request = new CMSMicroservice.Protobuf.Protos.ProductTag.CreateNewProductTagRequest { ProductId = productId, TagId = tagId @@ -129,14 +129,14 @@ public class TagService : ITagService public async Task> GetProductTagsAsync(long productId) { - var request = new BackOffice.BFF.ProductTag.Protobuf.Protos.ProductTag.GetAllProductTagByFilterRequest + var request = new CMSMicroservice.Protobuf.Protos.ProductTag.GetAllProductTagByFilterRequest { - PaginationState = new BackOffice.BFF.Protobuf.Common.PaginationState + PaginationState = new CMSMicroservice.Protobuf.Protos.PaginationState { PageNumber = 1, PageSize = 100 }, - Filter = new BackOffice.BFF.ProductTag.Protobuf.Protos.ProductTag.GetAllProductTagByFilterFilter + Filter = new CMSMicroservice.Protobuf.Protos.ProductTag.GetAllProductTagByFilterFilter { ProductId = productId } @@ -168,7 +168,7 @@ public class TagService : ITagService public async Task RemoveProductTagAsync(long productTagId) { await _productTagClient.DeleteProductTagAsync( - new BackOffice.BFF.ProductTag.Protobuf.Protos.ProductTag.DeleteProductTagRequest + new CMSMicroservice.Protobuf.Protos.ProductTag.DeleteProductTagRequest { Id = productTagId }); diff --git a/src/BackOffice/wwwroot/appsettings.CMS-Direct.json b/src/BackOffice/wwwroot/appsettings.CMS-Direct.json new file mode 100644 index 0000000..4bb6ac4 --- /dev/null +++ b/src/BackOffice/wwwroot/appsettings.CMS-Direct.json @@ -0,0 +1,10 @@ +{ + // تست مستقیم اتصال به CMS (بدون BFF) + // برای فعال‌سازی: این فایل رو به appsettings.json rename کن + + "GwUrl": "https://cms.se.kbs1.ir", + "Authentication": { + "Authority": "https://ids.afrino.co/", + "ClientId": "client_backoffice_spa" + } +} diff --git a/src/BackOffice/wwwroot/appsettings.Staging.json b/src/BackOffice/wwwroot/appsettings.Staging.json index 73b283a..8d2e127 100644 --- a/src/BackOffice/wwwroot/appsettings.Staging.json +++ b/src/BackOffice/wwwroot/appsettings.Staging.json @@ -1,6 +1,7 @@ { // "GwUrl": "https://localhost:6468", - "GwUrl": "https://backoffice-bff.se.kbs1.ir", +// "GwUrl": "https://backoffice-bff.se.kbs1.ir", // OLD - via BFF + "GwUrl": "https://cms.se.kbs1.ir", "Authentication": { "Authority": "https://ids.afrino.co/", "ClientId": "client_backoffice_spa" diff --git a/src/BackOffice/wwwroot/appsettings.json b/src/BackOffice/wwwroot/appsettings.json index 73b283a..364b3b6 100644 --- a/src/BackOffice/wwwroot/appsettings.json +++ b/src/BackOffice/wwwroot/appsettings.json @@ -1,6 +1,7 @@ { -// "GwUrl": "https://localhost:6468", - "GwUrl": "https://backoffice-bff.se.kbs1.ir", + "GwUrl": "https://localhost:32846", +// "GwUrl": "https://backoffice-bff.se.kbs1.ir", // OLD - via BFF + // "GwUrl": "https://cms.se.kbs1.ir", // NEW - direct to CMS "Authentication": { "Authority": "https://ids.afrino.co/", "ClientId": "client_backoffice_spa"