# 📝 Changelog - ۷ دی ۱۴۰۴ (27 December 2025) > **Session**: بهینه‌سازی‌های Mapping + SystemConstants + SMS Templates + AppVersion UI --- ## 🎯 خلاصه Session این session شامل موارد زیر بود: 1. **SystemConstants** - انتقال مقادیر ثابت از hardcode به کلاس مرکزی 2. **SMS Templates** - متمرکز کردن همه قالب‌های پیامک 3. **SMS for Daya Loan** - ارسال پیامک هنگام تأیید وام دایا 4. **AppVersion UI** - تکمیل صفحه مدیریت نسخه در BackOffice 5. **Mapping Fixes** - رفع مشکلات Mapster --- ## ✨ تغییرات ### 1. 💰 SystemConstants - مقادیر ثابت ✅ **فایل**: `CMSMicroservice.Domain/Common/SystemConstants.cs` ```csharp public static class SystemConstants { // Club Configuration public const decimal ClubJoiningPercentage = 0.35m; // 35% کمیسیون پیوستن به باشگاه public const decimal ClubActivationThreshold = 0.5m; // 50% آستانه فعال‌سازی // Commission Configuration public const int MaxCalculationAttempts = 3; // حداکثر تلاش محاسبه public const int DefaultCommissionPoolDays = 7; // روزهای استخر کمیسیون // Package Amounts public const long GoldenPackageAmount = 56_000_000; // 56 میلیون - پکیج طلایی public const long DayaLoanAmount = 56_000_000; // 56 میلیون - وام دایا } ``` **Handlers آپدیت شده**: | Handler | تغییر | |---------|-------| | `ProcessDayaLoanApprovalCommandHandler` | استفاده از `SystemConstants.DayaLoanAmount` | | `ValidateGoldenPackagePurchaseQueryHandler` | استفاده از `SystemConstants.GoldenPackageAmount` | | سایر handlers با 56_000_000 | همه به ثابت تبدیل شدند | --- ### 2. 📱 SmsTemplates - قالب‌های متمرکز پیامک ✅ **فایل جدید**: `CMSMicroservice.Domain/Common/SmsTemplates.cs` ```csharp public static class SmsTemplates { private static string GetUserName(string? firstName) => string.IsNullOrWhiteSpace(firstName) ? "کاربر" : firstName; public static string DayaLoanReceived(string? firstName, long amount) => $"{GetUserName(firstName)} عزیز، مبلغ {amount:N0} ریال وام دایا به کیف پول شما واریز شد. کارابازار"; public static string ClubActivated(string? firstName) => $"{GetUserName(firstName)} عزیز، حساب باشگاه شما فعال شد. کارابازار"; public static string PackagePurchased(string? firstName, string packageName) => $"{GetUserName(firstName)} عزیز، پکیج {packageName} با موفقیت خریداری شد. کارابازار"; public static string CommissionDeposited(string? firstName, long amount) => $"{GetUserName(firstName)} عزیز، مبلغ {amount:N0} ریال کمیسیون به کیف پول شما واریز شد. کارابازار"; public static string WithdrawalSuccess(string? firstName, long amount) => $"{GetUserName(firstName)} عزیز، درخواست برداشت {amount:N0} ریال با موفقیت انجام شد. کارابازار"; public static string NetworkJoined(string? firstName, string referrerName) => $"{GetUserName(firstName)} عزیز، به شبکه {referrerName} پیوستید. کارابازار"; public static string NewDownline(string? firstName, string newMemberName) => $"{GetUserName(firstName)} عزیز، {newMemberName} به زیرمجموعه شما اضافه شد. کارابازار"; public static string OtpCode(string code) => $"کد تأیید شما: {code}\nکارابازار"; public static string Welcome(string? firstName) => $"{GetUserName(firstName)} عزیز، به کارابازار خوش آمدید!"; } ``` --- ### 3. 📲 ارسال SMS هنگام تأیید وام دایا ✅ **فایل**: `CMSMicroservice.Application/FinancialCQ/Commands/ProcessDayaLoanApproval/ProcessDayaLoanApprovalCommandHandler.cs` **تغییرات**: ```csharp public class ProcessDayaLoanApprovalCommandHandler : IRequestHandler { private readonly IKavenegarService _smsService; // جدید private readonly ILogger _logger; // جدید // بعد از واریز موفق به کیف پول private async Task SendDayaLoanSmsAsync(User user) { try { var message = SmsTemplates.DayaLoanReceived( user.FirstName, SystemConstants.DayaLoanAmount); await _smsService.SendAsync(user.PhoneNumber, message); _logger.LogInformation("Daya loan SMS sent to user {UserId}", user.Id); } catch (Exception ex) { _logger.LogWarning(ex, "Failed to send Daya loan SMS to user {UserId}", user.Id); // خطای SMS مانع عملیات اصلی نمی‌شود } } } ``` --- ### 4. 🖥️ BackOffice - صفحه مدیریت نسخه اپلیکیشن ✅ #### 4.1 اضافه شدن به منو **فایل**: `BackOffice/Shared/NavMenu.razor` ```razor @if (CanViewSettings) { نسخه اپلیکیشن‌ها } ``` **Permission**: `settings.view` #### 4.2 دکمه افزودن نسخه جدید **فایل**: `BackOffice/Pages/Settings/AppVersions.razor` ```razor افزودن نسخه جدید ``` #### 4.3 Dialog با حالت جدید/ویرایش **فایل**: `BackOffice/Pages/Settings/Components/AppVersionEditDialog.razor` ```razor [Parameter] public bool IsNew { get; set; } = false; @if (IsNew) { کارابازار ادمین کارابازار } else { } ``` #### 4.4 آیکون و رنگ اپلیکیشن‌ها ```csharp private string GetAppIcon(string appName) => appName switch { "KaraBazarApp" => Icons.Material.Filled.ShoppingCart, "KaraBazarAdminApp" => Icons.Material.Filled.AdminPanelSettings, _ => Icons.Material.Filled.PhoneAndroid }; private Color GetAppColor(string appName) => appName switch { "KaraBazarApp" => Color.Primary, "KaraBazarAdminApp" => Color.Secondary, _ => Color.Default }; ``` --- ### 5. 🔧 Mapping Fixes ✅ #### 5.1 CMS - AppVersionProfile **فایل جدید**: `CMSMicroservice.WebApi/Common/Mappings/AppVersionProfile.cs` ```csharp public class AppVersionProfile : IRegister { public void Register(TypeAdapterConfig config) { // Map List to GetAllAppVersionsResponse config.NewConfig, GetAllAppVersionsResponse>() .MapWith(src => CreateResponse(src)); // Map AppVersionItemDto to AppVersionItem (proto message) config.NewConfig() .Map(dest => dest.Id, src => src.Id) .Map(dest => dest.AppName, src => src.AppName) // ... other mappings } private static GetAllAppVersionsResponse CreateResponse(List items) { var response = new GetAllAppVersionsResponse(); foreach (var item in items) { response.Items.Add(item.Adapt()); } return response; } } ``` #### 5.2 BackOffice.BFF - CommissionProfile **فایل**: `BackOffice.BFF.Application/Common/Mappings/CommissionProfile.cs` ```csharp // CMS GetAllWeeklyPoolsResponse -> GetAllWeeklyPoolsResponseDto config.NewConfig() .MapWith(src => new GetAllWeeklyPoolsResponseDto { MetaData = new MetaDataDto { TotalCount = (int)src.MetaData.TotalCount, PageSize = (int)src.MetaData.PageSize, CurrentPage = (int)src.MetaData.CurrentPage, TotalPages = (int)src.MetaData.TotalPage }, Models = src.Models.Select(m => new WeeklyCommissionPoolDto { Id = m.Id, WeekDefinitionId = m.WeekDefinitionId, // ... other mappings }).ToList() }); ``` #### 5.3 BackOffice.BFF - GeneralMapping (Unit to Empty) **فایل**: `BackOffice.BFF.WebApi/Common/Mappings/GeneralMapping.cs` ```csharp // MediatR Unit to Google.Protobuf.Empty config.NewConfig() .MapWith(_ => new Google.Protobuf.WellKnownTypes.Empty()); ``` --- ## 📦 فایل‌های تغییر یافته ### CMS | فایل | نوع تغییر | |------|-----------| | `Domain/Common/SystemConstants.cs` | Modified - اضافه شدن GoldenPackageAmount, DayaLoanAmount | | `Domain/Common/SmsTemplates.cs` | **New** - قالب‌های پیامک | | `Application/.../ProcessDayaLoanApprovalCommandHandler.cs` | Modified - اضافه شدن SMS | | `WebApi/Common/Mappings/AppVersionProfile.cs` | **New** - Mapster profile | ### BackOffice.BFF | فایل | نوع تغییر | |------|-----------| | `Application/Common/Mappings/CommissionProfile.cs` | Modified - اضافه شدن GetAllWeeklyPools mapping | | `WebApi/Common/Mappings/GeneralMapping.cs` | Modified - اضافه شدن Unit to Empty | ### BackOffice | فایل | نوع تغییر | |------|-----------| | `Shared/NavMenu.razor` | Modified - اضافه شدن لینک app-versions | | `Pages/Settings/AppVersions.razor` | Modified - دکمه افزودن + OpenCreateDialog | | `Pages/Settings/Components/AppVersionEditDialog.razor` | Modified - پارامتر IsNew + Select | --- ## ✅ Build Status ```bash # CMS dotnet build CMSMicroservice.WebApi/CMSMicroservice.WebApi.csproj # Build succeeded. 0 Error(s) # BackOffice.BFF dotnet build BackOffice.BFF.WebApi/BackOffice.BFF.WebApi.csproj # Build succeeded. 0 Error(s) # BackOffice dotnet build BackOffice/BackOffice.csproj # Build succeeded. 0 Error(s) ``` --- ## 📊 آمار Session | متریک | مقدار | |-------|-------| | فایل‌های جدید | 2 | | فایل‌های تغییر یافته | 8 | | خطوط کد اضافه شده | ~300 | | باگ‌های Mapping رفع شده | 3 | --- ## 🔗 Related Changelogs - [CHANGELOG-2025-12-26.md](CHANGELOG-2025-12-26.md) - App Version Management + ReferralCode in Tree - [CHANGELOG-2025-12-25.md](CHANGELOG-2025-12-25.md) - درخت شبکه BackOffice